From bf86c9d9beb4bfc9ce8505c873bc909d53f6424f Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 4 Aug 2015 12:49:40 +0000 Subject: Added support up to STM32 UART8 in v2 drivers. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8155 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/USARTv2/serial_lld.c | 106 ++++++++- os/hal/ports/STM32/LLD/USARTv2/serial_lld.h | 59 ++++- os/hal/ports/STM32/LLD/USARTv2/uart_lld.c | 354 +++++++++++++++++++++++++++- os/hal/ports/STM32/LLD/USARTv2/uart_lld.h | 347 +++++++++++++++++++++++++-- os/hal/ports/STM32/STM32F7xx/stm32_rcc.h | 90 +++++-- 5 files changed, 903 insertions(+), 53 deletions(-) (limited to 'os') diff --git a/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c b/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c index bf4ac2cd6..0c459c84e 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c @@ -69,6 +69,16 @@ SerialDriver SD5; SerialDriver SD6; #endif +/** @brief UART7 serial driver identifier.*/ +#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +SerialDriver SD7; +#endif + +/** @brief UART8 serial driver identifier.*/ +#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +SerialDriver SD8; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -97,7 +107,7 @@ static void usart_init(SerialDriver *sdp, const SerialConfig *config) { USART_TypeDef *u = sdp->usart; /* Baud rate setting.*/ - u->BRR = (uint16_t)(sdp->clock / config->speed); + u->BRR = (uint32_t)(sdp->clock / config->speed); /* Note that some bits are enforced.*/ u->CR2 = config->cr2 | USART_CR2_LBDIE; @@ -105,7 +115,7 @@ static void usart_init(SerialDriver *sdp, const SerialConfig *config) { u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; - u->ICR = 0xFFFFFFFF; + u->ICR = 0xFFFFFFFFU; } /** @@ -247,6 +257,22 @@ static void notify6(io_queue_t *qp) { } #endif +#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +static void notify7(io_queue_t *qp) { + + (void)qp; + UART7->CR1 |= USART_CR1_TXEIE; +} +#endif + +#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +static void notify8(io_queue_t *qp) { + + (void)qp; + UART8->CR1 |= USART_CR1_TXEIE; +} +#endif + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -365,6 +391,44 @@ OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) { } #endif +#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +#if !defined(STM32_UART7_HANDLER) +#error "STM32_UART7_HANDLER not defined" +#endif +/** + * @brief UART7 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&SD7); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +#if !defined(STM32_UART8_HANDLER) +#error "STM32_UART8_HANDLER not defined" +#endif +/** + * @brief UART8 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_interrupt(&SD8); + + OSAL_IRQ_EPILOGUE(); +} +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -411,6 +475,18 @@ void sd_lld_init(void) { SD6.usart = USART6; SD6.clock = STM32_USART6CLK; #endif + +#if STM32_SERIAL_USE_UART7 + sdObjectInit(&SD7, NULL, notify7); + SD7.usart = UART7; + SD7.clock = STM32_UART7CLK; +#endif + +#if STM32_SERIAL_USE_UART8 + sdObjectInit(&SD8, NULL, notify8); + SD8.usart = UART8; + SD8.clock = STM32_UART8CLK; +#endif } /** @@ -464,6 +540,18 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { rccEnableUSART6(FALSE); nvicEnableVector(STM32_USART6_NUMBER, STM32_SERIAL_USART6_PRIORITY); } +#endif +#if STM32_SERIAL_USE_UART7 + if (&SD7 == sdp) { + rccEnableUART7(FALSE); + nvicEnableVector(STM32_UART7_NUMBER, STM32_SERIAL_UART7_PRIORITY); + } +#endif +#if STM32_SERIAL_USE_UART8 + if (&SD8 == sdp) { + rccEnableUART8(FALSE); + nvicEnableVector(STM32_UART8_NUMBER, STM32_SERIAL_UART8_PRIORITY); + } #endif } usart_init(sdp, config); @@ -523,6 +611,20 @@ void sd_lld_stop(SerialDriver *sdp) { nvicDisableVector(STM32_USART6_NUMBER); return; } +#endif +#if STM32_SERIAL_USE_UART7 + if (&SD7 == sdp) { + rccDisableUART7(FALSE); + nvicDisableVector(STM32_UART7_NUMBER); + return; + } +#endif +#if STM32_SERIAL_USE_UART8 + if (&SD8 == sdp) { + rccDisableUART8(FALSE); + nvicDisableVector(STM32_UART8_NUMBER); + return; + } #endif } } diff --git a/os/hal/ports/STM32/LLD/USARTv2/serial_lld.h b/os/hal/ports/STM32/LLD/USARTv2/serial_lld.h index 522913aae..8385f310f 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/serial_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv2/serial_lld.h @@ -93,6 +93,24 @@ #define STM32_SERIAL_USE_USART6 FALSE #endif +/** + * @brief UART7 driver enable switch. + * @details If set to @p TRUE the support for UART7 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_SERIAL_USE_UART7) || defined(__DOXYGEN__) +#define STM32_SERIAL_USE_UART7 FALSE +#endif + +/** + * @brief UART8 driver enable switch. + * @details If set to @p TRUE the support for UART8 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_SERIAL_USE_UART8) || defined(__DOXYGEN__) +#define STM32_SERIAL_USE_UART8 FALSE +#endif + /** * @brief USART1 interrupt priority level setting. */ @@ -134,6 +152,20 @@ #if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__) #define STM32_SERIAL_USART6_PRIORITY 12 #endif + +/** + * @brief UART7 interrupt priority level setting. + */ +#if !defined(STM32_SERIAL_UART7_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SERIAL_UART7_PRIORITY 12 +#endif + +/** + * @brief UART8 interrupt priority level setting. + */ +#if !defined(STM32_SERIAL_UART8_PRIORITY) || defined(__DOXYGEN__) +#define STM32_SERIAL_UART8_PRIORITY 12 +#endif /** @} */ /*===========================================================================*/ @@ -164,9 +196,18 @@ #error "USART6 not present in the selected device" #endif +#if STM32_SERIAL_USE_UART5 && !STM32_HAS_UART5 +#error "UART5 not present in the selected device" +#endif + +#if STM32_SERIAL_USE_UART8 && !STM32_HAS_UART8 +#error "UART8 not present in the selected device" +#endif + #if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 && \ !STM32_SERIAL_USE_USART3 && !STM32_SERIAL_USE_UART4 && \ - !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 + !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 && \ + !STM32_SERIAL_USE_UART7 && !STM32_SERIAL_USE_UART8 #error "SERIAL driver activated but no USART/UART peripheral assigned" #endif @@ -200,6 +241,16 @@ #error "Invalid IRQ priority assigned to USART6" #endif +#if STM32_SERIAL_USE_UART7 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART7_PRIORITY) +#error "Invalid IRQ priority assigned to UART7" +#endif + +#if STM32_SERIAL_USE_UART8 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART8_PRIORITY) +#error "Invalid IRQ priority assigned to UART8" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -287,6 +338,12 @@ extern SerialDriver SD5; #if STM32_SERIAL_USE_USART6 && !defined(__DOXYGEN__) extern SerialDriver SD6; #endif +#if STM32_SERIAL_USE_UART7 && !defined(__DOXYGEN__) +extern SerialDriver SD7; +#endif +#if STM32_SERIAL_USE_UART8 && !defined(__DOXYGEN__) +extern SerialDriver SD8; +#endif #ifdef __cplusplus extern "C" { diff --git a/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c b/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c index 95e80594d..aacc7c925 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c @@ -54,6 +54,38 @@ STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM, \ STM32_USART3_TX_DMA_CHN) +#define UART4_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART4_RX_DMA_STREAM, \ + STM32_UART4_RX_DMA_CHN) + +#define UART4_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART4_TX_DMA_STREAM, \ + STM32_UART4_TX_DMA_CHN) + +#define UART5_RX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART5_RX_DMA_STREAM, \ + STM32_UART5_RX_DMA_CHN) + +#define UART5_TX_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_UART_UART5_TX_DMA_STREAM, \ + STM32_UART5_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) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -73,6 +105,31 @@ UARTDriver UARTD2; UARTDriver UARTD3; #endif +/** @brief UART4 UART driver identifier.*/ +#if STM32_UART_USE_UART4 || defined(__DOXYGEN__) +UARTDriver UARTD4; +#endif + +/** @brief UART5 UART driver identifier.*/ +#if STM32_UART_USE_UART5 || defined(__DOXYGEN__) +UARTDriver UARTD5; +#endif + +/** @brief USART6 UART driver identifier.*/ +#if STM32_UART_USE_USART6 || defined(__DOXYGEN__) +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. */ /*===========================================================================*/ @@ -156,20 +213,10 @@ static void usart_start(UARTDriver *uartp) { usart_stop(uartp); /* Baud rate setting.*/ -#if defined(STM32F0XX) - if (uartp->usart == USART1) - u->BRR = STM32_USART1CLK / uartp->config->speed; - else - u->BRR = STM32_PCLK / uartp->config->speed; -#else /* !defined(STM32F0XX) */ - if (uartp->usart == USART1) - u->BRR = STM32_PCLK2 / uartp->config->speed; - else - u->BRR = STM32_PCLK1 / uartp->config->speed; -#endif /* !defined(STM32F0XX) */ + u->BRR = (uint32_t)(uartp->clock / uartp->config->speed); /* Resetting eventual pending status flags.*/ - u->ICR = 0xFFFFFFFF; + u->ICR = 0xFFFFFFFFU; /* Note that some bits are enforced because required for correct driver operations.*/ @@ -347,6 +394,101 @@ OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) { } #endif /* STM32_UART_USE_USART3 */ +#if STM32_UART_USE_UART4 || defined(__DOXYGEN__) +#if !defined(STM32_UART4_HANDLER) +#error "STM32_UART4_HANDLER not defined" +#endif +/** + * @brief UART4 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD4); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_UART4 */ + +#if STM32_UART_USE_UART5 || defined(__DOXYGEN__) +#if !defined(STM32_UART5_HANDLER) +#error "STM32_UART5_HANDLER not defined" +#endif +/** + * @brief UART5 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD5); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* STM32_UART_USE_UART5 */ + +#if STM32_UART_USE_USART6 || defined(__DOXYGEN__) +#if !defined(STM32_USART6_HANDLER) +#error "STM32_USART6_HANDLER not defined" +#endif +/** + * @brief USART6 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + serve_usart_irq(&UARTD6); + + OSAL_IRQ_EPILOGUE(); +} +#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. */ /*===========================================================================*/ @@ -361,6 +503,7 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART1 uartObjectInit(&UARTD1); UARTD1.usart = USART1; + UARTD1.clock = STM32_USART1CLK; UARTD1.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; UARTD1.dmarx = STM32_DMA_STREAM(STM32_UART_USART1_RX_DMA_STREAM); UARTD1.dmatx = STM32_DMA_STREAM(STM32_UART_USART1_TX_DMA_STREAM); @@ -369,6 +512,7 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART2 uartObjectInit(&UARTD2); UARTD2.usart = USART2; + UARTD2.clock = STM32_USART2CLK; UARTD2.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; UARTD2.dmarx = STM32_DMA_STREAM(STM32_UART_USART2_RX_DMA_STREAM); UARTD2.dmatx = STM32_DMA_STREAM(STM32_UART_USART2_TX_DMA_STREAM); @@ -377,10 +521,56 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART3 uartObjectInit(&UARTD3); UARTD3.usart = USART3; + UARTD3.clock = STM32_USART3CLK; UARTD3.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; UARTD3.dmarx = STM32_DMA_STREAM(STM32_UART_USART3_RX_DMA_STREAM); UARTD3.dmatx = STM32_DMA_STREAM(STM32_UART_USART3_TX_DMA_STREAM); #endif + +#if STM32_UART_USE_UART4 + uartObjectInit(&UARTD4); + UARTD4.usart = UART4; + UARTD4.clock = STM32_UART4CLK; + UARTD4.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + UARTD4.dmarx = STM32_DMA_STREAM(STM32_UART_UART4_RX_DMA_STREAM); + UARTD4.dmatx = STM32_DMA_STREAM(STM32_UART_UART4_TX_DMA_STREAM); +#endif + +#if STM32_UART_USE_UART5 + uartObjectInit(&UARTD5); + UARTD5.usart = UART5; + UARTD5.clock = STM32_UART5CLK; + UARTD5.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + UARTD5.dmarx = STM32_DMA_STREAM(STM32_UART_UART5_RX_DMA_STREAM); + UARTD5.dmatx = STM32_DMA_STREAM(STM32_UART_UART5_TX_DMA_STREAM); +#endif + +#if STM32_UART_USE_USART6 + uartObjectInit(&UARTD6); + UARTD6.usart = USART6; + UARTD6.clock = STM32_USART6CLK; + UARTD6.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; + 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.clock = STM32_UART7CLK; + 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.clock = STM32_UART8CLK; + 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 } /** @@ -453,6 +643,106 @@ void uart_lld_start(UARTDriver *uartp) { } #endif +#if STM32_UART_USE_UART4 + if (&UARTD4 == uartp) { + bool b; + b = dmaStreamAllocate(uartp->dmarx, + STM32_UART_UART4_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(uartp->dmatx, + STM32_UART_UART4_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableUART4(FALSE); + nvicEnableVector(STM32_UART4_NUMBER, STM32_UART_UART4_IRQ_PRIORITY); + uartp->dmamode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY); + } +#endif + +#if STM32_UART_USE_UART5 + if (&UARTD5 == uartp) { + bool b; + b = dmaStreamAllocate(uartp->dmarx, + STM32_UART_UART5_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(uartp->dmatx, + STM32_UART_UART5_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableUART5(FALSE); + nvicEnableVector(STM32_UART5_NUMBER, STM32_UART_UART5_IRQ_PRIORITY); + uartp->dmamode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY); + } +#endif + +#if STM32_UART_USE_USART6 + if (&UARTD6 == uartp) { + bool b; + b = dmaStreamAllocate(uartp->dmarx, + STM32_UART_USART6_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + b = dmaStreamAllocate(uartp->dmatx, + STM32_UART_USART6_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(!b, "stream already allocated"); + rccEnableUSART6(FALSE); + nvicEnableVector(STM32_USART6_NUMBER, STM32_UART_USART6_IRQ_PRIORITY); + uartp->dmamode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY); + } +#endif + +#if STM32_UART_USE_UART7 + if (&UARTD7 == uartp) { + bool b; + 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(FALSE); + 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; + 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(FALSE); + 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) @@ -504,6 +794,46 @@ void uart_lld_stop(UARTDriver *uartp) { return; } #endif + +#if STM32_UART_USE_UART4 + if (&UARTD4 == uartp) { + nvicDisableVector(STM32_UART4_NUMBER); + rccDisableUART4(FALSE); + return; + } +#endif + +#if STM32_UART_USE_UART5 + if (&UARTD5 == uartp) { + nvicDisableVector(STM32_UART5_NUMBER); + rccDisableUART5(FALSE); + return; + } +#endif + +#if STM32_UART_USE_USART6 + if (&UARTD6 == uartp) { + nvicDisableVector(STM32_USART6_NUMBER); + rccDisableUSART6(FALSE); + return; + } +#endif + +#if STM32_UART_USE_UART7 + if (&UARTD7 == uartp) { + nvicDisableVector(STM32_UART7_NUMBER); + rccDisableUART7(FALSE); + return; + } +#endif + +#if STM32_UART_USE_UART8 + if (&UARTD8 == uartp) { + nvicDisableVector(STM32_UART8_NUMBER); + rccDisableUART8(FALSE); + return; + } +#endif } } diff --git a/os/hal/ports/STM32/LLD/USARTv2/uart_lld.h b/os/hal/ports/STM32/LLD/USARTv2/uart_lld.h index ebd2e34fd..b8c227842 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/uart_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv2/uart_lld.h @@ -66,6 +66,51 @@ #define STM32_UART_USE_USART3 FALSE #endif +/** + * @brief UART driver on UART4 enable switch. + * @details If set to @p TRUE the support for UART4 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__) +#define STM32_UART_USE_UART4 FALSE +#endif + +/** + * @brief UART driver on UART5 enable switch. + * @details If set to @p TRUE the support for UART5 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_UART5) || defined(__DOXYGEN__) +#define STM32_UART_USE_UART5 FALSE +#endif + +/** + * @brief UART driver on USART6 enable switch. + * @details If set to @p TRUE the support for USART6 is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_UART_USE_USART6) || defined(__DOXYGEN__) +#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. */ @@ -87,6 +132,41 @@ #define STM32_UART_USART3_IRQ_PRIORITY 12 #endif +/** + * @brief UART4 interrupt priority level setting. + */ +#if !defined(STM32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART4_IRQ_PRIORITY 12 +#endif + +/** + * @brief UART5 interrupt priority level setting. + */ +#if !defined(STM32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART5_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART6 interrupt priority level setting. + */ +#if !defined(STM32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__) +#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 @@ -118,7 +198,57 @@ #endif /** - * @brief USART1 DMA error hook. + * @brief UART4 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_UART4_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART4_DMA_PRIORITY 0 +#endif + +/** + * @brief UART5 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_UART5_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_UART_UART5_DMA_PRIORITY 0 +#endif + +/** + * @brief USART6 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_USART6_DMA_PRIORITY) || defined(__DOXYGEN__) +#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 UART DMA error hook. * @note The default action for DMA errors is a system halt because DMA * error can only happen because programming errors. */ @@ -143,8 +273,26 @@ #error "USART3 not present in the selected device" #endif +#if STM32_UART_USE_UART4 && !STM32_HAS_UART4 +#error "UART4 not present in the selected device" +#endif + +#if STM32_UART_USE_UART5 && !STM32_HAS_UART5 +#error "UART5 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_USART3 && !STM32_UART_USE_UART4 && \ + !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 @@ -163,6 +311,31 @@ #error "Invalid IRQ priority assigned to USART3" #endif +#if STM32_UART_USE_UART4 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART4_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART4" +#endif + +#if STM32_UART_USE_UART5 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART5_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART5" +#endif + +#if STM32_UART_USE_USART6 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART6_IRQ_PRIORITY) +#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" @@ -178,6 +351,31 @@ #error "Invalid DMA priority assigned to USART3" #endif +#if STM32_UART_USE_UART4 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART4_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART4" +#endif + +#if STM32_UART_USE_UART5 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART5_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART5" +#endif + +#if STM32_UART_USE_USART6 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART6_DMA_PRIORITY) +#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 @@ -197,6 +395,31 @@ #error "USART3 DMA streams not defined" #endif +#if STM32_UART_USE_UART4 && (!defined(STM32_UART_UART4_RX_DMA_STREAM) || \ + !defined(STM32_UART_UART4_TX_DMA_STREAM)) +#error "UART4 DMA streams not defined" +#endif + +#if STM32_UART_USE_UART5 && (!defined(STM32_UART_UART5_RX_DMA_STREAM) || \ + !defined(STM32_UART_UART5_TX_DMA_STREAM)) +#error "UART5 DMA streams not defined" +#endif + +#if STM32_UART_USE_USART6 && (!defined(STM32_UART_USART6_RX_DMA_STREAM) || \ + !defined(STM32_UART_USART6_TX_DMA_STREAM)) +#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, \ @@ -233,6 +456,66 @@ STM32_USART3_TX_DMA_MSK) #error "invalid DMA stream associated to USART3 TX" #endif + +#if STM32_UART_USE_UART4 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_RX_DMA_STREAM, \ + STM32_UART4_RX_DMA_MSK) +#error "invalid DMA stream associated to UART4 RX" +#endif + +#if STM32_UART_USE_UART4 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_TX_DMA_STREAM, \ + STM32_UART4_TX_DMA_MSK) +#error "invalid DMA stream associated to UART4 TX" +#endif + +#if STM32_UART_USE_UART5 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_RX_DMA_STREAM, \ + STM32_UART5_RX_DMA_MSK) +#error "invalid DMA stream associated to UART5 RX" +#endif + +#if STM32_UART_USE_UART5 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_TX_DMA_STREAM, \ + STM32_UART5_TX_DMA_MSK) +#error "invalid DMA stream associated to UART5 TX" +#endif + +#if STM32_UART_USE_USART6 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_RX_DMA_STREAM, \ + STM32_USART6_RX_DMA_MSK) +#error "invalid DMA stream associated to USART6 RX" +#endif + +#if STM32_UART_USE_USART6 && \ + !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_TX_DMA_STREAM, \ + STM32_USART6_TX_DMA_MSK) +#error "invalid DMA stream associated to USART6 TX" +#endif + +#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 #endif /* STM32_ADVANCED_DMA */ #if !defined(STM32_DMA_REQUIRED) @@ -282,40 +565,40 @@ typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); */ typedef struct { /** - * @brief End of transmission buffer callback. + * @brief End of transmission buffer callback. */ uartcb_t txend1_cb; /** - * @brief Physical end of transmission callback. + * @brief Physical end of transmission callback. */ uartcb_t txend2_cb; /** - * @brief Receive buffer filled callback. + * @brief Receive buffer filled callback. */ uartcb_t rxend_cb; /** - * @brief Character received while out if the @p UART_RECEIVE state. + * @brief Character received while out if the @p UART_RECEIVE state. */ uartccb_t rxchar_cb; /** - * @brief Receive error callback. + * @brief Receive error callback. */ uartecb_t rxerr_cb; /* End of the mandatory fields.*/ /** - * @brief Bit rate. + * @brief Bit rate. */ uint32_t speed; /** - * @brief Initialization value for the CR1 register. + * @brief Initialization value for the CR1 register. */ uint32_t cr1; /** - * @brief Initialization value for the CR2 register. + * @brief Initialization value for the CR2 register. */ uint32_t cr2; /** - * @brief Initialization value for the CR3 register. + * @brief Initialization value for the CR3 register. */ uint32_t cr3; } UARTConfig; @@ -325,19 +608,19 @@ typedef struct { */ struct UARTDriver { /** - * @brief Driver state. + * @brief Driver state. */ uartstate_t state; /** - * @brief Transmitter state. + * @brief Transmitter state. */ uarttxstate_t txstate; /** - * @brief Receiver state. + * @brief Receiver state. */ uartrxstate_t rxstate; /** - * @brief Current configuration data. + * @brief Current configuration data. */ const UARTConfig *config; #if defined(UART_DRIVER_EXT_FIELDS) @@ -345,23 +628,27 @@ struct UARTDriver { #endif /* End of the mandatory fields.*/ /** - * @brief Pointer to the USART registers block. + * @brief Pointer to the USART registers block. */ USART_TypeDef *usart; /** - * @brief DMA mode bit mask. + * @brief Clock frequency for the associated USART/UART. + */ + uint32_t clock; + /** + * @brief DMA mode bit mask. */ uint32_t dmamode; /** - * @brief Receive DMA channel. + * @brief Receive DMA channel. */ const stm32_dma_stream_t *dmarx; /** - * @brief Transmit DMA channel. + * @brief Transmit DMA channel. */ const stm32_dma_stream_t *dmatx; /** - * @brief Default receive buffer while into @p UART_RX_IDLE state. + * @brief Default receive buffer while into @p UART_RX_IDLE state. */ volatile uint16_t rxbuf; }; @@ -386,6 +673,26 @@ extern UARTDriver UARTD2; extern UARTDriver UARTD3; #endif +#if STM32_UART_USE_UART4 && !defined(__DOXYGEN__) +extern UARTDriver UARTD4; +#endif + +#if STM32_UART_USE_UART5 && !defined(__DOXYGEN__) +extern UARTDriver UARTD5; +#endif + +#if STM32_UART_USE_USART6 && !defined(__DOXYGEN__) +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/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h index 5b24de152..cce276e1b 100644 --- a/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h +++ b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h @@ -1358,24 +1358,6 @@ */ #define rccResetUSART3() rccResetAPB1(RCC_APB1RSTR_USART3RST) -/** - * @brief Enables the USART6 peripheral clock. - * - * @param[in] lp low power enable flag - * - * @api - */ -#define rccEnableUSART6(lp) rccEnableAPB2(RCC_APB2ENR_USART6EN, lp) - -/** - * @brief Disables the USART6 peripheral clock. - * - * @param[in] lp low power enable flag - * - * @api - */ -#define rccDisableUSART6(lp) rccDisableAPB2(RCC_APB2ENR_USART6EN, lp) - /** * @brief Enables the UART4 peripheral clock. * @note The @p lp parameter is ignored in this family. @@ -1430,12 +1412,84 @@ */ #define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_UART5RST) +/** + * @brief Enables the USART6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART6(lp) rccEnableAPB2(RCC_APB2ENR_USART6EN, lp) + +/** + * @brief Disables the USART6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUSART6(lp) rccDisableAPB2(RCC_APB2ENR_USART6EN, lp) + /** * @brief Resets the USART6 peripheral. * * @api */ #define rccResetUSART6() rccResetAPB2(RCC_APB2RSTR_USART6RST) + +/** + * @brief Enables the UART7 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART7(lp) rccEnableAPB1(RCC_APB1ENR_UART7EN, lp) + +/** + * @brief Disables the UART7 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUART7(lp) rccDisableAPB1(RCC_APB1ENR_UART7EN, lp) + +/** + * @brief Resets the UART7 peripheral. + * + * @api + */ +#define rccResetUART7() rccResetAPB1(RCC_APB1RSTR_UART7RST) + +/** + * @brief Enables the UART8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART8(lp) rccEnableAPB1(RCC_APB1ENR_UART8EN, lp) + +/** + * @brief Disables the UART8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableUART8(lp) rccDisableAPB1(RCC_APB1ENR_UART8EN, lp) + +/** + * @brief Resets the UART8 peripheral. + * + * @api + */ +#define rccResetUART8() rccResetAPB1(RCC_APB1RSTR_UART8RST) /** @} */ /** -- cgit v1.2.3