@@ -206,20 +206,24 @@ static void init_timers_dma_up(void)
206206 timer_configs [timer_index ].dma_handle = stm32_dmachannel (io_timers [timer_index ].dshot .dma_map_up );
207207
208208 if (timer_configs [timer_index ].dma_handle == NULL ) {
209- PX4_DEBUG ("Failed to allocate Timer %u DMA UP" , timer_index );
209+ PX4_WARN ("Failed to allocate Timer %u DMA UP" , timer_index );
210210 continue ;
211211 }
212212
213213 PX4_INFO ("Allocated DMA UP Timer Index %u" , timer_index );
214214 timer_configs [timer_index ].initialized = true;
215215 }
216216
217- // Free the allocated DMA channels
218- for (uint8_t timer_index = 0 ; timer_index < MAX_IO_TIMERS ; timer_index ++ ) {
219- if (timer_configs [timer_index ].dma_handle != NULL ) {
220- stm32_dmafree (timer_configs [timer_index ].dma_handle );
221- timer_configs [timer_index ].dma_handle = NULL ;
222- PX4_INFO ("Freed DMA UP Timer Index %u" , timer_index );
217+ // Bidirectional DShot will free/allocate DMA stream on every update event. This is required
218+ // in order to reconfigure the DMA stream between Timer Burst and CaptureCompare.
219+ if (_bidirectional ) {
220+ // Free the allocated DMA channels
221+ for (uint8_t timer_index = 0 ; timer_index < MAX_IO_TIMERS ; timer_index ++ ) {
222+ if (timer_configs [timer_index ].dma_handle != NULL ) {
223+ stm32_dmafree (timer_configs [timer_index ].dma_handle );
224+ timer_configs [timer_index ].dma_handle = NULL ;
225+ PX4_INFO ("Freed DMA UP Timer Index %u" , timer_index );
226+ }
223227 }
224228 }
225229}
@@ -341,8 +345,15 @@ void up_dshot_trigger()
341345
342346 io_timer_set_dshot_burst_mode (timer_index , _dshot_frequency , channel_count );
343347
344- // Allocate DMA
345- if (timer_configs [timer_index ].dma_handle == NULL ) {
348+ if (_bidirectional ) {
349+ // Deallocate DMA from previous transaction
350+ if (timer_configs [timer_index ].dma_handle != NULL ) {
351+ stm32_dmastop (timer_configs [timer_index ].dma_handle );
352+ stm32_dmafree (timer_configs [timer_index ].dma_handle );
353+ timer_configs [timer_index ].dma_handle = NULL ;
354+ }
355+
356+ // Allocate DMA
346357 timer_configs [timer_index ].dma_handle = stm32_dmachannel (io_timers [timer_index ].dshot .dma_map_up );
347358
348359 if (timer_configs [timer_index ].dma_handle == NULL ) {
@@ -502,11 +513,8 @@ static void capture_complete_callback(void *arg)
502513 // Disable capture DMA
503514 io_timer_capture_dma_req (timer_index , capture_channel , false);
504515
505- if (timer_configs [timer_index ].dma_handle != NULL ) {
506- stm32_dmastop (timer_configs [timer_index ].dma_handle );
507- stm32_dmafree (timer_configs [timer_index ].dma_handle );
508- timer_configs [timer_index ].dma_handle = NULL ;
509- }
516+ // Stop DMA (should already be finished)
517+ stm32_dmastop (timer_configs [timer_index ].dma_handle );
510518
511519 // Re-initialize all output channels on this timer
512520 for (uint8_t output_channel = 0 ; output_channel < MAX_TIMER_IO_CHANNELS ; output_channel ++ ) {
0 commit comments