Skip to content

Commit 89594e3

Browse files
fougekartben
authored andcommitted
apa102: fix end frame
end frame is used to supply clock pulses so that data goes to last LED in the chain. Thus, it depends on the number of LEDs in the chain. Previously, the number of ones sent into the end frame was hard-coded and limited the usage of the driver to 64 LEDs in the strip. Signed-off-by: Cyril Fougeray <[email protected]>
1 parent fd5b976 commit 89594e3

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

drivers/led_strip/apa102.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
struct apa102_config {
1616
struct spi_dt_spec bus;
1717
size_t length;
18+
uint8_t *const end_frame;
19+
const size_t end_frame_size;
1820
};
1921

2022
static int apa102_update(const struct device *dev, void *buf, size_t size)
2123
{
2224
const struct apa102_config *config = dev->config;
2325
static const uint8_t zeros[] = { 0, 0, 0, 0 };
24-
static const uint8_t ones[] = { 0xFF, 0xFF, 0xFF, 0xFF };
26+
2527
const struct spi_buf tx_bufs[] = {
2628
{
2729
/* Start frame: at least 32 zeros */
@@ -38,8 +40,8 @@ static int apa102_update(const struct device *dev, void *buf, size_t size)
3840
* remaining bits to the LEDs at the end of
3941
* the strip.
4042
*/
41-
.buf = (uint8_t *)ones,
42-
.len = sizeof(ones),
43+
.buf = (uint8_t *)config->end_frame,
44+
.len = config->end_frame_size,
4345
},
4446
};
4547
const struct spi_buf_set tx = {
@@ -89,6 +91,8 @@ static int apa102_init(const struct device *dev)
8991
return -ENODEV;
9092
}
9193

94+
memset(config->end_frame, 0xFF, config->end_frame_size);
95+
9296
return 0;
9397
}
9498

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

104+
/*
105+
* The "End frame" is statically allocated, as a sequence of 0xFF bytes
106+
* The only function of the “End frame” is to supply more clock pulses
107+
* to the string until the data has permeated to the last LED. The
108+
* number of clock pulses required is exactly half the total number
109+
* of LEDs in the string. See below `end_frame`.
110+
*/
100111
#define APA102_DEVICE(idx) \
112+
static uint8_t apa102_end_frame_##idx \
113+
[(DT_INST_PROP(idx, chain_length) / \
114+
sizeof(struct led_rgb) / 2) + 1]; \
101115
static const struct apa102_config apa102_##idx##_config = { \
102116
.bus = SPI_DT_SPEC_INST_GET( \
103117
idx, \
104118
SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), \
105119
0), \
106120
.length = DT_INST_PROP(idx, chain_length), \
121+
.end_frame = apa102_end_frame_##idx, \
122+
.end_frame_size = (DT_INST_PROP(idx, chain_length) / \
123+
sizeof(struct led_rgb) / 2) + 1, \
107124
}; \
108125
\
109126
DEVICE_DT_INST_DEFINE(idx, \

0 commit comments

Comments
 (0)