aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2015-07-26 06:17:10 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2015-07-26 06:17:10 +0000
commitc96f0b2bbf7c911a5d23d6c9920f1c6f4d766c8c (patch)
tree53c0ebd122fe369cc08b4ed3bf885ba39e9a07f1 /os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
parentb05e7e8c4464bda8fecd21ff80086a34edf9292c (diff)
downloadChibiOS-c96f0b2bbf7c911a5d23d6c9920f1c6f4d766c8c.tar.gz
ChibiOS-c96f0b2bbf7c911a5d23d6c9920f1c6f4d766c8c.tar.bz2
ChibiOS-c96f0b2bbf7c911a5d23d6c9920f1c6f4d766c8c.zip
More STM32L0xx support files.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8104 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c')
-rw-r--r--os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c224
1 files changed, 160 insertions, 64 deletions
diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
index 9fd59bbff..4f0d29eb1 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
+++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
@@ -15,10 +15,10 @@
*/
/**
- * @file DMAv1/stm32_dma.c
+ * @file STM32F3xx/stm32_dma.c
* @brief DMA helper driver code.
*
- * @addtogroup STM32_DMA_V1
+ * @addtogroup STM32F3xx_DMA
* @details DMA sharing helper driver. In the STM32 the DMA streams are a
* shared resource, this driver allows to allocate and free DMA
* streams at runtime in order to allow all the other device
@@ -54,6 +54,29 @@
*/
#define STM32_DMA_CCR_RESET_VALUE 0x00000000U
+/*
+ * Handling devices with shared DMA IRQ handlers.
+ */
+#if defined(STM32_DMA1_CH23_NUMBER)
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#endif
+
+#if defined(STM32_DMA1_CH4567_NUMBER)
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#endif
+
+#if STM32_ADVANCED_DMA == TRUE
+#define ADDR_DMA1_CSELR &DMA1_CSELR->CSELR
+#define ADDR_DMA2_CSELR &DMA2_CSELR->CSELR
+#else
+#define ADDR_DMA1_CSELR NULL
+#define ADDR_DMA2_CSELR NULL
+#endif
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -65,22 +88,28 @@
* @note Don't use this array directly, use the appropriate wrapper macros
* instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
*/
-const stm32_dma_stream_t __stm32_dma_streams[STM32_DMA_STREAMS] = {
- {DMA1_Channel1, &DMA1->IFCR, 0, 0, STM32_DMA1_STREAM1_EVENT_NUMBER},
- {DMA1_Channel2, &DMA1->IFCR, 4, 1, STM32_DMA1_STREAM2_EVENT_NUMBER},
- {DMA1_Channel3, &DMA1->IFCR, 8, 2, STM32_DMA1_STREAM3_EVENT_NUMBER},
- {DMA1_Channel4, &DMA1->IFCR, 12, 3, STM32_DMA1_STREAM4_EVENT_NUMBER},
- {DMA1_Channel5, &DMA1->IFCR, 16, 4, STM32_DMA1_STREAM5_EVENT_NUMBER},
-#if STM32_DMA_STREAMS > 5
- {DMA1_Channel6, &DMA1->IFCR, 20, 5, STM32_DMA1_STREAM6_EVENT_NUMBER},
- {DMA1_Channel7, &DMA1->IFCR, 24, 6, STM32_DMA1_STREAM7_EVENT_NUMBER},
+const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
+ {DMA1_Channel1, &DMA1->IFCR, ADDR_DMA1_CSELR, 0, 0, STM32_DMA1_CH1_NUMBER},
+ {DMA1_Channel2, &DMA1->IFCR, ADDR_DMA1_CSELR, 4, 1, STM32_DMA1_CH2_NUMBER},
+ {DMA1_Channel3, &DMA1->IFCR, ADDR_DMA1_CSELR, 8, 2, STM32_DMA1_CH3_NUMBER},
+ {DMA1_Channel4, &DMA1->IFCR, ADDR_DMA1_CSELR, 12, 3, STM32_DMA1_CH4_NUMBER},
+ {DMA1_Channel5, &DMA1->IFCR, ADDR_DMA1_CSELR, 16, 4, STM32_DMA1_CH5_NUMBER},
+#if STM32_DMA1_NUM_CHANNELS > 5
+ {DMA1_Channel6, &DMA1->IFCR, ADDR_DMA1_CSELR, 20, 5, STM32_DMA1_CH6_NUMBER},
+#else
+ {NULL, NULL, NULL, 0, 5, 0},
#endif
-#if STM32_DMA_STREAMS > 7
- {DMA2_Channel1, &DMA2->IFCR, 0, 7, STM32_DMA2_STREAM1_EVENT_NUMBER},
- {DMA2_Channel2, &DMA2->IFCR, 4, 8, STM32_DMA2_STREAM2_EVENT_NUMBER},
- {DMA2_Channel3, &DMA2->IFCR, 8, 9, STM32_DMA2_STREAM3_EVENT_NUMBER},
- {DMA2_Channel4, &DMA2->IFCR, 12, 10, STM32_DMA2_STREAM4_EVENT_NUMBER},
- {DMA2_Channel5, &DMA2->IFCR, 16, 11, STM32_DMA2_STREAM5_EVENT_NUMBER},
+#if STM32_DMA1_NUM_CHANNELS > 6
+ {DMA1_Channel7, &DMA1->IFCR, ADDR_DMA1_CSELR, 24, 6, STM32_DMA1_CH7_NUMBER},
+#else
+ {NULL, NULL, NULL, 0, 6, 0},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 0
+ {DMA2_Channel1, &DMA2->IFCR, ADDR_DMA2_CSELR, 0, 8, STM32_DMA2_CH1_NUMBER},
+ {DMA2_Channel2, &DMA2->IFCR, ADDR_DMA2_CSELR, 4, 9, STM32_DMA2_CH2_NUMBER},
+ {DMA2_Channel3, &DMA2->IFCR, ADDR_DMA2_CSELR, 8, 10, STM32_DMA2_CH3_NUMBER},
+ {DMA2_Channel4, &DMA2->IFCR, ADDR_DMA2_CSELR, 12, 11, STM32_DMA2_CH4_NUMBER},
+ {DMA2_Channel5, &DMA2->IFCR, ADDR_DMA2_CSELR, 16, 13, STM32_DMA2_CH5_NUMBER},
#endif
};
@@ -114,13 +143,12 @@ static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
/* Driver interrupt handlers. */
/*===========================================================================*/
-#if defined(STM32_DMA1_STREAM1_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 1 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM1_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -132,15 +160,44 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM1_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM2_EVENT_HANDLER) || defined(__DOXYGEN__)
+/* Channels 2 and 3 are shared on some devices.*/
+#if defined(STM32_DMA1_CH23_HANDLER)
+/**
+ * @brief DMA1 streams 2 and 3 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Check on channel 2.*/
+ flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 4;
+ if (dma_isr_redir[1].dma_func)
+ dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
+ }
+
+ /* Check on channel 3.*/
+ flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 8;
+ if (dma_isr_redir[2].dma_func)
+ dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
+ }
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /*!defined(STM32_DMA1_CH23_HANDLER) */
/**
* @brief DMA1 stream 2 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM2_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -152,15 +209,13 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM2_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM3_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 3 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM3_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -172,15 +227,66 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM3_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
+#endif /*!defined(STM32_DMA1_CH23_HANDLER) */
+
+
+/* Channels 4, 5, 6 and 7 are shared on some devices.*/
+#if defined(STM32_DMA1_CH4567_HANDLER)
+/**
+ * @brief DMA1 streams 4 and 5 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Check on channel 4.*/
+ flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 12;
+ if (dma_isr_redir[3].dma_func)
+ dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
+ }
+
+ /* Check on channel 5.*/
+ flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 16;
+ if (dma_isr_redir[4].dma_func)
+ dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
+ }
+
+#if STM32_DMA1_NUM_CHANNELS > 5
+ /* Check on channel 6.*/
+ flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 20;
+ if (dma_isr_redir[5].dma_func)
+ dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
+ }
#endif
-#if defined(STM32_DMA1_STREAM4_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if STM32_DMA1_NUM_CHANNELS > 6
+ /* Check on channel 7.*/
+ flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 24;
+ if (dma_isr_redir[6].dma_func)
+ dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
+ }
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /* !defined(STM32_DMA1_CH4567_HANDLER) */
/**
* @brief DMA1 stream 4 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM4_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -192,15 +298,13 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM4_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM5_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 5 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM5_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -212,15 +316,14 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM5_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM6_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if (STM32_DMA1_NUM_CHANNELS > 5) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 6 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM6_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -232,15 +335,15 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM6_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_DMA1_NUM_CHANNELS > 5 */
-#if defined(STM32_DMA1_STREAM7_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if (STM32_DMA1_NUM_CHANNELS > 6) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 7 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM7_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -252,15 +355,16 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM7_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_DMA1_NUM_CHANNELS > 6 */
+#endif /* !defined(STM32_DMA1_CH4567_HANDLER) */
-#if defined(STM32_DMA2_STREAM1_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if (STM32_DMA2_NUM_CHANNELS > 0) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 1 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM1_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -272,15 +376,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM1_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM2_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 2 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM2_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -292,15 +394,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM2_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM3_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 3 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM3_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -312,15 +412,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM3_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM4_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 4 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM4_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -332,15 +430,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM4_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM5_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 5 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -352,7 +448,7 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_DMA2_NUM_CHANNELS > 0 */
/*===========================================================================*/
/* Driver exported functions. */
@@ -366,13 +462,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) {
void dmaInit(void) {
int i;
- dma_streams_mask = 0;
+ dma_streams_mask = 0U;
for (i = 0; i < STM32_DMA_STREAMS; i++) {
- __stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE;
+ _stm32_dma_streams[i].channel->CCR = 0U;
dma_isr_redir[i].dma_func = NULL;
}
DMA1->IFCR = 0xFFFFFFFFU;
-#if STM32_HAS_DMA2
+#if STM32_DMA2_NUM_CHANNELS > 0
DMA2->IFCR = 0xFFFFFFFFU;
#endif
}
@@ -409,19 +505,19 @@ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
osalDbgCheck(dmastp != NULL);
/* Checks if the stream is already taken.*/
- if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
+ if ((dma_streams_mask & (1U << dmastp->selfindex)) != 0U)
return true;
/* Marks the stream as allocated.*/
dma_isr_redir[dmastp->selfindex].dma_func = func;
dma_isr_redir[dmastp->selfindex].dma_param = param;
- dma_streams_mask |= (1 << dmastp->selfindex);
+ dma_streams_mask |= (1U << dmastp->selfindex);
/* Enabling DMA clocks required by the current streams set.*/
- if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0U)
rccEnableDMA1(false);
-#if STM32_HAS_DMA2
- if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
+#if STM32_DMA2_NUM_CHANNELS > 0
+ if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0U)
rccEnableDMA2(false);
#endif
@@ -454,7 +550,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
osalDbgCheck(dmastp != NULL);
/* Check if the streams is not taken.*/
- osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
+ osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0U,
"not allocated");
/* Disables the associated IRQ vector.*/
@@ -464,10 +560,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
dma_streams_mask &= ~(1 << dmastp->selfindex);
/* Shutting down clocks that are no more required, if any.*/
- if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0U)
rccDisableDMA1(false);
-#if STM32_HAS_DMA2
- if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
+#if STM32_DMA2_NUM_CHANNELS > 0
+ if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0U)
rccDisableDMA2(false);
#endif
}