From da5080f92aa8b725e99d26269c714294c32e9d82 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 30 Jul 2010 18:02:52 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2098 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32F103-GCC/mcuconf.h | 9 ++- os/hal/platforms/STM32/uart_lld.c | 106 ++++++++++++++++++++++++++- os/hal/platforms/STM32/uart_lld.h | 66 ++++++++++++++++- 3 files changed, 177 insertions(+), 4 deletions(-) diff --git a/demos/ARMCM3-STM32F103-GCC/mcuconf.h b/demos/ARMCM3-STM32F103-GCC/mcuconf.h index 723b5b991..6e2caf61d 100644 --- a/demos/ARMCM3-STM32F103-GCC/mcuconf.h +++ b/demos/ARMCM3-STM32F103-GCC/mcuconf.h @@ -103,5 +103,12 @@ * UART driver system settings. */ #define STM32_UART_USE_USART1 TRUE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE #define STM32_UART_USART1_IRQ_PRIORITY 12 -#define STM32_UART_USART1_DMA_PRIORITY 1 +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK() chSysHalt() diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c index 7f55fabb0..6708fe1e6 100644 --- a/os/hal/platforms/STM32/uart_lld.c +++ b/os/hal/platforms/STM32/uart_lld.c @@ -39,6 +39,16 @@ UARTDriver UARTD1; #endif +/** @brief USART2 UART driver identifier.*/ +#if STM32_UART_USE_USART2 || defined(__DOXYGEN__) +UARTDriver UARTD2; +#endif + +/** @brief USART3 UART driver identifier.*/ +#if STM32_UART_USE_USART3 || defined(__DOXYGEN__) +UARTDriver UARTD3; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -272,6 +282,9 @@ CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { CH_IRQ_EPILOGUE(); } +/** + * @brief USART1 IRQ handler. + */ CH_IRQ_HANDLER(USART1_IRQHandler) { CH_IRQ_PROLOGUE(); @@ -280,7 +293,62 @@ CH_IRQ_HANDLER(USART1_IRQHandler) { CH_IRQ_EPILOGUE(); } -#endif +#endif /* STM32_UART_USE_USART1 */ + +#if STM32_UART_USE_USART2 || defined(__DOXYGEN__) +/** + * @brief USART2 RX DMA interrupt handler (channel 6). + */ +CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { + UARTDriver *uartp; + + CH_IRQ_PROLOGUE(); + + dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6); + uartp = &UARTD2; + if (uartp->ud_rxstate == UART_RX_IDLE) { + /* 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->ud_config->uc_rxchar != NULL) + uartp->ud_config->uc_rxchar(uartp->ud_rxbuf); + } + else { + /* Receiver in active state, a callback is generated, if enabled, after + a completed transfer.*/ + dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_6); + serve_rx_end_irq(uartp); + } + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief USART2 TX DMA interrupt handler (channel 7). + */ +CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + 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. + */ +CH_IRQ_HANDLER(USART2_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD2); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_USART2 */ /*===========================================================================*/ /* Driver exported functions. */ @@ -300,6 +368,16 @@ void uart_lld_init(void) { UARTD1.ud_dmatx = STM32_DMA_CHANNEL_5; UARTD1.ud_dmaccr = 0; #endif + +#if STM32_UART_USE_USART2 + RCC->APB1RSTR = RCC_APB1RSTR_USART2RST; + RCC->APB1RSTR = 0; + uartObjectInit(&UARTD2); + UARTD1.ud_usart = USART2; + UARTD1.ud_dmarx = STM32_DMA_CHANNEL_6; + UARTD1.ud_dmatx = STM32_DMA_CHANNEL_7; + UARTD1.ud_dmaccr = 0; +#endif } /** @@ -323,6 +401,19 @@ void uart_lld_start(UARTDriver *uartp) { } #endif +#if STM32_UART_USE_USART2 + if (&UARTD2 == uartp) { + dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/ + NVICEnableVector(USART2_IRQn, + CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); + NVICEnableVector(DMA1_Channel6_IRQn, + CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); + NVICEnableVector(DMA1_Channel7_IRQn, + CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); + RCC->APB1ENR |= RCC_APB2ENR_USART1EN; + } +#endif + /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ uartp->ud_dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12; @@ -357,6 +448,17 @@ void uart_lld_stop(UARTDriver *uartp) { return; } #endif + +#if STM32_UART_USE_USART2 + if (&UARTD2 == uartp) { + NVICDisableVector(USART2_IRQn); + NVICDisableVector(DMA1_Channel6_IRQn); + NVICDisableVector(DMA1_Channel7_IRQn); + dmaDisable(DMA1_ID); + RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; + return; + } +#endif } } @@ -372,7 +474,7 @@ void uart_lld_stop(UARTDriver *uartp) { void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { /* TX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmatx, n, &uartp->ud_txbuf, + dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmatx, n, txbuf, uartp->ud_dmaccr | DMA_CCR1_TEIE | DMA_CCR1_TCIE); dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmatx); } diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h index 50eacbd9c..d1033050e 100644 --- a/os/hal/platforms/STM32/uart_lld.h +++ b/os/hal/platforms/STM32/uart_lld.h @@ -47,6 +47,24 @@ #define STM32_UART_USE_USART1 TRUE #endif +/** + * @brief UART driver on USART2 enable switch. + * @details If set to @p TRUE the support for USART2 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__) +#define STM32_UART_USE_USART2 TRUE +#endif + +/** + * @brief UART driver on USART3 enable switch. + * @details If set to @p TRUE the support for USART3 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__) +#define STM32_UART_USE_USART3 TRUE +#endif + /** * @brief USART1 interrupt priority level setting. */ @@ -54,6 +72,20 @@ #define STM32_UART_USART1_IRQ_PRIORITY 12 #endif +/** + * @brief USART2 interrupt priority level setting. + */ +#if !defined(STM32_UART_USART2_IRQ_PRIO) || defined(__DOXYGEN__) +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART3 interrupt priority level setting. + */ +#if !defined(STM32_UART_USART3_IRQ_PRIO) || defined(__DOXYGEN__) +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#endif + /** * @brief USART1 DMA priority (0..3|lowest..highest). * @note The priority level is used for both the TX and RX DMA channels but @@ -61,9 +93,29 @@ * over the TX channel. */ #if !defined(STM32_UART_USART1_DMA_PRIO) || defined(__DOXYGEN__) -#define STM32_UART_USART1_DMA_PRIORITY 1 +#define STM32_UART_USART1_DMA_PRIORITY 0 #endif +/** + * @brief USART2 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_UART_USART2_DMA_PRIO) || defined(__DOXYGEN__) +#define STM32_UART_USART2_DMA_PRIORITY 0 +#endif +/** + * @brief USART3 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(STM32_UART_USART3_DMA_PRIO) || defined(__DOXYGEN__) +#define STM32_UART_USART3_DMA_PRIORITY 0 +#endif + + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -159,6 +211,18 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__) +extern UARTDriver UARTD1; +#endif + +#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__) +extern UARTDriver UARTD2; +#endif + +#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__) +extern UARTDriver UARTD3; +#endif + #ifdef __cplusplus extern "C" { #endif