30
30
#define TIM_PERIOD ((168000000 / 2 / WS2812_CLK_HZ) - 1)
31
31
#define WS2812_ZERO (((uint32_t) TIM_PERIOD) * 0.3)
32
32
#define WS2812_ONE (((uint32_t) TIM_PERIOD) * 0.7)
33
- #define BITBUFFER_PAD 1000
34
33
35
34
typedef struct {
36
35
uint8_t pin_nr ;
@@ -90,6 +89,10 @@ static void disable_dma_stream(DMA_Stream_TypeDef *dma_stream) {
90
89
dma_stream -> CR &= ~DMA_SxCR_EN ;
91
90
}
92
91
92
+ static void enable_dma_stream (DMA_Stream_TypeDef * dma_stream ) {
93
+ dma_stream -> CR |= DMA_SxCR_EN ;
94
+ }
95
+
93
96
// Only DMA_Stream0 and DMA_Stream3 supported as of now.
94
97
static void init_dma_stream (
95
98
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(
110
113
}
111
114
112
115
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 |
114
117
DMA_Priority_High | DMA_MemoryBurst_Single | DMA_PeripheralBurst_Single ;
115
118
116
119
dma_stream -> FCR = 0x00000020 | DMA_FIFOThreshold_Full ;
@@ -119,8 +122,19 @@ static void init_dma_stream(
119
122
dma_stream -> NDTR = buf_len ;
120
123
dma_stream -> PAR = ccr_address ;
121
124
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 ;
124
138
}
125
139
126
140
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
181
195
driver -> bitbuffer_length += color_order_bits (strip -> color_order ) * strip -> length ;
182
196
}
183
197
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 ;
187
200
driver -> bitbuffer = VESC_IF -> malloc (sizeof (uint16_t ) * driver -> bitbuffer_length );
188
201
driver -> pin = pin ;
189
202
@@ -198,11 +211,11 @@ bool led_driver_setup(LedDriver *driver, LedPin pin, const LedStrip **led_strips
198
211
}
199
212
}
200
213
201
- for (uint32_t i = 0 ; i < padding_offset ; ++ i ) {
214
+ for (uint32_t i = 0 ; i < driver -> bitbuffer_length - 1 ; ++ i ) {
202
215
driver -> bitbuffer [i ] = WS2812_ZERO ;
203
216
}
217
+ driver -> bitbuffer [driver -> bitbuffer_length - 1 ] = 0 ;
204
218
205
- memset (driver -> bitbuffer + padding_offset , 0 , sizeof (uint16_t ) * BITBUFFER_PAD );
206
219
init_hw (pin , driver -> bitbuffer , driver -> bitbuffer_length );
207
220
return true;
208
221
}
@@ -274,6 +287,13 @@ void led_driver_paint(LedDriver *driver) {
274
287
}
275
288
}
276
289
}
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 );
277
297
}
278
298
279
299
void led_driver_destroy (LedDriver * driver ) {
0 commit comments