Skip to content

Commit a688764

Browse files
committed
LEDs: Send LED signal at the end of paint
Instead of refreshing as fast as possible. Saves 2000B of RAM allocated for the LED DMA buffer in the Lisp memory pool.
1 parent c1375c1 commit a688764

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

src/led_driver.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#define TIM_PERIOD ((168000000 / 2 / WS2812_CLK_HZ) - 1)
3131
#define WS2812_ZERO (((uint32_t) TIM_PERIOD) * 0.3)
3232
#define WS2812_ONE (((uint32_t) TIM_PERIOD) * 0.7)
33-
#define BITBUFFER_PAD 1000
3433

3534
typedef struct {
3635
uint8_t pin_nr;
@@ -90,6 +89,10 @@ static void disable_dma_stream(DMA_Stream_TypeDef *dma_stream) {
9089
dma_stream->CR &= ~DMA_SxCR_EN;
9190
}
9291

92+
static void enable_dma_stream(DMA_Stream_TypeDef *dma_stream) {
93+
dma_stream->CR |= DMA_SxCR_EN;
94+
}
95+
9396
// Only DMA_Stream0 and DMA_Stream3 supported as of now.
9497
static void init_dma_stream(
9598
DMA_Stream_TypeDef *dma_stream, uint16_t *buf, uint32_t buf_len, uint32_t ccr_address
@@ -110,7 +113,7 @@ static void init_dma_stream(
110113
}
111114

112115
dma_stream->CR = DMA_Channel_2 | DMA_DIR_MemoryToPeripheral | DMA_MemoryInc_Enable |
113-
DMA_PeripheralDataSize_HalfWord | DMA_MemoryDataSize_HalfWord | DMA_Mode_Circular |
116+
DMA_PeripheralDataSize_HalfWord | DMA_MemoryDataSize_HalfWord | DMA_Mode_Normal |
114117
DMA_Priority_High | DMA_MemoryBurst_Single | DMA_PeripheralBurst_Single;
115118

116119
dma_stream->FCR = 0x00000020 | DMA_FIFOThreshold_Full;
@@ -119,8 +122,19 @@ static void init_dma_stream(
119122
dma_stream->NDTR = buf_len;
120123
dma_stream->PAR = ccr_address;
121124

122-
// enable the stream
123-
dma_stream->CR |= DMA_SxCR_EN;
125+
enable_dma_stream(dma_stream);
126+
}
127+
128+
static void reset_dma_stream_transfer_complete(DMA_Stream_TypeDef *dma_stream) {
129+
if (dma_stream == DMA1_Stream0) {
130+
DMA1->LIFCR |= DMA_LIFCR_CTCIF0;
131+
} else if (dma_stream == DMA1_Stream3) {
132+
DMA1->LIFCR |= DMA_LIFCR_CTCIF3;
133+
}
134+
}
135+
136+
static void disable_tim4_dma(uint16_t dma_source) {
137+
TIM4->DIER &= ~dma_source;
124138
}
125139

126140
static void enable_tim4_dma(uint16_t dma_source) {
@@ -181,9 +195,8 @@ bool led_driver_setup(LedDriver *driver, LedPin pin, const LedStrip **led_strips
181195
driver->bitbuffer_length += color_order_bits(strip->color_order) * strip->length;
182196
}
183197

184-
uint32_t padding_offset = driver->bitbuffer_length;
185-
186-
driver->bitbuffer_length += BITBUFFER_PAD;
198+
// An extra array item to set the output to 0 PWM
199+
++driver->bitbuffer_length;
187200
driver->bitbuffer = VESC_IF->malloc(sizeof(uint16_t) * driver->bitbuffer_length);
188201
driver->pin = pin;
189202

@@ -198,11 +211,11 @@ bool led_driver_setup(LedDriver *driver, LedPin pin, const LedStrip **led_strips
198211
}
199212
}
200213

201-
for (uint32_t i = 0; i < padding_offset; ++i) {
214+
for (uint32_t i = 0; i < driver->bitbuffer_length - 1; ++i) {
202215
driver->bitbuffer[i] = WS2812_ZERO;
203216
}
217+
driver->bitbuffer[driver->bitbuffer_length - 1] = 0;
204218

205-
memset(driver->bitbuffer + padding_offset, 0, sizeof(uint16_t) * BITBUFFER_PAD);
206219
init_hw(pin, driver->bitbuffer, driver->bitbuffer_length);
207220
return true;
208221
}
@@ -274,6 +287,13 @@ void led_driver_paint(LedDriver *driver) {
274287
}
275288
}
276289
}
290+
291+
PinHwConfig cfg = get_pin_hw_config(driver->pin);
292+
disable_tim4_dma(cfg.dma_source);
293+
disable_dma_stream(cfg.dma_stream);
294+
reset_dma_stream_transfer_complete(cfg.dma_stream);
295+
enable_dma_stream(cfg.dma_stream);
296+
enable_tim4_dma(cfg.dma_source);
277297
}
278298

279299
void led_driver_destroy(LedDriver *driver) {

0 commit comments

Comments
 (0)