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 | \
|
#define SPI_OPER (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \
|
||||||
SPI_WORD_SET(SPI_FRAME_BITS) | SPI_LINES_SINGLE)
|
SPI_WORD_SET(SPI_FRAME_BITS) | SPI_LINES_SINGLE)
|
||||||
|
|
||||||
struct ws2812_spi_data {
|
|
||||||
const struct device *spi;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ws2812_spi_cfg {
|
struct ws2812_spi_cfg {
|
||||||
struct spi_config spi_cfg;
|
struct spi_dt_spec bus;
|
||||||
uint8_t *px_buf;
|
uint8_t *px_buf;
|
||||||
size_t px_buf_size;
|
size_t px_buf_size;
|
||||||
uint8_t one_frame;
|
uint8_t one_frame;
|
||||||
|
@ -51,11 +47,6 @@ struct ws2812_spi_cfg {
|
||||||
uint16_t reset_delay;
|
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)
|
static const struct ws2812_spi_cfg *dev_cfg(const struct device *dev)
|
||||||
{
|
{
|
||||||
return dev->config;
|
return dev->config;
|
||||||
|
@ -155,7 +146,7 @@ static int ws2812_strip_update_rgb(const struct device *dev,
|
||||||
/*
|
/*
|
||||||
* Display the pixel data.
|
* 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);
|
ws2812_reset_delay(cfg->reset_delay);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -169,6 +160,34 @@ static int ws2812_strip_update_channels(const struct device *dev,
|
||||||
return -ENOTSUP;
|
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 = {
|
static const struct led_strip_driver_api ws2812_spi_api = {
|
||||||
.update_rgb = ws2812_strip_update_rgb,
|
.update_rgb = ws2812_strip_update_rgb,
|
||||||
.update_channels = ws2812_strip_update_channels,
|
.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))
|
(DT_INST_PROP(idx, chain_length))
|
||||||
#define WS2812_SPI_HAS_WHITE(idx) \
|
#define WS2812_SPI_HAS_WHITE(idx) \
|
||||||
(DT_INST_PROP(idx, has_white_channel) == 1)
|
(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) \
|
#define WS2812_SPI_ONE_FRAME(idx) \
|
||||||
(DT_INST_PROP(idx, spi_one_frame))
|
(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))
|
(DT_INST_PROP(idx, spi_zero_frame))
|
||||||
#define WS2812_SPI_BUFSZ(idx) \
|
#define WS2812_SPI_BUFSZ(idx) \
|
||||||
(WS2812_NUM_COLORS(idx) * 8 * WS2812_SPI_NUM_PIXELS(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
|
* Retrieve the channel to color mapping (e.g. RGB, BGR, GRB, ...) from the
|
||||||
* "color-mapping" DT property.
|
* "color-mapping" DT property.
|
||||||
*/
|
*/
|
||||||
#define WS2812_COLOR_MAPPING(idx) \
|
#define WS2812_COLOR_MAPPING(idx) \
|
||||||
static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
|
static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
|
||||||
DT_INST_PROP(idx, color_mapping)
|
DT_INST_PROP(idx, color_mapping)
|
||||||
|
|
||||||
#define WS2812_NUM_COLORS(idx) (DT_INST_PROP_LEN(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. */
|
/* Get the latch/reset delay from the "reset-delay" DT property. */
|
||||||
#define WS2812_RESET_DELAY(idx) DT_INST_PROP(idx, reset_delay)
|
#define WS2812_RESET_DELAY(idx) DT_INST_PROP(idx, reset_delay)
|
||||||
|
|
||||||
#define WS2812_SPI_DEVICE(idx) \
|
#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)]; \
|
||||||
\
|
\
|
||||||
static uint8_t ws2812_spi_##idx##_px_buf[WS2812_SPI_BUFSZ(idx)]; \
|
WS2812_COLOR_MAPPING(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), \
|
||||||
static const struct ws2812_spi_cfg ws2812_spi_##idx##_cfg = { \
|
.px_buf = ws2812_spi_##idx##_px_buf, \
|
||||||
.spi_cfg = { \
|
.px_buf_size = WS2812_SPI_BUFSZ(idx), \
|
||||||
.frequency = WS2812_SPI_FREQ(idx), \
|
.one_frame = WS2812_SPI_ONE_FRAME(idx), \
|
||||||
.operation = SPI_OPER, \
|
.zero_frame = WS2812_SPI_ZERO_FRAME(idx), \
|
||||||
.slave = WS2812_SPI_SLAVE(idx), \
|
.num_colors = WS2812_NUM_COLORS(idx), \
|
||||||
.cs = NULL, \
|
.color_mapping = ws2812_spi_##idx##_color_mapping, \
|
||||||
}, \
|
.reset_delay = WS2812_RESET_DELAY(idx), \
|
||||||
.px_buf = ws2812_spi_##idx##_px_buf, \
|
}; \
|
||||||
.px_buf_size = WS2812_SPI_BUFSZ(idx), \
|
\
|
||||||
.one_frame = WS2812_SPI_ONE_FRAME(idx), \
|
DEVICE_DT_INST_DEFINE(idx, \
|
||||||
.zero_frame = WS2812_SPI_ZERO_FRAME(idx), \
|
ws2812_spi_init, \
|
||||||
.num_colors = WS2812_NUM_COLORS(idx), \
|
NULL, \
|
||||||
.color_mapping = ws2812_spi_##idx##_color_mapping, \
|
NULL, \
|
||||||
.reset_delay = WS2812_RESET_DELAY(idx), \
|
&ws2812_spi_##idx##_cfg, \
|
||||||
}; \
|
POST_KERNEL, \
|
||||||
\
|
CONFIG_LED_STRIP_INIT_PRIORITY, \
|
||||||
static int ws2812_spi_##idx##_init(const struct device *dev) \
|
&ws2812_spi_api);
|
||||||
{ \
|
|
||||||
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);
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(WS2812_SPI_DEVICE)
|
DT_INST_FOREACH_STATUS_OKAY(WS2812_SPI_DEVICE)
|
||||||
|
|
Loading…
Reference in a new issue