From 22bd23114af166980bad6ff00caaf97fdb1f2cf4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Nov 2015 15:40:59 +0000 Subject: [PATCH] stmhal: On SysTick IRQ, only process one DMA channel at a time. This can be generalised if/when more processing is needed by SysTick. Thanks to @chuckbook for the idea. --- stmhal/dma.c | 10 ++++++---- stmhal/dma.h | 4 ++-- stmhal/stm32_it.c | 6 +++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/stmhal/dma.c b/stmhal/dma.c index 7abd521be0..2b344141e9 100644 --- a/stmhal/dma.c +++ b/stmhal/dma.c @@ -220,14 +220,16 @@ void dma_invalidate_channel(DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel } } -// Called from the SysTick handler (once per millisecond) -void dma_idle_handler() { +// Called from the SysTick handler +// We use LSB of tick to select which controller to process +void dma_idle_handler(int tick) { static const uint32_t controller_mask[] = { DMA1_ENABLE_MASK, DMA2_ENABLE_MASK }; - for (int controller = 0; controller < NCONTROLLERS; controller++) { + { + int controller = tick & 1; if (dma_idle.counter[controller] == 0) { - continue; + return; } if (++dma_idle.counter[controller] > DMA_IDLE_TICK_MAX) { if ((dma_enable_mask & controller_mask[controller]) == 0) { diff --git a/stmhal/dma.h b/stmhal/dma.h index 17ccd1a4bb..3e62792613 100644 --- a/stmhal/dma.h +++ b/stmhal/dma.h @@ -38,7 +38,7 @@ typedef union { extern volatile dma_idle_count_t dma_idle; #define DMA_IDLE_ENABLED() (dma_idle.enabled != 0) -#define DMA_SYSTICK_MASK 0x0F +#define DMA_SYSTICK_MASK 0x0e #define DMA_MSECS_PER_SYSTICK (DMA_SYSTICK_MASK + 1) #define DMA_IDLE_TICK_MAX (8) // 128 msec #define DMA_IDLE_TICK(tick) (((tick) & DMA_SYSTICK_MASK) == 0) @@ -48,4 +48,4 @@ extern const DMA_InitTypeDef dma_init_struct_spi_i2c; void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, const DMA_InitTypeDef *dma_init, uint32_t dma_channel, uint32_t direction, void *data); void dma_deinit(DMA_HandleTypeDef *dma); void dma_invalidate_channel(DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel); -void dma_idle_handler(); +void dma_idle_handler(int controller); diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c index 8a00c1469e..aaa1aaca7f 100644 --- a/stmhal/stm32_it.c +++ b/stmhal/stm32_it.c @@ -269,8 +269,12 @@ void SysTick_Handler(void) { // work properly. SysTick->CTRL; + // Right now we just have the DMA controllers to process during this + // interrupt and we use a custom dispatch handler. If this needs to + // be generalised in the future then a dispatch table can be used as + // follows: ((void(*)(void))(systick_dispatch[uwTick & 0xf]))(); if (DMA_IDLE_ENABLED() && DMA_IDLE_TICK(uwTick)) { - dma_idle_handler(); + dma_idle_handler(uwTick); } }