From 01e1216f5e175166041820b67d1abafb81ae5c16 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 2 Dec 2018 16:38:55 +0000 Subject: Added UART7/8 support to STM32 UART USARTv1 driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12457 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c | 148 ++++++++++++++++++++++++++ os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h | 125 +++++++++++++++++++++- readme.txt | 1 + 3 files changed, 273 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c index f4370d28d..7d7fc8b2d 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c @@ -78,6 +78,22 @@ STM32_DMA_GETCHANNEL(STM32_UART_USART6_TX_DMA_STREAM, \ STM32_USART6_TX_DMA_CHN) +#define UART7_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART7_RX_DMA_STREAM, \ + STM32_UART7_RX_DMA_CHN) + +#define UART7_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART7_TX_DMA_STREAM, \ + STM32_UART7_TX_DMA_CHN) + +#define UART8_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART8_RX_DMA_STREAM, \ + STM32_UART8_RX_DMA_CHN) + +#define UART8_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART8_TX_DMA_STREAM, \ + STM32_UART8_TX_DMA_CHN) + #define STM32_UART45_CR2_CHECK_MASK \ (USART_CR2_STOP_0 | USART_CR2_CLKEN | USART_CR2_CPOL | USART_CR2_CPHA | \ USART_CR2_LBCL) @@ -120,6 +136,16 @@ UARTDriver UARTD5; UARTDriver UARTD6; #endif +/** @brief UART7 UART driver identifier.*/ +#if STM32_UART_USE_UART7 || defined(__DOXYGEN__) +UARTDriver UARTD7; +#endif + +/** @brief UART8 UART driver identifier.*/ +#if STM32_UART_USE_UART8 || defined(__DOXYGEN__) +UARTDriver UARTD8; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -442,6 +468,44 @@ OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) { } #endif /* STM32_UART_USE_USART6 */ +#if STM32_UART_USE_UART7 || defined(__DOXYGEN__) +#if !defined(STM32_UART7_HANDLER) +#error "STM32_UART7_HANDLER not defined" +#endif +/** + * @brief UART7 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD7); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_UART7 */ + +#if STM32_UART_USE_UART8 || defined(__DOXYGEN__) +#if !defined(STM32_UART8_HANDLER) +#error "STM32_UART8_HANDLER not defined" +#endif +/** + * @brief UART8 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD8); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_UART8 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -499,6 +563,22 @@ void uart_lld_init(void) { UARTD6.dmarx = STM32_DMA_STREAM(STM32_UART_USART6_RX_DMA_STREAM); UARTD6.dmatx = STM32_DMA_STREAM(STM32_UART_USART6_TX_DMA_STREAM); #endif + +#if STM32_UART_USE_UART7 + uartObjectInit(&UARTD7); + UARTD7.usart = UART7; + UARTD7.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + UARTD7.dmarx = STM32_DMA_STREAM(STM32_UART_UART7_RX_DMA_STREAM); + UARTD7.dmatx = STM32_DMA_STREAM(STM32_UART_UART7_TX_DMA_STREAM); +#endif + +#if STM32_UART_USE_UART8 + uartObjectInit(&UARTD8); + UARTD8.usart = UART8; + UARTD8.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + UARTD8.dmarx = STM32_DMA_STREAM(STM32_UART_UART8_RX_DMA_STREAM); + UARTD8.dmatx = STM32_DMA_STREAM(STM32_UART_UART8_TX_DMA_STREAM); +#endif } /** @@ -643,6 +723,58 @@ void uart_lld_start(UARTDriver *uartp) { } #endif +#if STM32_UART_USE_UART7 + if (&UARTD7 == uartp) { + bool b; + + osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0, + "specified invalid bits in UART7 CR2 register settings"); + osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0, + "specified invalid bits in UART7 CR3 register settings"); + + b = dmaStreamAllocate(uartp->dmarx, + STM32_UART_UART7_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(uartp->dmatx, + STM32_UART_UART7_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableUART7(true); + nvicEnableVector(STM32_UART7_NUMBER, STM32_UART_UART7_IRQ_PRIORITY); + uartp->dmamode |= STM32_DMA_CR_CHSEL(UART7_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY); + } +#endif + +#if STM32_UART_USE_UART8 + if (&UARTD8 == uartp) { + bool b; + + osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0, + "specified invalid bits in UART8 CR2 register settings"); + osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0, + "specified invalid bits in UART8 CR3 register settings"); + + b = dmaStreamAllocate(uartp->dmarx, + STM32_UART_UART8_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(uartp->dmatx, + STM32_UART_UART8_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableUART8(true); + nvicEnableVector(STM32_UART8_NUMBER, STM32_UART_UART8_IRQ_PRIORITY); + uartp->dmamode |= STM32_DMA_CR_CHSEL(UART8_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY); + } +#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.*/ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) @@ -718,6 +850,22 @@ void uart_lld_stop(UARTDriver *uartp) { return; } #endif + +#if STM32_UART_USE_UART7 + if (&UARTD7 == uartp) { + nvicDisableVector(STM32_UART7_NUMBER); + rccDisableUART7(); + return; + } +#endif + +#if STM32_UART_USE_UART8 + if (&UARTD8 == uartp) { + nvicDisableVector(STM32_UART8_NUMBER); + rccDisableUART8(); + return; + } +#endif } } diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h index fcf73e7fb..a1369cc1a 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h @@ -93,6 +93,24 @@ #define STM32_UART_USE_USART6 FALSE #endif +/** + * @brief UART driver on UART7 enable switch. + * @details If set to @p TRUE the support for UART7 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_UART7) || defined(__DOXYGEN__) +#define STM32_UART_USE_UART7 FALSE +#endif + +/** + * @brief UART driver on UART8 enable switch. + * @details If set to @p TRUE the support for UART8 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_UART8) || defined(__DOXYGEN__) +#define STM32_UART_USE_UART8 FALSE +#endif + /** * @brief USART1 interrupt priority level setting. */ @@ -135,6 +153,20 @@ #define STM32_UART_USART6_IRQ_PRIORITY 12 #endif +/** + * @brief UART7 interrupt priority level setting. + */ +#if !defined(STM32_UART_UART7_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART7_IRQ_PRIORITY 12 +#endif + +/** + * @brief UART8 interrupt priority level setting. + */ +#if !defined(STM32_UART_UART8_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART8_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 @@ -195,6 +227,26 @@ #define STM32_UART_USART6_DMA_PRIORITY 0 #endif +/** + * @brief UART7 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_UART7_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART7_DMA_PRIORITY 0 +#endif + +/** + * @brief UART8 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_UART8_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART8_DMA_PRIORITY 0 +#endif + /** * @brief USART DMA error hook. * @note The default action for DMA errors is a system halt because DMA @@ -247,9 +299,18 @@ #error "USART6 not present in the selected device" #endif +#if STM32_UART_USE_UART7 && !STM32_HAS_UART7 +#error "UART7 not present in the selected device" +#endif + +#if STM32_UART_USE_UART8 && !STM32_HAS_UART8 +#error "UART8 not present in the selected device" +#endif + #if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \ !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4 && \ - !STM32_UART_USE_UART5 && !STM32_UART_USE_USART6 + !STM32_UART_USE_UART5 && !STM32_UART_USE_USART6 && \ + !STM32_UART_USE_UART7 && !STM32_UART_USE_UART8 #error "UART driver activated but no USART/UART peripheral assigned" #endif @@ -283,6 +344,16 @@ #error "Invalid IRQ priority assigned to USART6" #endif +#if STM32_UART_USE_UART7 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART7_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART7" +#endif + +#if STM32_UART_USE_UART8 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART8_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART8" +#endif + #if STM32_UART_USE_USART1 && \ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART1_DMA_PRIORITY) #error "Invalid DMA priority assigned to USART1" @@ -313,6 +384,16 @@ #error "Invalid DMA priority assigned to USART6" #endif +#if STM32_UART_USE_UART7 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART7_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART7" +#endif + +#if STM32_UART_USE_UART8 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART8_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART8" +#endif + /* The following checks are only required when there is a DMA able to reassign streams to different channels.*/ #if STM32_ADVANCED_DMA @@ -347,6 +428,16 @@ #error "USART6 DMA streams not defined" #endif +#if STM32_UART_USE_UART7 && (!defined(STM32_UART_UART7_RX_DMA_STREAM) || \ + !defined(STM32_UART_UART7_TX_DMA_STREAM)) +#error "UART7 DMA streams not defined" +#endif + +#if STM32_UART_USE_UART8 && (!defined(STM32_UART_UART8_RX_DMA_STREAM) || \ + !defined(STM32_UART_UART8_TX_DMA_STREAM)) +#error "UART8 DMA streams not defined" +#endif + /* Check on the validity of the assigned DMA channels.*/ #if STM32_UART_USE_USART1 && \ !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \ @@ -421,6 +512,30 @@ #endif #endif /* STM32_ADVANCED_DMA */ +#if STM32_UART_USE_UART7 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_RX_DMA_STREAM, \ + STM32_UART7_RX_DMA_MSK) +#error "invalid DMA stream associated to UART7 RX" +#endif + +#if STM32_UART_USE_UART7 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_TX_DMA_STREAM, \ + STM32_UART7_TX_DMA_MSK) +#error "invalid DMA stream associated to UART7 TX" +#endif + +#if STM32_UART_USE_UART8 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_RX_DMA_STREAM, \ + STM32_UART8_RX_DMA_MSK) +#error "invalid DMA stream associated to UART8 RX" +#endif + +#if STM32_UART_USE_UART8 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_TX_DMA_STREAM, \ + STM32_UART8_TX_DMA_MSK) +#error "invalid DMA stream associated to UART8 TX" +#endif + #if !defined(STM32_DMA_REQUIRED) #define STM32_DMA_REQUIRED #endif @@ -604,6 +719,14 @@ extern UARTDriver UARTD5; extern UARTDriver UARTD6; #endif +#if STM32_UART_USE_UART7 && !defined(__DOXYGEN__) +extern UARTDriver UARTD7; +#endif + +#if STM32_UART_USE_UART8 && !defined(__DOXYGEN__) +extern UARTDriver UARTD8; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/readme.txt b/readme.txt index 2efe4d127..87b5176bd 100644 --- a/readme.txt +++ b/readme.txt @@ -75,6 +75,7 @@ ***************************************************************************** *** Next *** +- NEW: Added UART7/8 support to STM32 UART USARTv1 driver. - NEW: Added persistent storage interface to the STM32 RTCv2 driver. - NEW: STM32 RTCv2 driver now supports callbacks on events. - NEW: Added an EXTI helper driver for STM32. -- cgit v1.2.3