|
| 1 | +# Copyright (c) 2025 Google LLC |
| 2 | +# SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +description: | |
| 5 | + Worldsemi WS2812 LED strip, UART binding |
| 6 | +
|
| 7 | + Driver bindings for Worldsemi WS2812 and compatible LED strips using a UART |
| 8 | + peripheral. |
| 9 | +
|
| 10 | + The driver encodes each WS2812 data bit into a multi-bit "symbol" that is |
| 11 | + transmitted via a UART. The signal timing is achieved through a combination |
| 12 | + of this node's properties: |
| 13 | + - one-symbol, |
| 14 | + - zero-symbol, |
| 15 | + - bits-per-symbol, |
| 16 | + and the parent UART's configuration: |
| 17 | + - current-speed (baudrate), |
| 18 | + - data-bits, |
| 19 | + - tx-invert (to produce the required idle-low signal), |
| 20 | + - stop-bits (must be "1" if set), |
| 21 | + - parity (must be "none" if set). |
| 22 | +
|
| 23 | + The driver employs a UART frame-aware packing strategy, reusing the UART's |
| 24 | + hardware start and stop bits as part of the on-wire symbol. This packing |
| 25 | + scheme imposes a configuration constraint: the total number of bits in a |
| 26 | + UART frame must be an integer multiple of `bits-per-symbol`. |
| 27 | +
|
| 28 | + Since the UART must be configured with one start bit, one stop bit, and no |
| 29 | + parity, this means the total frame size, `(2 + data-bits)`, must be evenly |
| 30 | + divisible by `bits-per-symbol`. |
| 31 | +
|
| 32 | + To meet the timing requirements of the WS2812 protocol, the UART controller |
| 33 | + must support high-speed operation, typically 2.4 MHz or higher. The parent |
| 34 | + UART's `current-speed` (baudrate) property should be configured as close as |
| 35 | + possible to the ideal rate, calculated as `bits-per-symbol` times the |
| 36 | + WS2812's data rate (typically 800 kHz). For example, with a |
| 37 | + `bits-per-symbol` of 3, the target baudrate is 2.4 MHz. |
| 38 | +
|
| 39 | + The internal memory buffer size is determined by `bits-per-symbol`. For |
| 40 | + each bit of pixel data, the driver generates a symbol of N bits (where N |
| 41 | + is the value of `bits-per-symbol`), which are then packed into the buffer. |
| 42 | +
|
| 43 | + An example of an overlay: |
| 44 | +
|
| 45 | + &uart1 { |
| 46 | + status = "okay"; |
| 47 | + /* Target baudrate is 800kHz * 3 = 2.4MHz. 2.5MHz is a close value. */ |
| 48 | + current-speed = <2500000>; |
| 49 | + /* Frame constraint: (1 start + 7 data + 1 stop) = 9 bits total. */ |
| 50 | + data-bits = <7>; |
| 51 | + /* tx-invert is required to create an idle-low signal. */ |
| 52 | + tx-invert; |
| 53 | +
|
| 54 | + led_strip: ws2812-strip { |
| 55 | + compatible = "worldsemi,ws2812-uart"; |
| 56 | + status = "okay"; |
| 57 | +
|
| 58 | + /* Timing based on 2.5MHz baudrate (400ns per bit): |
| 59 | + * T1H for '1' bit (2 high bits) = 2 * 400ns = 800ns. |
| 60 | + * T0H for '0' bit (1 high bit) = 1 * 400ns = 400ns. |
| 61 | + */ |
| 62 | + one-symbol = <6>; /* 0b110 */ |
| 63 | + zero-symbol = <4>; /* 0b100 */ |
| 64 | + bits-per-symbol = <3>; |
| 65 | +
|
| 66 | + chain-length = <8>; |
| 67 | + reset-delay = <50>; |
| 68 | + color-mapping = <LED_COLOR_ID_GREEN |
| 69 | + LED_COLOR_ID_RED |
| 70 | + LED_COLOR_ID_BLUE>; |
| 71 | + }; |
| 72 | + }; |
| 73 | +
|
| 74 | +compatible: "worldsemi,ws2812-uart" |
| 75 | + |
| 76 | +include: [ws2812.yaml, uart-device.yaml] |
| 77 | + |
| 78 | +on-bus: uart |
| 79 | + |
| 80 | +properties: |
| 81 | + one-symbol: |
| 82 | + type: int |
| 83 | + required: true |
| 84 | + description: | |
| 85 | + The bit pattern that represents a single WS2812 '1' bit. The length of |
| 86 | + the pattern is defined by 'bits-per-symbol'. The pattern's MSB must be |
| 87 | + 1 (to align with the UART start bit) and its LSB must be 0 (to align |
| 88 | + with the UART stop bit). |
| 89 | +
|
| 90 | + zero-symbol: |
| 91 | + type: int |
| 92 | + required: true |
| 93 | + description: | |
| 94 | + The bit pattern that represents a single WS2812 '0' bit. The length of |
| 95 | + the pattern is defined by 'bits-per-symbol'. The pattern's MSB must be |
| 96 | + 1 (to align with the UART start bit) and its LSB must be 0 (to align |
| 97 | + with the UART stop bit). |
| 98 | +
|
| 99 | + bits-per-symbol: |
| 100 | + type: int |
| 101 | + required: true |
| 102 | + description: | |
| 103 | + The number of UART bits used to represent a single WS2812 data bit. |
| 104 | + The value must be between 3 and 10, inclusive. |
0 commit comments