Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions drivers/led_strip/apa102.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
struct apa102_config {
struct spi_dt_spec bus;
size_t length;
uint8_t *const end_frame;
const size_t end_frame_size;
};

static int apa102_update(const struct device *dev, void *buf, size_t size)
{
const struct apa102_config *config = dev->config;
static const uint8_t zeros[] = { 0, 0, 0, 0 };
static const uint8_t ones[] = { 0xFF, 0xFF, 0xFF, 0xFF };

const struct spi_buf tx_bufs[] = {
{
/* Start frame: at least 32 zeros */
Expand All @@ -38,8 +40,8 @@ static int apa102_update(const struct device *dev, void *buf, size_t size)
* remaining bits to the LEDs at the end of
* the strip.
*/
.buf = (uint8_t *)ones,
.len = sizeof(ones),
.buf = (uint8_t *)config->end_frame,
.len = config->end_frame_size,
},
};
const struct spi_buf_set tx = {
Expand Down Expand Up @@ -89,6 +91,8 @@ static int apa102_init(const struct device *dev)
return -ENODEV;
}

memset(config->end_frame, 0xFF, config->end_frame_size);

return 0;
}

Expand All @@ -97,13 +101,26 @@ static DEVICE_API(led_strip, apa102_api) = {
.length = apa102_length,
};

/*
* The "End frame" is statically allocated, as a sequence of 0xFF bytes
* The only function of the “End frame” is to supply more clock pulses
* to the string until the data has permeated to the last LED. The
* number of clock pulses required is exactly half the total number
* of LEDs in the string. See below `end_frame`.
*/
#define APA102_DEVICE(idx) \
static uint8_t apa102_end_frame_##idx \
[(DT_INST_PROP(idx, chain_length) / \
sizeof(struct led_rgb) / 2) + 1]; \
static const struct apa102_config apa102_##idx##_config = { \
.bus = SPI_DT_SPEC_INST_GET( \
idx, \
SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), \
0), \
.length = DT_INST_PROP(idx, chain_length), \
.end_frame = apa102_end_frame_##idx, \
.end_frame_size = (DT_INST_PROP(idx, chain_length) / \
sizeof(struct led_rgb) / 2) + 1, \
}; \
\
DEVICE_DT_INST_DEFINE(idx, \
Expand Down
Loading