From 618a978da8f1b570236914e034fb91aa980b9ffc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 10 Apr 2011 16:45:41 +0000 Subject: [PATCH] Added DMA sharing in the STM32 HAL. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2874 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h | 10 +- demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h | 10 +- demos/ARMCM3-STM32F103/mcuconf.h | 10 +- demos/ARMCM3-STM32F107/mcuconf.h | 10 +- os/hal/platforms/STM32/adc_lld.c | 61 ++-- os/hal/platforms/STM32/adc_lld.h | 10 +- os/hal/platforms/STM32/hal_lld.c | 2 +- os/hal/platforms/STM32/spi_lld.c | 165 +++------- os/hal/platforms/STM32/spi_lld.h | 32 +- os/hal/platforms/STM32/stm32_dma.c | 365 +++++++++++++++++++-- os/hal/platforms/STM32/stm32_dma.h | 45 ++- os/hal/platforms/STM32/uart_lld.c | 236 ++++--------- os/hal/platforms/STM32/uart_lld.h | 26 +- readme.txt | 3 + testhal/STM32/ADC/mcuconf.h | 10 +- testhal/STM32/CAN/mcuconf.h | 10 +- testhal/STM32/GPT/mcuconf.h | 10 +- testhal/STM32/IRQ_STORM/mcuconf.h | 10 +- testhal/STM32/PWM-ICU/mcuconf.h | 10 +- testhal/STM32/SPI/mcuconf.h | 10 +- testhal/STM32/UART/mcuconf.h | 10 +- testhal/STM32/USB_CDC/mcuconf.h | 10 +- testhal/STM32/USB_MSC/mcuconf.h | 10 +- 23 files changed, 577 insertions(+), 498 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,40 +48,36 @@ ADCDriver ADCD1; /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Shared ADC DMA ISR service routine. + * + * @param[in] adcp pointer to the @p ADCDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(STM32_ADC_DMA_ERROR_HOOK) + if ((flags & DMA_ISR_TEIF1) != 0) { + STM32_ADC_DMA_ERROR_HOOK(spip); + } +#else + (void)flags; +#endif + if ((flags & DMA_ISR_HTIF1) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + if ((flags & DMA_ISR_TCIF1) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ -#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__) -/** - * @brief ADC1 DMA interrupt handler (channel 1). - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { - uint32_t isr; - - CH_IRQ_PROLOGUE(); - - 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(); - } - if ((isr & DMA_ISR_HTIF1) != 0) { - /* Half transfer processing.*/ - _adc_isr_half_code(&ADCD1); - } - if ((isr & DMA_ISR_TCIF1) != 0) { - /* Transfer complete processing.*/ - _adc_isr_full_code(&ADCD1); - } - - CH_IRQ_EPILOGUE(); -} -#endif - /*===========================================================================*/ /* 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,115 +106,29 @@ static void serve_interrupt(SPIDriver *spip) { _spi_isr_code(spip); } +/** + * @brief Shared end-of-tx service routine. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void spi_lld_serve_tx_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)spip; + (void)flags; +#endif +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ -#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__) -/** - * @brief SPI1 RX DMA interrupt handler (channel 2). - * - * @isr - */ -CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) { - STM32_SPI_SPI1_DMA_ERROR_HOOK(); - } - 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(); -} -#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 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) { - switch (dma) { - case DMA1_ID: - if (--dmacnt1 == 0) - RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; - break; #if STM32_HAS_DMA2 - case DMA2_ID: - if (--dmacnt2 == 0) + switch (dma) { + 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; +#if STM32_HAS_DMA2 + 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. * @@ -224,58 +257,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. * @@ -292,58 +273,6 @@ CH_IRQ_HANDLER(USART1_IRQHandler) { #endif /* STM32_UART_USE_USART1 */ #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. * @@ -360,58 +289,6 @@ CH_IRQ_HANDLER(USART2_IRQHandler) { #endif /* STM32_UART_USE_USART2 */ #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. * @@ -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.