aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h10
-rw-r--r--demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h10
-rw-r--r--demos/ARMCM3-STM32F103/mcuconf.h10
-rw-r--r--demos/ARMCM3-STM32F107/mcuconf.h10
-rw-r--r--os/hal/platforms/STM32/adc_lld.c47
-rw-r--r--os/hal/platforms/STM32/adc_lld.h10
-rw-r--r--os/hal/platforms/STM32/hal_lld.c2
-rw-r--r--os/hal/platforms/STM32/spi_lld.c155
-rw-r--r--os/hal/platforms/STM32/spi_lld.h32
-rw-r--r--os/hal/platforms/STM32/stm32_dma.c361
-rw-r--r--os/hal/platforms/STM32/stm32_dma.h45
-rw-r--r--os/hal/platforms/STM32/uart_lld.c236
-rw-r--r--os/hal/platforms/STM32/uart_lld.h26
-rw-r--r--readme.txt3
-rw-r--r--testhal/STM32/ADC/mcuconf.h10
-rw-r--r--testhal/STM32/CAN/mcuconf.h10
-rw-r--r--testhal/STM32/GPT/mcuconf.h10
-rw-r--r--testhal/STM32/IRQ_STORM/mcuconf.h10
-rw-r--r--testhal/STM32/PWM-ICU/mcuconf.h10
-rw-r--r--testhal/STM32/SPI/mcuconf.h10
-rw-r--r--testhal/STM32/UART/mcuconf.h10
-rw-r--r--testhal/STM32/USB_CDC/mcuconf.h10
-rw-r--r--testhal/STM32/USB_MSC/mcuconf.h10
23 files changed, 563 insertions, 484 deletions
diff --git a/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h b/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h
index 9bc43776c..5b3a5c785 100644
--- a/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h
+++ b/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h
@@ -51,7 +51,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -128,9 +128,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -144,9 +142,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h b/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h
+++ b/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/demos/ARMCM3-STM32F103/mcuconf.h b/demos/ARMCM3-STM32F103/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/demos/ARMCM3-STM32F103/mcuconf.h
+++ b/demos/ARMCM3-STM32F103/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/demos/ARMCM3-STM32F107/mcuconf.h b/demos/ARMCM3-STM32F107/mcuconf.h
index 613541da4..fbebae6db 100644
--- a/demos/ARMCM3-STM32F107/mcuconf.h
+++ b/demos/ARMCM3-STM32F107/mcuconf.h
@@ -59,7 +59,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -136,9 +136,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -152,9 +150,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/os/hal/platforms/STM32/adc_lld.c b/os/hal/platforms/STM32/adc_lld.c
index 72574108f..8a8027e55 100644
--- a/os/hal/platforms/STM32/adc_lld.c
+++ b/os/hal/platforms/STM32/adc_lld.c
@@ -48,39 +48,35 @@ ADCDriver ADCD1;
/* Driver local functions. */
/*===========================================================================*/
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
/**
- * @brief ADC1 DMA interrupt handler (channel 1).
+ * @brief Shared ADC DMA ISR service routine.
*
- * @isr
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
- uint32_t isr;
-
- CH_IRQ_PROLOGUE();
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
- isr = STM32_DMA1->ISR;
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
- if ((isr & DMA_ISR_TEIF1) != 0) {
- /* DMA error processing.*/
- STM32_ADC1_DMA_ERROR_HOOK();
+ /* DMA errors handling.*/
+#if defined(STM32_ADC_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_ADC_DMA_ERROR_HOOK(spip);
}
- if ((isr & DMA_ISR_HTIF1) != 0) {
+#else
+ (void)flags;
+#endif
+ if ((flags & DMA_ISR_HTIF1) != 0) {
/* Half transfer processing.*/
- _adc_isr_half_code(&ADCD1);
+ _adc_isr_half_code(adcp);
}
- if ((isr & DMA_ISR_TCIF1) != 0) {
+ if ((flags & DMA_ISR_TCIF1) != 0) {
/* Transfer complete processing.*/
- _adc_isr_full_code(&ADCD1);
+ _adc_isr_full_code(adcp);
}
-
- CH_IRQ_EPILOGUE();
}
-#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -136,7 +132,8 @@ void adc_lld_start(ADCDriver *adcp) {
if (adcp->state == ADC_STOP) {
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp);
NVICEnableVector(DMA1_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY));
dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR);
@@ -167,7 +164,7 @@ void adc_lld_stop(ADCDriver *adcp) {
ADC1->CR1 = 0;
ADC1->CR2 = 0;
NVICDisableVector(DMA1_Channel1_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1);
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
}
#endif
diff --git a/os/hal/platforms/STM32/adc_lld.h b/os/hal/platforms/STM32/adc_lld.h
index 6f93170ed..3cc34735f 100644
--- a/os/hal/platforms/STM32/adc_lld.h
+++ b/os/hal/platforms/STM32/adc_lld.h
@@ -94,12 +94,12 @@
#endif
/**
- * @brief ADC1 DMA error hook.
+ * @brief ADC DMA error hook.
* @note The default action for DMA errors is a system halt because DMA
* error can only happen because programming errors.
*/
-#if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
#endif
/*===========================================================================*/
@@ -114,6 +114,10 @@
#error "ADC driver activated but no ADC peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/hal_lld.c b/os/hal/platforms/STM32/hal_lld.c
index 701ea8b50..784c159be 100644
--- a/os/hal/platforms/STM32/hal_lld.c
+++ b/os/hal/platforms/STM32/hal_lld.c
@@ -71,7 +71,7 @@ void hal_lld_init(void) {
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
-#if HAL_USE_ADC || HAL_USE_SPI || HAL_USE_UART
+#if defined(STM32_DMA_REQUIRED)
dmaInit();
#endif
}
diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c
index fccbf3329..72db75857 100644
--- a/os/hal/platforms/STM32/spi_lld.c
+++ b/os/hal/platforms/STM32/spi_lld.c
@@ -82,11 +82,21 @@ static uint16_t dummyrx;
}
/**
- * @brief Shared end-of-transfer service routine.
+ * @brief Shared end-of-rx service routine.
*
* @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_interrupt(SPIDriver *spip) {
+static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
/* Stop everything.*/
dma_stop(spip);
@@ -96,114 +106,28 @@ static void serve_interrupt(SPIDriver *spip) {
_spi_isr_code(spip);
}
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
/**
- * @brief SPI1 RX DMA interrupt handler (channel 2).
+ * @brief Shared end-of-tx service routine.
*
- * @isr
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
+static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
- STM32_SPI_SPI1_DMA_ERROR_HOOK();
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
}
- serve_interrupt(&SPID1);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief SPI1 TX DMA interrupt handler (channel 3).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI1_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
-
- CH_IRQ_EPILOGUE();
-}
+#else
+ (void)spip;
+ (void)flags;
#endif
-
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-/**
- * @brief SPI2 RX DMA interrupt handler (channel 4).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
- STM32_SPI_SPI2_DMA_ERROR_HOOK();
- }
- serve_interrupt(&SPID2);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
-
- CH_IRQ_EPILOGUE();
}
-/**
- * @brief SPI2 TX DMA interrupt handler (channel 5).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI2_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
-
- CH_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-/**
- * @brief SPI3 RX DMA interrupt handler (DMA2, channel 1).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA2->ISR & DMA_ISR_TEIF1) != 0) {
- STM32_SPI_SPI3_DMA_ERROR_HOOK();
- }
- serve_interrupt(&SPID3);
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief SPI3 TX DMA2 interrupt handler (DMA2, channel 2).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- STM32_SPI_SPI3_DMA_ERROR_HOOK();
- dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
-
- CH_IRQ_EPILOGUE();
-}
-#endif
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -256,7 +180,11 @@ void spi_lld_start(SPIDriver *spip) {
if (spip->state == SPI_STOP) {
#if STM32_SPI_USE_SPI1
if (&SPID1 == spip) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA1_Channel2_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel3_IRQn,
@@ -266,7 +194,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
#if STM32_SPI_USE_SPI2
if (&SPID2 == spip) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA1_Channel4_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel5_IRQn,
@@ -276,7 +208,11 @@ void spi_lld_start(SPIDriver *spip) {
#endif
#if STM32_SPI_USE_SPI3
if (&SPID3 == spip) {
- dmaEnable(DMA2_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip);
+ dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip);
NVICEnableVector(DMA2_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY));
NVICEnableVector(DMA2_Channel2_IRQn,
@@ -324,7 +260,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID1 == spip) {
NVICDisableVector(DMA1_Channel2_IRQn);
NVICDisableVector(DMA1_Channel3_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
}
#endif
@@ -332,7 +269,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID2 == spip) {
NVICDisableVector(DMA1_Channel4_IRQn);
NVICDisableVector(DMA1_Channel5_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
}
#endif
@@ -340,7 +278,8 @@ void spi_lld_stop(SPIDriver *spip) {
if (&SPID3 == spip) {
NVICDisableVector(DMA2_Channel1_IRQn);
NVICDisableVector(DMA2_Channel2_IRQn);
- dmaDisable(DMA2_ID);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1);
+ dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2);
RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN;
}
#endif
diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h
index ca5a6d111..49e03e38c 100644
--- a/os/hal/platforms/STM32/spi_lld.h
+++ b/os/hal/platforms/STM32/spi_lld.h
@@ -118,30 +118,12 @@
#endif
/**
- * @brief SPI1 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
+ * @brief SPI DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
*/
-#if !defined(STM32_SPI_SPI1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief SPI2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_SPI_SPI2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief SPI3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA error
- * can only happen because programming errors.
- */
-#if !defined(STM32_SPI_SPI3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
#endif
/*===========================================================================*/
@@ -164,6 +146,10 @@
#error "SPI driver activated but no SPI peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
diff --git a/os/hal/platforms/STM32/stm32_dma.c b/os/hal/platforms/STM32/stm32_dma.c
index be7833777..023f2fdd3 100644
--- a/os/hal/platforms/STM32/stm32_dma.c
+++ b/os/hal/platforms/STM32/stm32_dma.c
@@ -23,23 +23,43 @@
* @brief STM32 DMA helper driver code.
*
* @addtogroup STM32_DMA
+ * @details DMA sharing helper driver. In the STM32 the DMA channels are a
+ * shared resource, this driver allows to allocate and free DMA
+ * channels at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The DMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * IRSs when allocating channels.
* @{
*/
#include "ch.h"
#include "hal.h"
+#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
-/* Driver local variables. */
+/* Driver local variables and types. */
/*===========================================================================*/
-static cnt_t dmacnt1;
+/**
+ * @brief DMA ISR redirector type.
+ */
+typedef struct {
+ stm32_dmaisr_t dmaisrfunc;
+ void *dmaisrparam;
+} dma_isr_redir_t;
+
+static uint32_t dmamsk1;
+static dma_isr_redir_t dma1[7];
+
#if STM32_HAS_DMA2
-static cnt_t dmacnt2;
+static uint32_t dmamsk2;
+static dma_isr_redir_t dma2[5];
#endif
/*===========================================================================*/
@@ -50,6 +70,224 @@ static cnt_t dmacnt2;
/* Driver interrupt handlers. */
/*===========================================================================*/
+/**
+ * @brief DMA1 channel 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
+ if (dma1[0].dmaisrfunc)
+ dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
+ if (dma1[1].dmaisrfunc)
+ dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
+ if (dma1[2].dmaisrfunc)
+ dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
+ if (dma1[3].dmaisrfunc)
+ dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
+ if (dma1[4].dmaisrfunc)
+ dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 6 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
+ if (dma1[5].dmaisrfunc)
+ dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 channel 7 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4);
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
+ if (dma1[6].dmaisrfunc)
+ dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 channel 1 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
+ if (dma2[0].dmaisrfunc)
+ dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 2 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
+ if (dma2[1].dmaisrfunc)
+ dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 3 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3);
+ if (dma2[2].dmaisrfunc)
+ dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 4 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
+ if (dma2[3].dmaisrfunc)
+ dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 channel 5 shared interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
+ uint32_t isr;
+
+ CH_IRQ_PROLOGUE();
+
+ isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
+ dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
+ if (dma2[4].dmaisrfunc)
+ dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_HAS_DMA2 */
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -62,66 +300,135 @@ static cnt_t dmacnt2;
void dmaInit(void) {
int i;
- dmacnt1 = 0;
- for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--)
+ dmamsk1 = 0;
+ for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA1, i);
+ dma1[i].dmaisrfunc = NULL;
+ }
STM32_DMA1->IFCR = 0xFFFFFFFF;
#if STM32_HAS_DMA2
- dmacnt2 = 0;
- for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--)
+ dmamsk2 = 0;
+ for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
dmaDisableChannel(STM32_DMA2, i);
+ dma2[i].dmaisrfunc = NULL;
+ }
STM32_DMA1->IFCR = 0xFFFFFFFF;
#endif
}
/**
- * @brief Enables the specified DMA controller clock.
+ * @brief Allocates a DMA channel.
+ * @details The channel is allocated and, if required, the DMA clock enabled.
+ * Trying to allocate a channel already allocated is an illegal
+ * operation and is trapped if assertions are enabled.
+ * @pre The channel must not be already in use.
+ * @post The channel is allocated and the default ISR handler redirected
+ * to the specified function.
+ * @post The channel must be freed using @p dmaRelease() before it can
+ * be reused with another peripheral.
+ * @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma the DMA controller id
+ * @param[in] dma DMA controller id
+ * @param[in] channel requested channel id
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return The operation status.
+ * @retval FALSE operation successfully allocated.
+ * @retval TRUE the channel was already in use.
*
- * @api
+ * @special
*/
-void dmaEnable(uint32_t dma) {
+void dmaAllocate(uint32_t dma, uint32_t channel,
+ stm32_dmaisr_t func, void *param) {
+ chDbgCheck(func != NULL, "dmaAllocate");
+
+#if STM32_HAS_DMA2
switch (dma) {
- case DMA1_ID:
- if (dmacnt1++ == 0) {
+ case STM32_DMA1_ID:
+#else
+ (void)dma;
+#endif
+ /* Check if the channel is already taken.*/
+ chDbgAssert((dmamsk1 & (1 << channel)) == 0,
+ "dmaAllocate(), #1", "already allocated");
+
+ /* If the DMA unit was idle then the clock is enabled.*/
+ if (dmamsk1 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1->IFCR = 0x0FFFFFFF;
}
- break;
+
+ dmamsk1 |= 1 << channel;
+ dma1[channel].dmaisrfunc = func;
+ dma1[channel].dmaisrparam = param;
#if STM32_HAS_DMA2
- case DMA2_ID:
- if (dmacnt2++ == 0) {
+ break;
+ case STM32_DMA2_ID:
+ /* Check if the channel is already taken.*/
+ chDbgAssert((dmamsk2 & (1 << channel)) == 0,
+ "dmaAllocate(), #2", "already allocated");
+
+ /* If the DMA unit was idle then the clock is enabled.*/
+ if (dmamsk1 == 0) {
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
DMA2->IFCR = 0x0FFFFFFF;
}
+
+ dmamsk2 |= 1 << channel;
+ dma2[channel].dmaisrfunc = func;
+ dma2[channel].dmaisrparam = param;
break;
-#endif
}
+#endif
}
/**
- * @brief Disables the specified DMA controller clock.
+ * @brief Releases a DMA channel.
+ * @details The channel is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated channel is an illegal operation
+ * and is trapped if assertions are enabled.
+ * @pre The channel must have been allocated using @p dmaRequest().
+ * @post The channel is again available.
+ * @note This function can be invoked in both ISR or thread context.
*
- * @param[in] dma the DMA controller id
+ * @param[in] dma DMA controller id
+ * @param[in] channel requested channel id
*
- * @api
+ * @special
*/
-void dmaDisable(uint32_t dma) {
+void dmaRelease(uint32_t dma, uint32_t channel) {
+#if STM32_HAS_DMA2
switch (dma) {
- case DMA1_ID:
- if (--dmacnt1 == 0)
+ case STM32_DMA1_ID:
+#else
+ (void)dma;
+#endif
+ /* Check if the channel is not taken.*/
+ chDbgAssert((dmamsk1 & (1 << channel)) != 0,
+ "dmaRelease(), #1", "not allocated");
+
+ dma1[channel].dmaisrfunc = NULL;
+ dmamsk1 &= ~(1 << channel);
+ if (dmamsk1 == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
- break;
#if STM32_HAS_DMA2
- case DMA2_ID:
- if (--dmacnt2 == 0)
+ break;
+ case STM32_DMA2_ID:
+ /* Check if the channel is not taken.*/
+ chDbgAssert((dmamsk2 & (1 << channel)) != 0,
+ "dmaRelease(), #2", "not allocated");
+
+ dma2[channel].dmaisrfunc = NULL;
+ dmamsk2 &= ~(1 << channel);
+ if (dmamsk2 == 0)
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
break;
-#endif
}
+#endif
}
+#endif /* STM32_DMA_REQUIRED */
+
/** @} */
diff --git a/os/hal/platforms/STM32/stm32_dma.h b/os/hal/platforms/STM32/stm32_dma.h
index 96e802f82..66a2f8c69 100644
--- a/os/hal/platforms/STM32/stm32_dma.h
+++ b/os/hal/platforms/STM32/stm32_dma.h
@@ -36,11 +36,11 @@
/*===========================================================================*/
/** @brief DMA1 identifier.*/
-#define DMA1_ID 0
+#define STM32_DMA1_ID 0
/** @brief DMA2 identifier.*/
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
-#define DMA2_ID 1
+#define STM32_DMA2_ID 1
#endif
/*===========================================================================*/
@@ -56,7 +56,7 @@
/*===========================================================================*/
/**
- * @brief STM32 DMA channel memory structure.
+ * @brief STM32 DMA channel memory structure type.
*/
typedef struct {
volatile uint32_t CCR;
@@ -67,7 +67,7 @@ typedef struct {
} stm32_dma_channel_t;
/**
- * @brief STM32 DMA subsystem memory structure.
+ * @brief STM32 DMA subsystem memory structure type.
* @note This structure has been redefined here because it is convenient to
* have the channels organized as an array, the ST header does not
* do that.
@@ -78,6 +78,14 @@ typedef struct {
stm32_dma_channel_t channels[7];
} stm32_dma_t;
+/**
+ * @brief STM32 DMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
+
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
@@ -128,11 +136,12 @@ typedef struct {
/**
* @brief Associates a peripheral data register to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cpar value to be written in the CPAR register
*
- * @api
+ * @special
*/
#define dmaChannelSetPeripheral(dmachp, cpar) { \
(dmachp)->CPAR = (uint32_t)(cpar); \
@@ -143,13 +152,14 @@ typedef struct {
* @note This macro does not change the CPAR register because that register
* value does not change frequently, it usually points to a peripheral
* data register.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cndtr value to be written in the CNDTR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
- * @api
+ * @special
*/
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
(dmachp)->CNDTR = (uint32_t)(cndtr); \
@@ -159,10 +169,11 @@ typedef struct {
/**
* @brief DMA channel enable by channel pointer.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
- * @api
+ * @special
*/
#define dmaChannelEnable(dmachp) { \
(dmachp)->CCR |= DMA_CCR1_EN; \
@@ -171,10 +182,11 @@ typedef struct {
/**
* @brief DMA channel disable by channel pointer.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
- * @api
+ * @special
*/
#define dmaChannelDisable(dmachp) { \
(dmachp)->CCR = 0; \
@@ -187,6 +199,7 @@ typedef struct {
* data register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
@@ -194,7 +207,7 @@ typedef struct {
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
- * @api
+ * @special
*/
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
@@ -204,11 +217,12 @@ typedef struct {
* @brief DMA channel enable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaEnableChannel(dmap, ch) { \
dmaChannelEnable(&(dmap)->channels[ch]); \
@@ -218,11 +232,12 @@ typedef struct {
* @brief DMA channel disable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaDisableChannel(dmap, ch) { \
dmaChannelDisable(&(dmap)->channels[ch]); \
@@ -234,11 +249,12 @@ typedef struct {
* withdraw all the pending interrupt bits from the ISR register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
+ * @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
- * @api
+ * @special
*/
#define dmaClearChannel(dmap, ch){ \
(dmap)->IFCR = 1 << ((ch) * 4); \
@@ -252,8 +268,9 @@ typedef struct {
extern "C" {
#endif
void dmaInit(void);
- void dmaEnable(uint32_t dma);
- void dmaDisable(uint32_t dma);
+ void dmaAllocate(uint32_t dma, uint32_t channel,
+ stm32_dmaisr_t func, void *param);
+ void dmaRelease(uint32_t dma, uint32_t channel);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c
index 958c3da0f..e2f306302 100644
--- a/os/hal/platforms/STM32/uart_lld.c
+++ b/os/hal/platforms/STM32/uart_lld.c
@@ -164,17 +164,38 @@ static void usart_start(UARTDriver *uartp) {
* @brief RX DMA common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_rx_end_irq(UARTDriver *uartp) {
+static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
- uartp->rxstate = UART_RX_COMPLETE;
- if (uartp->config->rxend_cb != NULL)
- uartp->config->rxend_cb(uartp);
- /* If the callback didn't explicitly change state then the receiver
- automatically returns to the idle state.*/
- if (uartp->rxstate == UART_RX_COMPLETE) {
- uartp->rxstate = UART_RX_IDLE;
- set_rx_idle_loop(uartp);
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (uartp->rxstate == UART_RX_IDLE) {
+ /* Receiver in idle state, a callback is generated, if enabled, for each
+ received character and then the driver stays in the same state.*/
+ if (uartp->config->rxchar_cb != NULL)
+ uartp->config->rxchar_cb(uartp, uartp->rxbuf);
+ }
+ else {
+ /* Receiver in active state, a callback is generated, if enabled, after
+ a completed transfer.*/
+ dmaDisableChannel(uartp->dmap, uartp->dmarx);
+ uartp->rxstate = UART_RX_COMPLETE;
+ if (uartp->config->rxend_cb != NULL)
+ uartp->config->rxend_cb(uartp);
+ /* If the callback didn't explicitly change state then the receiver
+ automatically returns to the idle state.*/
+ if (uartp->rxstate == UART_RX_COMPLETE) {
+ uartp->rxstate = UART_RX_IDLE;
+ set_rx_idle_loop(uartp);
+ }
}
}
@@ -182,9 +203,20 @@ static void serve_rx_end_irq(UARTDriver *uartp) {
* @brief TX DMA common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
*/
-static void serve_tx_end_irq(UARTDriver *uartp) {
+static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & DMA_ISR_TEIF1) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ dmaDisableChannel(uartp->dmap, uartp->dmatx);
/* A callback is generated, if enabled, after a completed transfer.*/
uartp->txstate = UART_TX_COMPLETE;
if (uartp->config->txend1_cb != NULL)
@@ -194,6 +226,7 @@ static void serve_tx_end_irq(UARTDriver *uartp) {
if (uartp->txstate == UART_TX_COMPLETE)
uartp->txstate = UART_TX_IDLE;
}
+
/**
* @brief USART common service routine.
*
@@ -225,58 +258,6 @@ static void serve_usart_irq(UARTDriver *uartp) {
#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
/**
- * @brief USART1 RX DMA interrupt handler (channel 5).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD1;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF5) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- if (uartp->rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->config->rxchar_cb != NULL)
- uartp->config->rxchar_cb(uartp, uartp->rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART1 TX DMA interrupt handler (channel 4).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
- serve_tx_end_irq(&UARTD1);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART1 IRQ handler.
*
* @isr
@@ -293,58 +274,6 @@ CH_IRQ_HANDLER(USART1_IRQHandler) {
#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
/**
- * @brief USART2 RX DMA interrupt handler (channel 6).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD2;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF6) != 0) {
- STM32_UART_USART2_DMA_ERROR_HOOK();
- }
- if (uartp->rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->config->rxchar_cb != NULL)
- uartp->config->rxchar_cb(uartp, uartp->rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART2 TX DMA interrupt handler (channel 7).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF7) != 0) {
- STM32_UART_USART2_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
- serve_tx_end_irq(&UARTD2);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART2 IRQ handler.
*
* @isr
@@ -361,58 +290,6 @@ CH_IRQ_HANDLER(USART2_IRQHandler) {
#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
/**
- * @brief USART3 RX DMA interrupt handler (channel 3).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
- UARTDriver *uartp;
-
- CH_IRQ_PROLOGUE();
-
- uartp = &UARTD3;
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF3) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- if (uartp->rxstate == UART_RX_IDLE) {
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- if (uartp->config->rxchar_cb != NULL)
- uartp->config->rxchar_cb(uartp, uartp->rxbuf);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
- serve_rx_end_irq(uartp);
- }
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
- * @brief USART3 TX DMA interrupt handler (channel 2).
- *
- * @isr
- */
-CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
- STM32_UART_USART1_DMA_ERROR_HOOK();
- }
- dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
- serve_tx_end_irq(&UARTD3);
-
- CH_IRQ_EPILOGUE();
-}
-
-/**
* @brief USART3 IRQ handler.
*
* @isr
@@ -478,7 +355,11 @@ void uart_lld_start(UARTDriver *uartp) {
if (uartp->state == UART_STOP) {
#if STM32_UART_USE_USART1
if (&UARTD1 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
NVICEnableVector(USART1_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel4_IRQn,
@@ -491,7 +372,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if STM32_UART_USE_USART2
if (&UARTD2 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
NVICEnableVector(USART2_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel6_IRQn,
@@ -504,7 +389,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if STM32_UART_USE_USART3
if (&UARTD3 == uartp) {
- dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ /* Note, the DMA must be enabled before the IRQs.*/
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp);
+ dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp);
NVICEnableVector(USART3_IRQn,
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
NVICEnableVector(DMA1_Channel2_IRQn,
@@ -549,7 +438,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART1_IRQn);
NVICDisableVector(DMA1_Channel4_IRQn);
NVICDisableVector(DMA1_Channel5_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
return;
}
@@ -560,7 +450,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART2_IRQn);
NVICDisableVector(DMA1_Channel6_IRQn);
NVICDisableVector(DMA1_Channel7_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7);
RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
return;
}
@@ -571,7 +462,8 @@ void uart_lld_stop(UARTDriver *uartp) {
NVICDisableVector(USART3_IRQn);
NVICDisableVector(DMA1_Channel2_IRQn);
NVICDisableVector(DMA1_Channel3_IRQn);
- dmaDisable(DMA1_ID);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
+ dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
return;
}
diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h
index 0cd75a395..f24cd7b79 100644
--- a/os/hal/platforms/STM32/uart_lld.h
+++ b/os/hal/platforms/STM32/uart_lld.h
@@ -121,26 +121,8 @@
* @note The default action for DMA errors is a system halt because DMA
* error can only happen because programming errors.
*/
-#if !defined(STM32_UART_USART1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief USART2 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_UART_USART2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#endif
-
-/**
- * @brief USART3 DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_UART_USART3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
#endif
/*===========================================================================*/
@@ -164,6 +146,10 @@
#error "UART driver activated but no USART/UART peripheral assigned"
#endif
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
diff --git a/readme.txt b/readme.txt
index 3a464c3b1..68ac730ce 100644
--- a/readme.txt
+++ b/readme.txt
@@ -73,6 +73,9 @@
*** 2.3.2 ***
- FIX: Fixed spurious characters generated by Serial over USB driver (bug
3276379).
+- NEW: Now it is possible to share DMA channels in the STM32 HAL thanks
+ to a centralized manager. Channels are allocated when the driver is
+ started and released when it is stopped.
- OPT: STM32 PWM driver implementation simplified.
- CHANGE: Now pwmChangePeriod() does not implicitly disable the active
PWM channels.
diff --git a/testhal/STM32/ADC/mcuconf.h b/testhal/STM32/ADC/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/testhal/STM32/ADC/mcuconf.h
+++ b/testhal/STM32/ADC/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/CAN/mcuconf.h b/testhal/STM32/CAN/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/testhal/STM32/CAN/mcuconf.h
+++ b/testhal/STM32/CAN/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/GPT/mcuconf.h b/testhal/STM32/GPT/mcuconf.h
index c7dc8742c..023c2ef9f 100644
--- a/testhal/STM32/GPT/mcuconf.h
+++ b/testhal/STM32/GPT/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/IRQ_STORM/mcuconf.h b/testhal/STM32/IRQ_STORM/mcuconf.h
index d27660a12..416f38ce1 100644
--- a/testhal/STM32/IRQ_STORM/mcuconf.h
+++ b/testhal/STM32/IRQ_STORM/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/PWM-ICU/mcuconf.h b/testhal/STM32/PWM-ICU/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/testhal/STM32/PWM-ICU/mcuconf.h
+++ b/testhal/STM32/PWM-ICU/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/SPI/mcuconf.h b/testhal/STM32/SPI/mcuconf.h
index d1f919486..f4cd4d3e2 100644
--- a/testhal/STM32/SPI/mcuconf.h
+++ b/testhal/STM32/SPI/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/UART/mcuconf.h b/testhal/STM32/UART/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/testhal/STM32/UART/mcuconf.h
+++ b/testhal/STM32/UART/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/USB_CDC/mcuconf.h b/testhal/STM32/USB_CDC/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/testhal/STM32/USB_CDC/mcuconf.h
+++ b/testhal/STM32/USB_CDC/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
diff --git a/testhal/STM32/USB_MSC/mcuconf.h b/testhal/STM32/USB_MSC/mcuconf.h
index 94e9c5d15..93bae3aea 100644
--- a/testhal/STM32/USB_MSC/mcuconf.h
+++ b/testhal/STM32/USB_MSC/mcuconf.h
@@ -52,7 +52,7 @@
#define STM32_ADC_USE_ADC1 TRUE
#define STM32_ADC_ADC1_DMA_PRIORITY 3
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
/*
* CAN driver system settings.
@@ -129,9 +129,7 @@
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
@@ -145,9 +143,7 @@
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.