summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-11-24 15:40:59 +0000
committerDamien George <damien.p.george@gmail.com>2015-11-24 15:44:16 +0000
commit22bd23114af166980bad6ff00caaf97fdb1f2cf4 (patch)
tree4be3618d58fdebc611b95ebbb3de77592eb71ae6
parent9936aa3f87046c92ec8721a5f5734612e178e8eb (diff)
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.
-rw-r--r--stmhal/dma.c10
-rw-r--r--stmhal/dma.h4
-rw-r--r--stmhal/stm32_it.c6
3 files changed, 13 insertions, 7 deletions
diff --git a/stmhal/dma.c b/stmhal/dma.c
index 7abd521be..2b344141e 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 17ccd1a4b..3e6279261 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 8a00c1469..aaa1aaca7 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);
}
}