led_strip: ws2812: convert to spi_dt_spec
Convert ws2812 LED strip driver to `spi_dt_spec`. Also moves the init function implementation outside the declaration macro. Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
parent
8d84626cab
commit
7065aec5e2
|
@ -36,12 +36,8 @@ LOG_MODULE_REGISTER(ws2812_spi);
|
|||
#define SPI_OPER (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \
|
||||
SPI_WORD_SET(SPI_FRAME_BITS) | SPI_LINES_SINGLE)
|
||||
|
||||
struct ws2812_spi_data {
|
||||
const struct device *spi;
|
||||
};
|
||||
|
||||
struct ws2812_spi_cfg {
|
||||
struct spi_config spi_cfg;
|
||||
struct spi_dt_spec bus;
|
||||
uint8_t *px_buf;
|
||||
size_t px_buf_size;
|
||||
uint8_t one_frame;
|
||||
|
@ -51,11 +47,6 @@ struct ws2812_spi_cfg {
|
|||
uint16_t reset_delay;
|
||||
};
|
||||
|
||||
static struct ws2812_spi_data *dev_data(const struct device *dev)
|
||||
{
|
||||
return dev->data;
|
||||
}
|
||||
|
||||
static const struct ws2812_spi_cfg *dev_cfg(const struct device *dev)
|
||||
{
|
||||
return dev->config;
|
||||
|
@ -155,7 +146,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);
|
||||
rc = spi_write_dt(&cfg->bus, &tx);
|
||||
ws2812_reset_delay(cfg->reset_delay);
|
||||
|
||||
return rc;
|
||||
|
@ -169,6 +160,34 @@ static int ws2812_strip_update_channels(const struct device *dev,
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int ws2812_spi_init(const struct device *dev)
|
||||
{
|
||||
const struct ws2812_spi_cfg *cfg = dev_cfg(dev);
|
||||
uint8_t i;
|
||||
|
||||
if (!spi_is_ready(&cfg->bus)) {
|
||||
LOG_ERR("SPI device %s not ready", cfg->bus.bus->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < cfg->num_colors; i++) {
|
||||
switch (cfg->color_mapping[i]) {
|
||||
case LED_COLOR_ID_WHITE:
|
||||
case LED_COLOR_ID_RED:
|
||||
case LED_COLOR_ID_GREEN:
|
||||
case LED_COLOR_ID_BLUE:
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("%s: invalid channel to color mapping."
|
||||
"Check the color-mapping DT property",
|
||||
dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct led_strip_driver_api ws2812_spi_api = {
|
||||
.update_rgb = ws2812_strip_update_rgb,
|
||||
.update_channels = ws2812_strip_update_channels,
|
||||
|
@ -178,15 +197,9 @@ static const struct led_strip_driver_api ws2812_spi_api = {
|
|||
(DT_INST_PROP(idx, chain_length))
|
||||
#define WS2812_SPI_HAS_WHITE(idx) \
|
||||
(DT_INST_PROP(idx, has_white_channel) == 1)
|
||||
#define WS2812_SPI_BUS(idx) \
|
||||
(DT_INST_BUS_LABEL(idx))
|
||||
#define WS2812_SPI_SLAVE(idx) \
|
||||
(DT_INST_REG_ADDR(idx))
|
||||
#define WS2812_SPI_FREQ(idx) \
|
||||
(DT_INST_PROP(idx, spi_max_frequency))
|
||||
#define WS2812_SPI_ONE_FRAME(idx) \
|
||||
(DT_INST_PROP(idx, spi_one_frame))
|
||||
#define WS2812_SPI_ZERO_FRAME(idx)\
|
||||
#define WS2812_SPI_ZERO_FRAME(idx) \
|
||||
(DT_INST_PROP(idx, spi_zero_frame))
|
||||
#define WS2812_SPI_BUFSZ(idx) \
|
||||
(WS2812_NUM_COLORS(idx) * 8 * WS2812_SPI_NUM_PIXELS(idx))
|
||||
|
@ -195,77 +208,39 @@ static const struct led_strip_driver_api ws2812_spi_api = {
|
|||
* Retrieve the channel to color mapping (e.g. RGB, BGR, GRB, ...) from the
|
||||
* "color-mapping" DT property.
|
||||
*/
|
||||
#define WS2812_COLOR_MAPPING(idx) \
|
||||
static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
|
||||
DT_INST_PROP(idx, color_mapping)
|
||||
#define WS2812_COLOR_MAPPING(idx) \
|
||||
static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
|
||||
DT_INST_PROP(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; \
|
||||
\
|
||||
static uint8_t ws2812_spi_##idx##_px_buf[WS2812_SPI_BUFSZ(idx)]; \
|
||||
\
|
||||
WS2812_COLOR_MAPPING(idx); \
|
||||
\
|
||||
static const struct ws2812_spi_cfg ws2812_spi_##idx##_cfg = { \
|
||||
.spi_cfg = { \
|
||||
.frequency = WS2812_SPI_FREQ(idx), \
|
||||
.operation = SPI_OPER, \
|
||||
.slave = WS2812_SPI_SLAVE(idx), \
|
||||
.cs = NULL, \
|
||||
}, \
|
||||
.px_buf = ws2812_spi_##idx##_px_buf, \
|
||||
.px_buf_size = WS2812_SPI_BUFSZ(idx), \
|
||||
.one_frame = WS2812_SPI_ONE_FRAME(idx), \
|
||||
.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) \
|
||||
{ \
|
||||
struct ws2812_spi_data *data = dev_data(dev); \
|
||||
const struct ws2812_spi_cfg *cfg = dev_cfg(dev); \
|
||||
uint8_t i; \
|
||||
\
|
||||
data->spi = device_get_binding(WS2812_SPI_BUS(idx)); \
|
||||
if (!data->spi) { \
|
||||
LOG_ERR("SPI device %s not found", \
|
||||
WS2812_SPI_BUS(idx)); \
|
||||
return -ENODEV; \
|
||||
} \
|
||||
\
|
||||
for (i = 0; i < cfg->num_colors; i++) { \
|
||||
switch (cfg->color_mapping[i]) { \
|
||||
case LED_COLOR_ID_WHITE: \
|
||||
case LED_COLOR_ID_RED: \
|
||||
case LED_COLOR_ID_GREEN: \
|
||||
case LED_COLOR_ID_BLUE: \
|
||||
break; \
|
||||
default: \
|
||||
LOG_ERR("%s: invalid channel to color mapping." \
|
||||
"Check the color-mapping DT property", \
|
||||
dev->name); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, \
|
||||
ws2812_spi_##idx##_init, \
|
||||
NULL, \
|
||||
&ws2812_spi_##idx##_data, \
|
||||
&ws2812_spi_##idx##_cfg, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_LED_STRIP_INIT_PRIORITY, \
|
||||
&ws2812_spi_api);
|
||||
#define WS2812_SPI_DEVICE(idx) \
|
||||
\
|
||||
static uint8_t ws2812_spi_##idx##_px_buf[WS2812_SPI_BUFSZ(idx)]; \
|
||||
\
|
||||
WS2812_COLOR_MAPPING(idx); \
|
||||
\
|
||||
static const struct ws2812_spi_cfg ws2812_spi_##idx##_cfg = { \
|
||||
.bus = SPI_DT_SPEC_INST_GET(idx, SPI_OPER, 0), \
|
||||
.px_buf = ws2812_spi_##idx##_px_buf, \
|
||||
.px_buf_size = WS2812_SPI_BUFSZ(idx), \
|
||||
.one_frame = WS2812_SPI_ONE_FRAME(idx), \
|
||||
.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), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, \
|
||||
ws2812_spi_init, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
&ws2812_spi_##idx##_cfg, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_LED_STRIP_INIT_PRIORITY, \
|
||||
&ws2812_spi_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(WS2812_SPI_DEVICE)
|
||||
|
|
Loading…
Reference in a new issue