led_strip: ws2812: allow to configure reset delay
Some devices compatibles with the WS2812 IC have a different reset/latch delay. This patch introduces the "reset-delay" optional property for the WS2812 DT binding and adds support to the ws2812_spi driver. This new property allows to configure the reset/latch delay of a WS2812 compatible LED strip controller from its DT node. If omitted the driver uses 8 microseconds by default (which is good for the WS2812 IC). Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
This commit is contained in:
parent
4ada0bbd6e
commit
17c0ddfe9c
|
@ -26,14 +26,6 @@ LOG_MODULE_REGISTER(ws2812_spi);
|
|||
/* spi-one-frame and spi-zero-frame in DT are for 8-bit frames. */
|
||||
#define SPI_FRAME_BITS 8
|
||||
|
||||
/*
|
||||
* Delay time to make sure the strip has latched a signal.
|
||||
*
|
||||
* Despite datasheet claims, a 6 microsecond delay is enough to reset
|
||||
* the strip. Delay for 8 usec just to be safe.
|
||||
*/
|
||||
#define RESET_DELAY_USEC 8
|
||||
|
||||
/*
|
||||
* SPI master configuration:
|
||||
*
|
||||
|
@ -56,6 +48,7 @@ struct ws2812_spi_cfg {
|
|||
uint8_t zero_frame;
|
||||
uint8_t num_colors;
|
||||
const uint8_t *color_mapping;
|
||||
uint16_t reset_delay;
|
||||
};
|
||||
|
||||
static struct ws2812_spi_data *dev_data(const struct device *dev)
|
||||
|
@ -100,13 +93,13 @@ static inline bool num_pixels_ok(const struct ws2812_spi_cfg *cfg,
|
|||
/*
|
||||
* Latch current color values on strip and reset its state machines.
|
||||
*/
|
||||
static inline void ws2812_reset_delay(void)
|
||||
static inline void ws2812_reset_delay(uint16_t delay)
|
||||
{
|
||||
/*
|
||||
* TODO: swap out with k_usleep() once that can be trusted to
|
||||
* work reliably.
|
||||
*/
|
||||
k_busy_wait(RESET_DELAY_USEC);
|
||||
k_busy_wait(delay);
|
||||
}
|
||||
|
||||
static int ws2812_strip_update_rgb(const struct device *dev,
|
||||
|
@ -167,7 +160,7 @@ static int ws2812_strip_update_rgb(const struct device *dev,
|
|||
* Display the pixel data.
|
||||
*/
|
||||
rc = spi_write(dev_data(dev)->spi, &cfg->spi_cfg, &tx);
|
||||
ws2812_reset_delay();
|
||||
ws2812_reset_delay(cfg->reset_delay);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -212,6 +205,9 @@ static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
|
|||
|
||||
#define WS2812_NUM_COLORS(idx) (DT_INST_PROP_LEN(idx, color_mapping))
|
||||
|
||||
/* Get the latch/reset delay from the "reset-delay" DT property. */
|
||||
#define WS2812_RESET_DELAY(idx) DT_INST_PROP(idx, reset_delay)
|
||||
|
||||
#define WS2812_SPI_DEVICE(idx) \
|
||||
\
|
||||
static struct ws2812_spi_data ws2812_spi_##idx##_data; \
|
||||
|
@ -233,6 +229,7 @@ static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
|
|||
.zero_frame = WS2812_SPI_ZERO_FRAME(idx), \
|
||||
.num_colors = WS2812_NUM_COLORS(idx), \
|
||||
.color_mapping = ws2812_spi_##idx##_color_mapping, \
|
||||
.reset_delay = WS2812_RESET_DELAY(idx), \
|
||||
}; \
|
||||
\
|
||||
static int ws2812_spi_##idx##_init(const struct device *dev) \
|
||||
|
|
|
@ -38,3 +38,15 @@ properties:
|
|||
color-mapping = <LED_COLOR_ID_GREEN
|
||||
LED_COLOR_ID_RED
|
||||
LED_COLOR_ID_BLUE>;
|
||||
|
||||
reset-delay:
|
||||
type: int
|
||||
required: false
|
||||
default: 8
|
||||
description: |
|
||||
Minimum delay to wait (in microseconds) to make sure that the strip has
|
||||
latched the signal. If omitted, a default value of 8 microseconds is used.
|
||||
This default is good for the WS2812 controllers. Note that despite the
|
||||
WS2812 datasheet states that a 50 microseconds delay is required, it seems
|
||||
6 microseconds is enough. The default is set to 8 microseconds just to be
|
||||
safe.
|
||||
|
|
Loading…
Reference in a new issue