From f093edb26c679781d52be84ae65c11f4c625013a Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 26 Aug 2026 10:58:29 +0200 Subject: [PATCH] arch/arm/stm32h5: Use common Cortex-M33 USART support Select STM32_HAVE_IP_USART_M33_V3 and drop the family serial, USART header, and low-level console sources. Provide the USART clock and RCC gate definitions for all thirteen ports in stm32_rcc_m33.h and the RX DMA request numbers in the family DMA signal map. Include the family DMA header from stm32.h so the common driver reaches the DMA API. Extend the common Cortex-M33 v3 USART support with the STM32H5 features: USART6, UART7-9, USART10-11, and UART12 ports, the LPUART prescaler for low baud rates, RX DMA through the family-provided request number, wakeup-from-stop CR3 definitions, and per-port descriptors gated by the family peripheral options. Enable the USART FIFO for every Cortex-M33 family. The low-level console uses the per-port kernel clock and RCC gate, which corrects the UART9 and UART12 enable register. The RX DMA callback delivers data only while reception is enabled. The non-BSD break ioctl now uses the send-break request register instead of a CR1 bit this USART IP does not have. Correct the UART12 gates and the RXDMA and console undef lists in the USART driver header. Raise STM32_NUSART to six on the H56x and H57x parts so UART12 fits the device table, add the missing UART9 buffers, write LPUART CR1 only on the USART path, and build device names with snprintf so minors above nine are valid. Keep the termios flow control fields writable so TCSETS compiles with input flow control, let up_putc emit a bare newline since syslog adds the carriage return, and make the unconfigure-on-close options available to every Cortex-M33 family. Signed-off-by: raiden00pl Assisted-by: Claude Code --- arch/arm/include/stm32h5/chip.h | 2 +- arch/arm/src/common/stm32/Kconfig.have | 2 +- .../common/stm32/hardware/stm32_uart_m33_v3.h | 31 +- .../common/stm32/stm32_lowputc_usart_m33_v3.c | 140 + .../src/common/stm32/stm32_serial_m33_v3.c | 1391 +++-- arch/arm/src/common/stm32/stm32_uart_m33_v3.h | 289 +- arch/arm/src/stm32h5/CMakeLists.txt | 5 - arch/arm/src/stm32h5/Kconfig | 1 + arch/arm/src/stm32h5/Make.defs | 6 +- arch/arm/src/stm32h5/hardware/stm32_uart.h | 43 - .../stm32h5/hardware/stm32h56x_dmasigmap.h | 18 +- .../src/stm32h5/hardware/stm32h5xxx_uart.h | 464 -- arch/arm/src/stm32h5/stm32.h | 1 + arch/arm/src/stm32h5/stm32_lowputc.c | 552 -- arch/arm/src/stm32h5/stm32_lowputc.h | 66 - arch/arm/src/stm32h5/stm32_rcc_m33.h | 248 + arch/arm/src/stm32h5/stm32_serial.c | 4481 ----------------- arch/arm/src/stm32h5/stm32_uart.h | 575 --- 18 files changed, 1824 insertions(+), 6491 deletions(-) delete mode 100644 arch/arm/src/stm32h5/hardware/stm32_uart.h delete mode 100644 arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h delete mode 100644 arch/arm/src/stm32h5/stm32_lowputc.c delete mode 100644 arch/arm/src/stm32h5/stm32_lowputc.h delete mode 100644 arch/arm/src/stm32h5/stm32_serial.c delete mode 100644 arch/arm/src/stm32h5/stm32_uart.h diff --git a/arch/arm/include/stm32h5/chip.h b/arch/arm/include/stm32h5/chip.h index 4b51c0b4aa5..211e3a09c63 100644 --- a/arch/arm/include/stm32h5/chip.h +++ b/arch/arm/include/stm32h5/chip.h @@ -79,7 +79,7 @@ #if defined(CONFIG_STM32_STM32H56XXX) || defined(CONFIG_STM32_STM32H57XXX) # define STM32_NUART (6) /* UART 4-5, 7-8, 9, 12 */ -# define STM32_NUSART (5) /* USART 1-3, 6, 10-11 */ +# define STM32_NUSART (6) /* USART 1-3, 6, 10-11 */ #elif defined(CONFIG_STM32_STM32H52XXX) || defined(CONFIG_STM32_STM32H53XXX) # define STM32_NUART (2) /* UART 4-5 */ # define STM32_NUSART (4) /* USART 1-3, 6*/ diff --git a/arch/arm/src/common/stm32/Kconfig.have b/arch/arm/src/common/stm32/Kconfig.have index a873604e66e..88b57a37df9 100644 --- a/arch/arm/src/common/stm32/Kconfig.have +++ b/arch/arm/src/common/stm32/Kconfig.have @@ -1077,7 +1077,7 @@ config STM32_HAVE_USART_WUS config STM32_HAVE_USART_UNCONFIG_ON_CLOSE bool - default y if ARCH_CHIP_STM32H5 + default y if STM32_HAVE_IP_USART_M33_V3 default y if ARCH_CHIP_STM32N6 config STM32_HAVE_USART2 diff --git a/arch/arm/src/common/stm32/hardware/stm32_uart_m33_v3.h b/arch/arm/src/common/stm32/hardware/stm32_uart_m33_v3.h index 6225a68218d..0047a63deca 100644 --- a/arch/arm/src/common/stm32/hardware/stm32_uart_m33_v3.h +++ b/arch/arm/src/common/stm32/hardware/stm32_uart_m33_v3.h @@ -184,10 +184,25 @@ #define USART_CR1_TXFEIE (1 << 30) #define USART_CR1_RXFFIE (1 << 31) #define USART_CR1_RXNEIE_RXFNEIE USART_CR1_RXNEIE -#define USART_CR1_ALLINTS (USART_CR1_IDLEIE | USART_CR1_RXNEIE | USART_CR1_TCIE | \ - USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_CMIE | \ - USART_CR1_RTOIE | USART_CR1_EOBIE | USART_CR1_TXFEIE | \ - USART_CR1_RXFFIE) +#define USART_CR1_ALLINTS (USART_CR1_IDLEIE | \ + USART_CR1_RXNEIE | \ + USART_CR1_TCIE | \ + USART_CR1_TXEIE | \ + USART_CR1_PEIE | \ + USART_CR1_CMIE | \ + USART_CR1_RTOIE | \ + USART_CR1_EOBIE | \ + USART_CR1_TXFEIE | \ + USART_CR1_RXFFIE) + +#define LPUART_CR1_ALLINTS (USART_CR1_IDLEIE | \ + USART_CR1_RXNEIE | \ + USART_CR1_TCIE | \ + USART_CR1_TXEIE | \ + USART_CR1_PEIE | \ + USART_CR1_CMIE | \ + USART_CR1_TXFEIE | \ + USART_CR1_RXFFIE) /* USART control register 2 */ @@ -265,6 +280,12 @@ #define USART_CR3_TXFTCFG(n) ((n) << USART_CR3_TXFTCFG_SHIFT) #define USART_CR3_SCARCNT2_SHIFT USART_CR3_SCARCNT_SHIFT #define USART_CR3_SCARCNT2_MASK USART_CR3_SCARCNT_MASK +#define USART_CR3_WUS_SHIFT (20) +#define USART_CR3_WUS_MASK (3 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_ADDRESS (0 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_START (2 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUFIE (1 << 22) #define USART_CR3_RXFTCFG_1_8 USART_CR3_RXFTCFG(0) #define USART_CR3_RXFTCFG_1_4 USART_CR3_RXFTCFG(1) #define USART_CR3_RXFTCFG_1_2 USART_CR3_RXFTCFG(2) @@ -339,6 +360,7 @@ #define USART_ISR_CMF (1 << 17) #define USART_ISR_SBKF (1 << 18) #define USART_ISR_RWU (1 << 19) +#define USART_ISR_WUF (1 << 20) #define USART_ISR_TEACK (1 << 21) #define USART_ISR_REACK (1 << 22) #define USART_ISR_TXFE (1 << 23) @@ -367,6 +389,7 @@ #define USART_ICR_EOBCF (1 << 12) #define USART_ICR_UDRCF (1 << 13) #define USART_ICR_CMCF (1 << 17) +#define USART_ICR_WUCF (1 << 20) #define USART_ICR_NCF USART_ICR_NECF /* USART receive-data register */ diff --git a/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c b/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c index e24840d7dd6..3a95b5c816b 100644 --- a/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c +++ b/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c @@ -165,6 +165,146 @@ # define STM32_CONSOLE_RS485_DIR_POLARITY true # endif # endif +# elif defined(CONFIG_USART6_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_USART6_BASE +# define STM32_APBCLOCK STM32_USART6_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_USART6_RCC_REG +# define STM32_CONSOLE_APBEN STM32_USART6_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_USART6_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART6_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART6_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART6_2STOP +# define STM32_CONSOLE_TX GPIO_USART6_TX +# define STM32_CONSOLE_RX GPIO_USART6_RX +# ifdef CONFIG_USART6_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART6_RS485_DIR +# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART7_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_UART7_BASE +# define STM32_APBCLOCK STM32_UART7_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_UART7_RCC_REG +# define STM32_CONSOLE_APBEN STM32_UART7_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_UART7_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART7_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART7_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART7_2STOP +# define STM32_CONSOLE_TX GPIO_UART7_TX +# define STM32_CONSOLE_RX GPIO_UART7_RX +# ifdef CONFIG_UART7_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART7_RS485_DIR +# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART8_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_UART8_BASE +# define STM32_APBCLOCK STM32_UART8_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_UART8_RCC_REG +# define STM32_CONSOLE_APBEN STM32_UART8_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_UART8_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART8_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART8_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART8_2STOP +# define STM32_CONSOLE_TX GPIO_UART8_TX +# define STM32_CONSOLE_RX GPIO_UART8_RX +# ifdef CONFIG_UART8_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART8_RS485_DIR +# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART9_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_UART9_BASE +# define STM32_APBCLOCK STM32_UART9_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_UART9_RCC_REG +# define STM32_CONSOLE_APBEN STM32_UART9_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_UART9_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART9_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART9_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART9_2STOP +# define STM32_CONSOLE_TX GPIO_UART9_TX +# define STM32_CONSOLE_RX GPIO_UART9_RX +# ifdef CONFIG_UART9_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART9_RS485_DIR +# if (CONFIG_UART9_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART10_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_USART10_BASE +# define STM32_APBCLOCK STM32_USART10_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_USART10_RCC_REG +# define STM32_CONSOLE_APBEN STM32_USART10_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_USART10_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART10_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART10_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART10_2STOP +# define STM32_CONSOLE_TX GPIO_USART10_TX +# define STM32_CONSOLE_RX GPIO_USART10_RX +# ifdef CONFIG_USART10_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART10_RS485_DIR +# if (CONFIG_USART10_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_USART11_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_USART11_BASE +# define STM32_APBCLOCK STM32_USART11_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_USART11_RCC_REG +# define STM32_CONSOLE_APBEN STM32_USART11_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_USART11_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART11_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART11_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART11_2STOP +# define STM32_CONSOLE_TX GPIO_USART11_TX +# define STM32_CONSOLE_RX GPIO_USART11_RX +# ifdef CONFIG_USART11_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_USART11_RS485_DIR +# if (CONFIG_USART11_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif +# elif defined(CONFIG_UART12_SERIAL_CONSOLE) +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_UART12_BASE +# define STM32_APBCLOCK STM32_UART12_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_UART12_RCC_REG +# define STM32_CONSOLE_APBEN STM32_UART12_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_UART12_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART12_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART12_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART12_2STOP +# define STM32_CONSOLE_TX GPIO_UART12_TX +# define STM32_CONSOLE_RX GPIO_UART12_RX +# ifdef CONFIG_UART12_RS485 +# define STM32_CONSOLE_RS485_DIR GPIO_UART12_RS485_DIR +# if (CONFIG_UART12_RS485_DIR_POLARITY == 0) +# define STM32_CONSOLE_RS485_DIR_POLARITY false +# else +# define STM32_CONSOLE_RS485_DIR_POLARITY true +# endif +# endif # endif /* CR1 settings */ diff --git a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c index 4ebaa17f8ba..7aaa25ab7b6 100644 --- a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c +++ b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -50,11 +51,9 @@ #include #include "chip.h" +#include "stm32.h" #include "stm32_gpio.h" #include "stm32_uart.h" -#ifdef SERIAL_HAVE_DMA -# include "stm32_dma.h" -#endif #include "stm32_rcc.h" #include "arm_internal.h" @@ -64,41 +63,19 @@ /* Some sanity checks *******************************************************/ -/* DMA configuration */ - -/* If DMA is enabled on any USART, then very that other pre-requisites - * have also been selected. - * UART DMA1 DMA2 - * 1 X X - * 2 X - * 3 X - * 4 X - * 5 X - */ - #ifdef SERIAL_HAVE_DMA -/* Verify that DMA has been enabled and the DMA channel has been defined. +/* Verify that DMA has been enabled and the DMA channel has been defined */ + +#if !defined(CONFIG_STM32_DMA1) && !defined(CONFIG_STM32_DMA2) +# error Serial RX DMA requires DMA1 or DMA2 to be enabled +#endif + +/* RS-485 support cannot be enabled when RXDMA is in use due to lack of + * testing. */ -# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) -# if !defined(CONFIG_STM32_DMA1) && !defined(CONFIG_STM32_DMAMUX) -# error STM32 USART2/3 receive DMA requires CONFIG_STM32_DMA1 -# endif -# endif - -# if defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) -# if !defined(CONFIG_STM32_DMA2) && !defined(CONFIG_STM32_DMAMUX) -# error STM32 UART4/5 receive DMA requires CONFIG_STM32_DMA2 -# endif -# endif - -/* Currently RS-485 support cannot be enabled when RXDMA is in use due to - * lack of testing - RS-485 support was developed on STM32F1x - */ - -# if (defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_RS485)) || \ - (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ +# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ @@ -106,46 +83,12 @@ # error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" # endif -/* For the L4, there are alternate DMA channels for USART1. - * Logic in the board.h file make the DMA channel selection by defining - * the following in the board.h file. - */ - -# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) -# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" -# endif - -/* UART2-5 have no alternate channels without DMAMUX */ - -# ifndef CONFIG_STM32_HAVE_DMAMUX -# define DMAMAP_USART2_RX DMACHAN_USART2_RX -# define DMAMAP_USART3_RX DMACHAN_USART3_RX -# define DMAMAP_UART4_RX DMACHAN_UART4_RX -# define DMAMAP_UART5_RX DMACHAN_UART5_RX -# endif - -# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX) -# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)" -# endif - -# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX) -# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)" -# endif - -# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX) -# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)" -# endif - -# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX) -# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)" -# endif - /* The DMA buffer size when using RX DMA to emulate a FIFO. * * When streaming data, the generic serial layer will be called * every time the FIFO receives half this number of bytes. * - * If a supported STM32 has D-cache, the buffer size + * On a device with D-cache, the buffer size * should be an even multiple of ARMV7M_DCACHE_LINESIZE, so that it * can be individually invalidated. */ @@ -157,31 +100,6 @@ # define RXDMA_BUFFER_SIZE ((CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE + 31) & ~31) # endif -/* DMA priority */ - -# ifndef CONFIG_USART_DMAPRIO -# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED -# endif -# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 -# error "Illegal value for CONFIG_USART_DMAPRIO" -# endif - -/* DMA control words */ - -# define SERIAL_DMA_CONTROL_WORD \ - (DMA_CCR_CIRC | \ - DMA_CCR_MINC | \ - DMA_CCR_PSIZE_8BITS | \ - DMA_CCR_MSIZE_8BITS | \ - CONFIG_USART_DMAPRIO) -# ifdef CONFIG_SERIAL_IFLOWCONTROL -# define SERIAL_DMA_IFLOW_CONTROL_WORD \ - (DMA_CCR_MINC | \ - DMA_CCR_PSIZE_8BITS | \ - DMA_CCR_MSIZE_8BITS | \ - CONFIG_USART_DMAPRIO) -# endif - #endif /* Power management definitions */ @@ -190,6 +108,30 @@ # define CONFIG_STM32_PM_SERIAL_ACTIVITY 10 #endif +/* USART Unconfigure bits */ + +#define USART_UNCONFIGURE_RX (1 << 0) +#define USART_UNCONFIGURE_TX (1 << 1) +#define USART_UNCONFIGURE_DIR (1 << 2) + +/* Map a configuration macro, defined to 1 or undefined, to 1 or 0 */ + +#define USART_PLACEHOLDER_1 0, +#define USART_SECOND_ARG(first, val, ...) val +#define USART_IS_JUNK(arg1_or_junk) USART_SECOND_ARG(arg1_or_junk 1, 0) +#define USART_IS_SET_EXPAND(val) USART_IS_JUNK(USART_PLACEHOLDER_##val) +#define USART_IS_SET(option) USART_IS_SET_EXPAND(option) + +/* Unconfigure-on-close mask from the per-port configuration options */ + +#define USART_UNCONFIGURE_ON_CLOSE(port) \ + ((USART_IS_SET(CONFIG_##port##_UNCONFIG_RX_ON_CLOSE) * \ + USART_UNCONFIGURE_RX) | \ + (USART_IS_SET(CONFIG_##port##_UNCONFIG_TX_ON_CLOSE) * \ + USART_UNCONFIGURE_TX) | \ + (USART_IS_SET(CONFIG_##port##_UNCONFIG_DIR_ON_CLOSE) * \ + USART_UNCONFIGURE_DIR)) + /* Keep track if a Break was set * * Note: @@ -216,8 +158,8 @@ struct stm32_serial_s { struct uart_dev_s dev; /* Generic UART device */ - uint16_t ie; /* Saved interrupt mask bits value */ - uint16_t sr; /* Saved status bits */ + uint32_t ie; /* Saved interrupt mask bits value */ + uint32_t sr; /* Saved status bits */ /* Has been initialized and HW is setup. */ @@ -228,7 +170,7 @@ struct stm32_serial_s /* Interrupt mask value stored before suspending for stop mode. */ - uint16_t suspended_ie; + uint32_t suspended_ie; #endif /* If termios are supported, then the following fields may vary at @@ -239,29 +181,24 @@ struct stm32_serial_s uint8_t parity; /* 0=none, 1=odd, 2=even */ uint8_t bits; /* Number of bits (7 or 8) */ bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - bool iflow; /* input flow control (RTS) enabled */ -#endif #ifdef CONFIG_SERIAL_OFLOWCONTROL bool oflow; /* output flow control (CTS) enabled */ #endif + bool iflow; /* input flow control (RTS) enabled */ uint32_t baud; /* Configured baud */ #else const uint8_t parity; /* 0=none, 1=odd, 2=even */ const uint8_t bits; /* Number of bits (7 or 8) */ const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - const bool iflow; /* input flow control (RTS) enabled */ -#endif #ifdef CONFIG_SERIAL_OFLOWCONTROL const bool oflow; /* output flow control (CTS) enabled */ #endif + const bool iflow; /* input flow control (RTS) enabled */ const uint32_t baud; /* Configured baud */ #endif - const uint8_t irq; /* IRQ associated with this USART */ const bool islpuart; /* True: This device is an LPUART */ - const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t apbclock; /* Peripheral kernel clock frequency */ const uint32_t rccreg; /* RCC enable register */ const uint32_t rccen; /* RCC enable bit */ const uint32_t usartbase; /* Base address of USART registers */ @@ -274,10 +211,6 @@ struct stm32_serial_s const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ #endif -#ifdef SERIAL_HAVE_DMA - const unsigned int rxdma_channel; /* DMA channel assigned */ -#endif - /* RX DMA state */ #ifdef SERIAL_HAVE_DMA @@ -287,14 +220,22 @@ struct stm32_serial_s bool rxdmasusp; /* Rx DMA suspended */ #endif uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ - char *const rxfifo; /* Receive DMA buffer */ + uint16_t rxdma_req; /* DMA request number */ + char *const rxfifo; /* Receive DMA buffer */ #endif #ifdef HAVE_RS485 - const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ - const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ + const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ + uint8_t rs485_flags; /* U[S]ART RS-485 flags + * (compatible with struct serial_rs485) + */ #endif + const uint8_t unconfigure; /* Unconfigure pins on close */ spinlock_t lock; +#ifdef CONFIG_STM32_HAVE_USART_WUS + const bool wakefromlowpower; /* Enable wake from low power mode */ + const uint8_t wus; /* USART_CR3_WUS_* selection */ +#endif }; /**************************************************************************** @@ -308,10 +249,9 @@ static int stm32serial_setup(struct uart_dev_s *dev); static void stm32serial_shutdown(struct uart_dev_s *dev); static int stm32serial_attach(struct uart_dev_s *dev); static void stm32serial_detach(struct uart_dev_s *dev); -static int stm32serial_interrupt(int irq, void *context, - void *arg); -static int stm32serial_ioctl(struct file *filep, int cmd, - unsigned long arg); +static int stm32serial_interrupt(int irq, void *context, void *arg); +static int stm32serial_ioctl(struct file *filep, + int cmd, unsigned long arg); #ifndef SERIAL_HAVE_ONLY_DMA static int stm32serial_receive(struct uart_dev_s *dev, unsigned int *status); @@ -320,7 +260,7 @@ static bool stm32serial_rxavailable(struct uart_dev_s *dev); #endif #ifdef CONFIG_SERIAL_IFLOWCONTROL static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, - unsigned int nbuffered, bool upper); + unsigned int nbuffered, bool upper); #endif static void stm32serial_send(struct uart_dev_s *dev, int ch); static void stm32serial_txint(struct uart_dev_s *dev, bool enable); @@ -330,7 +270,7 @@ static bool stm32serial_txready(struct uart_dev_s *dev); static int stm32serial_dmasetup(struct uart_dev_s *dev); static void stm32serial_dmashutdown(struct uart_dev_s *dev); static int stm32serial_dmareceive(struct uart_dev_s *dev, - unsigned int *status); + unsigned int *status); static void stm32serial_dmareenable(struct stm32_serial_s *priv); #ifdef CONFIG_SERIAL_IFLOWCONTROL static bool stm32serial_dmaiflowrestart(struct stm32_serial_s *priv); @@ -339,16 +279,16 @@ static void stm32serial_dmarxint(struct uart_dev_s *dev, bool enable); static bool stm32serial_dmarxavailable(struct uart_dev_s *dev); static void stm32serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, - void *arg); + void *arg); #endif #ifdef CONFIG_PM static void stm32serial_setsuspend(struct uart_dev_s *dev, bool suspend); static void stm32serial_pm_setsuspend(bool suspend); static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); + enum pm_state_e pmstate); static int stm32serial_pmprepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); + enum pm_state_e pmstate); #endif /**************************************************************************** @@ -447,6 +387,62 @@ static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; # endif #endif +#ifdef CONFIG_STM32_USART6_SERIALDRIVER +static char g_usart6rxbuffer[CONFIG_USART6_RXBUFSIZE]; +static char g_usart6txbuffer[CONFIG_USART6_TXBUFSIZE]; +# ifdef CONFIG_USART6_RXDMA +static char g_usart6rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART7_SERIALDRIVER +static char g_uart7rxbuffer[CONFIG_UART7_RXBUFSIZE]; +static char g_uart7txbuffer[CONFIG_UART7_TXBUFSIZE]; +# ifdef CONFIG_UART7_RXDMA +static char g_uart7rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART8_SERIALDRIVER +static char g_uart8rxbuffer[CONFIG_UART8_RXBUFSIZE]; +static char g_uart8txbuffer[CONFIG_UART8_TXBUFSIZE]; +# ifdef CONFIG_UART8_RXDMA +static char g_uart8rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART9_SERIALDRIVER +static char g_uart9rxbuffer[CONFIG_UART9_RXBUFSIZE]; +static char g_uart9txbuffer[CONFIG_UART9_TXBUFSIZE]; +# ifdef CONFIG_UART9_RXDMA +static char g_uart9rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_USART10_SERIALDRIVER +static char g_usart10rxbuffer[CONFIG_USART10_RXBUFSIZE]; +static char g_usart10txbuffer[CONFIG_USART10_TXBUFSIZE]; +# ifdef CONFIG_USART10_RXDMA +static char g_usart10rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_USART11_SERIALDRIVER +static char g_usart11rxbuffer[CONFIG_USART11_RXBUFSIZE]; +static char g_usart11txbuffer[CONFIG_USART11_TXBUFSIZE]; +# ifdef CONFIG_USART11_RXDMA +static char g_usart11rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + +#ifdef CONFIG_STM32_UART12_SERIALDRIVER +static char g_uart12rxbuffer[CONFIG_UART12_RXBUFSIZE]; +static char g_uart12txbuffer[CONFIG_UART12_TXBUFSIZE]; +# ifdef CONFIG_UART12_RXDMA +static char g_uart12rxfifo[RXDMA_BUFFER_SIZE]; +# endif +#endif + /* This describes the state of the STM32 USART1 ports. */ #ifdef CONFIG_STM32_LPUART1_SERIALDRIVER @@ -496,19 +492,20 @@ static struct stm32_serial_s g_lpuart1priv = .rts_gpio = GPIO_LPUART1_RTS, # endif # ifdef CONFIG_LPUART1_RXDMA - .rxdma_channel = DMAMAP_LPUART1_RX, .rxfifo = g_lpuart1rxfifo, + .rxdma_req = STM32_LPUART1_RXDMA_REQ, # endif # ifdef CONFIG_LPUART1_RS485 .rs485_dir_gpio = GPIO_LPUART1_RS485_DIR, # if (CONFIG_LPUART1_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, # else - .rs485_dir_polarity = true, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, # endif # endif .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(LPUART1), }; #endif @@ -559,19 +556,24 @@ static struct stm32_serial_s g_usart1priv = .rts_gpio = GPIO_USART1_RTS, # endif # ifdef CONFIG_USART1_RXDMA - .rxdma_channel = DMAMAP_USART1_RX, .rxfifo = g_usart1rxfifo, + .rxdma_req = STM32_USART1_RXDMA_REQ, # endif # ifdef CONFIG_USART1_RS485 .rs485_dir_gpio = GPIO_USART1_RS485_DIR, # if (CONFIG_USART1_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, # else - .rs485_dir_polarity = true, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, # endif # endif .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(USART1), +# ifdef CONFIG_USART1_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_USART1_WUS, +# endif }; #endif @@ -624,19 +626,24 @@ static struct stm32_serial_s g_usart2priv = .rts_gpio = GPIO_USART2_RTS, # endif # ifdef CONFIG_USART2_RXDMA - .rxdma_channel = DMAMAP_USART2_RX, .rxfifo = g_usart2rxfifo, + .rxdma_req = STM32_USART2_RXDMA_REQ, # endif # ifdef CONFIG_USART2_RS485 .rs485_dir_gpio = GPIO_USART2_RS485_DIR, # if (CONFIG_USART2_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, # else - .rs485_dir_polarity = true, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, # endif # endif .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(USART2), +# ifdef CONFIG_USART2_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_USART2_WUS, +# endif }; #endif @@ -689,19 +696,24 @@ static struct stm32_serial_s g_usart3priv = .rts_gpio = GPIO_USART3_RTS, # endif # ifdef CONFIG_USART3_RXDMA - .rxdma_channel = DMAMAP_USART3_RX, .rxfifo = g_usart3rxfifo, + .rxdma_req = STM32_USART3_RXDMA_REQ, # endif # ifdef CONFIG_USART3_RS485 .rs485_dir_gpio = GPIO_USART3_RS485_DIR, # if (CONFIG_USART3_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, # else - .rs485_dir_polarity = true, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, # endif # endif .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(USART3), +# ifdef CONFIG_USART3_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_USART3_WUS, +# endif }; #endif @@ -754,19 +766,24 @@ static struct stm32_serial_s g_uart4priv = .tx_gpio = GPIO_UART4_TX, .rx_gpio = GPIO_UART4_RX, # ifdef CONFIG_UART4_RXDMA - .rxdma_channel = DMAMAP_UART4_RX, .rxfifo = g_uart4rxfifo, + .rxdma_req = STM32_UART4_RXDMA_REQ, # endif # ifdef CONFIG_UART4_RS485 .rs485_dir_gpio = GPIO_UART4_RS485_DIR, # if (CONFIG_UART4_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, # else - .rs485_dir_polarity = true, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, # endif # endif .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(UART4), +# ifdef CONFIG_UART4_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_UART4_WUS, +# endif }; #endif @@ -819,19 +836,514 @@ static struct stm32_serial_s g_uart5priv = .tx_gpio = GPIO_UART5_TX, .rx_gpio = GPIO_UART5_RX, # ifdef CONFIG_UART5_RXDMA - .rxdma_channel = DMAMAP_UART5_RX, .rxfifo = g_uart5rxfifo, + .rxdma_req = STM32_UART5_RXDMA_REQ, # endif # ifdef CONFIG_UART5_RS485 .rs485_dir_gpio = GPIO_UART5_RS485_DIR, # if (CONFIG_UART5_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, # else - .rs485_dir_polarity = true, + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, # endif # endif .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(UART5), +# ifdef CONFIG_UART5_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_UART5_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 USART6 port. */ + +#ifdef CONFIG_STM32_USART6_SERIALDRIVER +static struct stm32_serial_s g_usart6priv = +{ + .dev = + { +# if CONSOLE_UART == 7 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_USART6_RXBUFSIZE, + .buffer = g_usart6rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART6_TXBUFSIZE, + .buffer = g_usart6txbuffer, + }, +# ifdef CONFIG_USART6_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_usart6priv, + }, + + .irq = STM32_IRQ_USART6, + .islpuart = false, + .parity = CONFIG_USART6_PARITY, + .bits = CONFIG_USART6_BITS, + .stopbits2 = CONFIG_USART6_2STOP, + .baud = CONFIG_USART6_BAUD, + .apbclock = STM32_USART6_FREQUENCY, + .rccreg = STM32_USART6_RCC_REG, + .rccen = STM32_USART6_RCC_EN, + .usartbase = STM32_USART6_BASE, + .tx_gpio = GPIO_USART6_TX, + .rx_gpio = GPIO_USART6_RX, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART6_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART6_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART6_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART6_RTS, +# endif +# ifdef CONFIG_USART6_RXDMA + .rxfifo = g_usart6rxfifo, + .rxdma_req = STM32_USART6_RXDMA_REQ, +# endif + +# ifdef CONFIG_USART6_RS485 + .rs485_dir_gpio = GPIO_USART6_RS485_DIR, +# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(USART6), +# ifdef CONFIG_USART6_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_USART6_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 UART7 port. */ + +#ifdef CONFIG_STM32_UART7_SERIALDRIVER +static struct stm32_serial_s g_uart7priv = +{ + .dev = + { +# if CONSOLE_UART == 8 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_UART7_RXBUFSIZE, + .buffer = g_uart7rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART7_TXBUFSIZE, + .buffer = g_uart7txbuffer, + }, +# ifdef CONFIG_UART7_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_uart7priv, + }, + + .irq = STM32_IRQ_UART7, + .islpuart = false, + .parity = CONFIG_UART7_PARITY, + .bits = CONFIG_UART7_BITS, + .stopbits2 = CONFIG_UART7_2STOP, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART7_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART7_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART7_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART7_RTS, +# endif + .baud = CONFIG_UART7_BAUD, + .apbclock = STM32_UART7_FREQUENCY, + .rccreg = STM32_UART7_RCC_REG, + .rccen = STM32_UART7_RCC_EN, + .usartbase = STM32_UART7_BASE, + .tx_gpio = GPIO_UART7_TX, + .rx_gpio = GPIO_UART7_RX, +# ifdef CONFIG_UART7_RXDMA + .rxfifo = g_uart7rxfifo, + .rxdma_req = STM32_UART7_RXDMA_REQ, +# endif + +# ifdef CONFIG_UART7_RS485 + .rs485_dir_gpio = GPIO_UART7_RS485_DIR, +# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(UART7), +# ifdef CONFIG_UART7_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_UART7_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 UART8 port. */ + +#ifdef CONFIG_STM32_UART8_SERIALDRIVER +static struct stm32_serial_s g_uart8priv = +{ + .dev = + { +# if CONSOLE_UART == 9 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_UART8_RXBUFSIZE, + .buffer = g_uart8rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART8_TXBUFSIZE, + .buffer = g_uart8txbuffer, + }, +# ifdef CONFIG_UART8_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_uart8priv, + }, + + .irq = STM32_IRQ_UART8, + .islpuart = false, + .parity = CONFIG_UART8_PARITY, + .bits = CONFIG_UART8_BITS, + .stopbits2 = CONFIG_UART8_2STOP, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART8_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART8_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART8_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART8_RTS, +# endif + .baud = CONFIG_UART8_BAUD, + .apbclock = STM32_UART8_FREQUENCY, + .rccreg = STM32_UART8_RCC_REG, + .rccen = STM32_UART8_RCC_EN, + .usartbase = STM32_UART8_BASE, + .tx_gpio = GPIO_UART8_TX, + .rx_gpio = GPIO_UART8_RX, +# ifdef CONFIG_UART8_RXDMA + .rxfifo = g_uart8rxfifo, + .rxdma_req = STM32_UART8_RXDMA_REQ, +# endif + +# ifdef CONFIG_UART8_RS485 + .rs485_dir_gpio = GPIO_UART8_RS485_DIR, +# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(UART8), +# ifdef CONFIG_UART8_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_UART8_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 UART9 port. */ + +#ifdef CONFIG_STM32_UART9_SERIALDRIVER +static struct stm32_serial_s g_uart9priv = +{ + .dev = + { +# if CONSOLE_UART == 10 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_UART9_RXBUFSIZE, + .buffer = g_uart9rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART9_TXBUFSIZE, + .buffer = g_uart9txbuffer, + }, +# ifdef CONFIG_UART9_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_uart9priv, + }, + + .irq = STM32_IRQ_UART9, + .islpuart = false, + .parity = CONFIG_UART9_PARITY, + .bits = CONFIG_UART9_BITS, + .stopbits2 = CONFIG_UART9_2STOP, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART9_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART9_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART9_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART9_RTS, +# endif + .baud = CONFIG_UART9_BAUD, + .apbclock = STM32_UART9_FREQUENCY, + .rccreg = STM32_UART9_RCC_REG, + .rccen = STM32_UART9_RCC_EN, + .usartbase = STM32_UART9_BASE, + .tx_gpio = GPIO_UART9_TX, + .rx_gpio = GPIO_UART9_RX, +# ifdef CONFIG_UART9_RXDMA + .rxfifo = g_uart9rxfifo, + .rxdma_req = STM32_UART9_RXDMA_REQ, +# endif + +# ifdef CONFIG_UART9_RS485 + .rs485_dir_gpio = GPIO_UART9_RS485_DIR, +# if (CONFIG_UART9_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(UART9), +# ifdef CONFIG_UART9_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_UART9_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 USART10 port. */ + +#ifdef CONFIG_STM32_USART10_SERIALDRIVER +static struct stm32_serial_s g_usart10priv = +{ + .dev = + { +# if CONSOLE_UART == 11 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_USART10_RXBUFSIZE, + .buffer = g_usart10rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART10_TXBUFSIZE, + .buffer = g_usart10txbuffer, + }, +# ifdef CONFIG_USART10_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_usart10priv, + }, + + .irq = STM32_IRQ_USART10, + .islpuart = false, + .parity = CONFIG_USART10_PARITY, + .bits = CONFIG_USART10_BITS, + .stopbits2 = CONFIG_USART10_2STOP, + .baud = CONFIG_USART10_BAUD, + .apbclock = STM32_USART10_FREQUENCY, + .rccreg = STM32_USART10_RCC_REG, + .rccen = STM32_USART10_RCC_EN, + .usartbase = STM32_USART10_BASE, + .tx_gpio = GPIO_USART10_TX, + .rx_gpio = GPIO_USART10_RX, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART10_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART10_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART10_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART10_RTS, +# endif +# ifdef CONFIG_USART10_RXDMA + .rxfifo = g_usart10rxfifo, + .rxdma_req = STM32_USART10_RXDMA_REQ, +# endif + +# ifdef CONFIG_USART10_RS485 + .rs485_dir_gpio = GPIO_USART10_RS485_DIR, +# if (CONFIG_USART10_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(USART10), +# ifdef CONFIG_USART10_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_USART10_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 USART11 port. */ + +#ifdef CONFIG_STM32_USART11_SERIALDRIVER +static struct stm32_serial_s g_usart11priv = +{ + .dev = + { +# if CONSOLE_UART == 12 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_USART11_RXBUFSIZE, + .buffer = g_usart11rxbuffer, + }, + .xmit = + { + .size = CONFIG_USART11_TXBUFSIZE, + .buffer = g_usart11txbuffer, + }, +# ifdef CONFIG_USART11_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_usart11priv, + }, + + .irq = STM32_IRQ_USART11, + .islpuart = false, + .parity = CONFIG_USART11_PARITY, + .bits = CONFIG_USART11_BITS, + .stopbits2 = CONFIG_USART11_2STOP, + .baud = CONFIG_USART11_BAUD, + .apbclock = STM32_USART11_FREQUENCY, + .rccreg = STM32_USART11_RCC_REG, + .rccen = STM32_USART11_RCC_EN, + .usartbase = STM32_USART11_BASE, + .tx_gpio = GPIO_USART11_TX, + .rx_gpio = GPIO_USART11_RX, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART11_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_USART11_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART11_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_USART11_RTS, +# endif +# ifdef CONFIG_USART11_RXDMA + .rxfifo = g_usart11rxfifo, + .rxdma_req = STM32_USART11_RXDMA_REQ, +# endif + +# ifdef CONFIG_USART11_RS485 + .rs485_dir_gpio = GPIO_USART11_RS485_DIR, +# if (CONFIG_USART11_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(USART11), +# ifdef CONFIG_USART11_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_USART11_WUS, +# endif +}; +#endif + +/* This describes the state of the STM32 UART12 port. */ + +#ifdef CONFIG_STM32_UART12_SERIALDRIVER +static struct stm32_serial_s g_uart12priv = +{ + .dev = + { +# if CONSOLE_UART == 13 + .isconsole = true, +# endif + .recv = + { + .size = CONFIG_UART12_RXBUFSIZE, + .buffer = g_uart12rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART12_TXBUFSIZE, + .buffer = g_uart12txbuffer, + }, +# ifdef CONFIG_UART12_RXDMA + .ops = &g_uart_dma_ops, +# else + .ops = &g_uart_ops, +# endif + .priv = &g_uart12priv, + }, + + .irq = STM32_IRQ_UART12, + .islpuart = false, + .parity = CONFIG_UART12_PARITY, + .bits = CONFIG_UART12_BITS, + .stopbits2 = CONFIG_UART12_2STOP, +# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART12_OFLOWCONTROL) + .oflow = true, + .cts_gpio = GPIO_UART12_CTS, +# endif +# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART12_IFLOWCONTROL) + .iflow = true, + .rts_gpio = GPIO_UART12_RTS, +# endif + .baud = CONFIG_UART12_BAUD, + .apbclock = STM32_UART12_FREQUENCY, + .rccreg = STM32_UART12_RCC_REG, + .rccen = STM32_UART12_RCC_EN, + .usartbase = STM32_UART12_BASE, + .tx_gpio = GPIO_UART12_TX, + .rx_gpio = GPIO_UART12_RX, +# ifdef CONFIG_UART12_RXDMA + .rxfifo = g_uart12rxfifo, + .rxdma_req = STM32_UART12_RXDMA_REQ, +# endif + +# ifdef CONFIG_UART12_RS485 + .rs485_dir_gpio = GPIO_UART12_RS485_DIR, +# if (CONFIG_UART12_RS485_DIR_POLARITY == 0) + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, +# else + .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, +# endif +# endif + .lock = SP_UNLOCKED, + .unconfigure = USART_UNCONFIGURE_ON_CLOSE(UART12), +# ifdef CONFIG_UART12_WAKE_FROM_LOW_POWER + .wakefromlowpower = true, + .wus = CONFIG_UART12_WUS, +# endif }; #endif @@ -858,6 +1370,27 @@ static struct stm32_serial_s * const #ifdef CONFIG_STM32_UART5_SERIALDRIVER [5] = &g_uart5priv, #endif +#ifdef CONFIG_STM32_USART6_SERIALDRIVER + [6] = &g_usart6priv, +#endif +#ifdef CONFIG_STM32_UART7_SERIALDRIVER + [7] = &g_uart7priv, +#endif +#ifdef CONFIG_STM32_UART8_SERIALDRIVER + [8] = &g_uart8priv, +#endif +#ifdef CONFIG_STM32_UART9_SERIALDRIVER + [9] = &g_uart9priv, +#endif +#ifdef CONFIG_STM32_USART10_SERIALDRIVER + [10] = &g_usart10priv, +#endif +#ifdef CONFIG_STM32_USART11_SERIALDRIVER + [11] = &g_usart11priv, +#endif +#ifdef CONFIG_STM32_UART12_SERIALDRIVER + [12] = &g_uart12priv, +#endif }; #ifdef CONFIG_PM @@ -895,7 +1428,7 @@ uint32_t stm32serial_getreg(struct stm32_serial_s *priv, int offset) static inline void stm32serial_putreg(struct stm32_serial_s *priv, - int offset, uint32_t value) + int offset, uint32_t value) { putreg32(value, priv->usartbase + offset); } @@ -906,7 +1439,7 @@ void stm32serial_putreg(struct stm32_serial_s *priv, static inline void stm32serial_setusartint(struct stm32_serial_s *priv, - uint16_t ie) + uint32_t ie) { uint32_t cr; @@ -934,15 +1467,15 @@ void stm32serial_setusartint(struct stm32_serial_s *priv, ****************************************************************************/ static void stm32serial_restoreusartint(struct stm32_serial_s *priv, - uint16_t ie) + uint32_t ie) { irqstate_t flags; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&priv->lock); stm32serial_setusartint(priv, ie); - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** @@ -950,7 +1483,7 @@ static void stm32serial_restoreusartint(struct stm32_serial_s *priv, ****************************************************************************/ static void stm32serial_disableusartint(struct stm32_serial_s *priv, - uint16_t *ie) + uint32_t *ie) { irqstate_t flags; @@ -1034,24 +1567,102 @@ static void stm32serial_setformat(struct uart_dev_s *dev) struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; uint32_t regval; + uint32_t brr; + uint32_t cr1; /* This first implementation is for U[S]ARTs that support oversampling - * by 8 in additional to the standard oversampling by 16. + * by 8 in additional to the standard oversampling by 16. The LPUART + * has no oversampling selection and must leave CR1 unchanged here. */ - uint32_t usartdiv8; - uint32_t cr1; - uint32_t brr; - if (priv->islpuart) { - /* LPUART BRR = 256 * fCK / baud */ + /* LPUART BRR (19:00) = (256*apbclock_hz/baud_rate) */ - brr = (((uint64_t)priv->apbclock << 8) + - (priv->baud >> 1)) / priv->baud; + uint32_t apbclock_whole = priv->apbclock; + uint32_t clock_baud_ratio = apbclock_whole / priv->baud; + uint32_t presc_reg = 0x0; + + /* LPUART PRESC (3:0) + * Divide the apbclock if necessary for low baud rates + * 3 * baud_rate <= apbclock_whole <= 4096 * baud_rate + */ + + if (clock_baud_ratio <= 4096) + { + presc_reg = 0x0; + } + else if (clock_baud_ratio > 4096 && clock_baud_ratio <= 8192) + { + presc_reg = 0x1; + apbclock_whole >>= 1; + } + else if (clock_baud_ratio > 8192 && clock_baud_ratio <= 16384) + { + presc_reg = 0x2; + apbclock_whole >>= 2; + } + else if (clock_baud_ratio > 16384 && clock_baud_ratio <= 24576) + { + presc_reg = 0x3; + apbclock_whole /= 6; + } + else if (clock_baud_ratio > 24576 && clock_baud_ratio <= 32768) + { + presc_reg = 0x4; + apbclock_whole >>= 3; + } + else if (clock_baud_ratio > 32768 && clock_baud_ratio <= 40960) + { + presc_reg = 0x5; + apbclock_whole /= 10; + } + else if (clock_baud_ratio > 40960 && clock_baud_ratio <= 49152) + { + presc_reg = 0x6; + apbclock_whole /= 12; + } + else if (clock_baud_ratio > 32768 && clock_baud_ratio <= 65536) + { + presc_reg = 0x7; + apbclock_whole >>= 4; + } + else if (clock_baud_ratio > 65536 && clock_baud_ratio <= 131072) + { + presc_reg = 0x8; + apbclock_whole >>= 5; + } + else if (clock_baud_ratio > 131072 && clock_baud_ratio <= 262144) + { + presc_reg = 0x9; + apbclock_whole >>= 6; + } + else if (clock_baud_ratio > 262144 && clock_baud_ratio <= 524288) + { + presc_reg = 0xa; + apbclock_whole >>= 7; + } + else + { + presc_reg = 0xb; + apbclock_whole >>= 8; + } + + /* Write the PRESC register */ + + stm32serial_putreg(priv, STM32_USART_PRESC_OFFSET, presc_reg); + + /* Set the LPUART BRR value after setting Prescaler + * BRR = ( (256 * apbclock_whole) + baud_rate / 2 ) / baud_rate + */ + + brr = (((uint64_t)apbclock_whole << 8) + (priv->baud >> 1)) / \ + priv->baud; } else { + uint32_t usartdiv8; + /* In case of oversampling by 8, the equation is: * * baud = 2 * fCK / usartdiv8 @@ -1356,7 +1967,7 @@ static void stm32serial_setapbclock(struct uart_dev_s *dev, bool on) struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; - /* Enable/disable APB 1/2 clock for USART */ + /* Enable/disable APB clock for the USART */ if (on) { @@ -1427,10 +2038,11 @@ static int stm32serial_setup(struct uart_dev_s *dev) #endif #ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) + if ((priv->rs485_flags & SER_RS485_ENABLED) != 0) { stm32_configgpio(priv->rs485_dir_gpio); - stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + stm32_gpiowrite(priv->rs485_dir_gpio, + (bool) (priv->rs485_flags & SER_RS485_RTS_AFTER_SEND)); } #endif @@ -1439,8 +2051,15 @@ static int stm32serial_setup(struct uart_dev_s *dev) /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ regval = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); - regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | - USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + if (priv->islpuart == true) + { + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN); + } + else + { + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); + } /* Configure STOP bits */ @@ -1453,10 +2072,22 @@ static int stm32serial_setup(struct uart_dev_s *dev) /* Configure CR1 */ - /* Clear TE, REm and all interrupt enable bits */ + /* Clear UE, TE, RE, and all interrupt enable bits */ regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); + +#ifdef CONFIG_STM32_LPUART1 + if (priv->islpuart == true) + { + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + LPUART_CR1_ALLINTS); + } + else +#endif + { + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + USART_CR1_ALLINTS); + } stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); @@ -1468,6 +2099,15 @@ static int stm32serial_setup(struct uart_dev_s *dev) regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_EIE); +#ifdef CONFIG_STM32_HAVE_USART_WUS + regval &= ~(USART_CR3_WUFIE | USART_CR3_WUS_MASK); + if (priv->wakefromlowpower) + { + regval |= USART_CR3_WUFIE; + regval |= (priv->wus << USART_CR3_WUS_SHIFT); + } +#endif + stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); /* Configure the USART line format and speed. */ @@ -1477,7 +2117,8 @@ static int stm32serial_setup(struct uart_dev_s *dev) /* Enable Rx, Tx, and the USART */ regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + USART_CR1_FIFOEN); stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); #endif /* CONFIG_SUPPRESS_UART_CONFIG */ @@ -1493,69 +2134,88 @@ static int stm32serial_setup(struct uart_dev_s *dev) return OK; } +/**************************************************************************** + * Name: serial_rxdmacfg + * + * Description: + * Generate the required DMA configuration structure for oneshot mode based + * on the serial configuration. + * + * Input Parameters: + * priv - serial instance structure + * cfg - DMA configuration structure + * circular - 0 = oneshot, 1 = circular + * + * Returned Value: + * None + ****************************************************************************/ + + #ifdef SERIAL_HAVE_DMA +static void serial_rxdmacfg(struct stm32_serial_s *priv, + struct stm32_gpdma_cfg_s *cfg) +{ + cfg->src_addr = priv->usartbase + STM32_USART_RDR_OFFSET; + cfg->dest_addr = (uint32_t)priv->rxfifo; + + cfg->request = priv->rxdma_req; + + cfg->priority = GPMDACFG_PRIO_LH; + + cfg->mode = GPDMACFG_MODE_CIRC; + + cfg->ntransfers = RXDMA_BUFFER_SIZE; + + /* Write SDW and DDW to 0 for 8-bit beats */ + + cfg->tr1 = GPDMA_CXTR1_DINC; /* dest-inc, source fixed */ +} +#endif + /**************************************************************************** * Name: stm32serial_dmasetup * * Description: - * Configure the USART baud, bits, parity, etc. This method is called the - * first time that the serial port is opened. + * Configure and start circular RX DMA for USART: + * - Allocate a GPDMA channel + * - Set up source (USART RDR), destination (RX buffer), REQSEL, + * circular mode + * - Program DMA and reset read index + * - Enable USART CR3.DMAR + * - Start DMA with half- and full-transfer callbacks * + * Returned Value: + * OK on success; negative errno on failure. ****************************************************************************/ #ifdef SERIAL_HAVE_DMA static int stm32serial_dmasetup(struct uart_dev_s *dev) { - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - int result; - uint32_t regval; - - /* Do the basic UART setup first, unless we are the console */ + struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; + struct stm32_gpdma_cfg_s dmacfg; + uint32_t regval; + int ret; if (!dev->isconsole) { - result = stm32serial_setup(dev); - if (result != OK) + ret = stm32serial_setup(dev); + if (ret != OK) { - return result; + return ret; } } - /* Acquire the DMA channel. This should always succeed. */ - - priv->rxdma = stm32_dmachannel(priv->rxdma_channel); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) + priv->rxdma = stm32_dmachannel(GPDMA_TTYPE_P2M); + if (!priv->rxdma) { - /* Configure for non-circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_IFLOW_CONTROL_WORD); - } - else -#endif - { - /* Configure for circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_CONTROL_WORD); + return -EBUSY; } - /* Reset our DMA shadow pointer to match the address just - * programmed above. - */ + serial_rxdmacfg(priv, &dmacfg); + + stm32_dmasetup(priv->rxdma, &dmacfg); priv->rxdmanext = 0; - /* Enable receive DMA for the UART */ - regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); regval |= USART_CR3_DMAR; stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); @@ -1569,7 +2229,7 @@ static int stm32serial_dmasetup(struct uart_dev_s *dev) */ stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, - (void *)priv, false); + (void *)priv, false); } else #endif @@ -1580,7 +2240,7 @@ static int stm32serial_dmasetup(struct uart_dev_s *dev) */ stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, - (void *)priv, true); + (void *)priv, true); } return OK; @@ -1628,12 +2288,12 @@ static void stm32serial_shutdown(struct uart_dev_s *dev) * then this may need to be a configuration option. */ - if (priv->tx_gpio != 0) + if ((priv->unconfigure & USART_UNCONFIGURE_TX) && (priv->tx_gpio != 0)) { stm32_unconfiggpio(priv->tx_gpio); } - if (priv->rx_gpio != 0) + if ((priv->unconfigure & USART_UNCONFIGURE_RX) && (priv->rx_gpio != 0)) { stm32_unconfiggpio(priv->rx_gpio); } @@ -1653,7 +2313,8 @@ static void stm32serial_shutdown(struct uart_dev_s *dev) #endif #ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) + if ((priv->rs485_dir_gpio != 0) && + (priv->unconfigure & USART_UNCONFIGURE_DIR)) { stm32_unconfiggpio(priv->rs485_dir_gpio); } @@ -1683,6 +2344,8 @@ static void stm32serial_dmashutdown(struct uart_dev_s *dev) stm32_dmastop(priv->rxdma); + priv->rxenable = false; + /* Release the DMA channel */ stm32_dmafree(priv->rxdma); @@ -1821,11 +2484,22 @@ static int stm32serial_interrupt(int irq, void *context, void *arg) (priv->ie & USART_CR1_TCIE) != 0 && (priv->ie & USART_CR1_TXEIE) == 0) { - stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); + stm32_gpiowrite(priv->rs485_dir_gpio, + (bool) (priv->rs485_flags & + SER_RS485_RTS_AFTER_SEND)); stm32serial_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); } #endif +#ifdef CONFIG_STM32_HAVE_USART_WUS + /* Wake up from low power mode interrupt */ + + if ((priv->sr & USART_ISR_WUF) != 0) + { + stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, USART_ICR_WUCF); + } +#endif + /* Handle incoming, receive bytes. */ if ((priv->sr & USART_ISR_RXNE) != 0 && @@ -1871,6 +2545,110 @@ static int stm32serial_interrupt(int irq, void *context, void *arg) return OK; } +/**************************************************************************** + * Name: stm32serial_set_rs485_mode + * + * Description: + * Handle mode set ioctl (TIOCSRS485) to enable + * and disable RS-485 mode. This is part of the serial ioctl logic. + * + * + ****************************************************************************/ + +#ifdef HAVE_RS485 +static inline int stm32serial_set_rs485_mode(struct stm32_serial_s *priv, + const struct serial_rs485 *mode) +{ + irqstate_t flags; + + DEBUGASSERT(priv && mode); + if (priv->rs485_dir_gpio == 0) + { + /* Can't configure RS485 dir pin if pin is not defined */ + + return -ENOTTY; + } + + flags = enter_critical_section(); + priv->sr = stm32serial_getreg(priv, STM32_USART_ISR_OFFSET); + + priv->rs485_flags = mode->flags & + (SER_RS485_ENABLED | + SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND | + SER_RS485_RX_DURING_TX); +/* Cases: + * Enabling, serial transfer currently in progress: + * Set the pin to the transfer in progress state and let the interrupt take + * care of it + * Enabling, no serial transfer currently in progress: + * Set the pin to the no transfer in progress state. + */ + + if (mode->flags & SER_RS485_ENABLED) + { + stm32_configgpio(priv->rs485_dir_gpio); + if ((priv->sr & USART_ISR_TC) != 0) + { + /* Transmission is complete, set to "after send' state */ + + stm32_gpiowrite(priv->rs485_dir_gpio, (bool) (priv->rs485_flags & + SER_RS485_RTS_AFTER_SEND)); + } + else + { + /* Transmission is currently in progress, set to "on send" state */ + + stm32_gpiowrite(priv->rs485_dir_gpio, (bool) (priv->rs485_flags & + SER_RS485_RTS_ON_SEND)); + } + } + else + { + if (priv->unconfigure & USART_UNCONFIGURE_DIR) + { + stm32_unconfiggpio(priv->rs485_dir_gpio); + } + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32serial_get_rs485_mode + * + * Description: + * Handle RS485 mode get ioctl (TIOCGRS485) to get the + * current RS-485 mode. + * + ****************************************************************************/ + +#ifdef HAVE_RS485 +static inline int stm32serial_get_rs485_mode(struct stm32_serial_s *priv, + struct serial_rs485 *mode) +{ + irqstate_t flags; + + DEBUGASSERT(priv && mode); + flags = enter_critical_section(); + + /* Assume disabled */ + + memset(mode, 0, sizeof(struct serial_rs485)); + + mode->flags = priv->rs485_flags & + (SER_RS485_ENABLED | + SER_RS485_RTS_ON_SEND | + SER_RS485_RTS_AFTER_SEND | + SER_RS485_RX_DURING_TX); + + leave_critical_section(flags); + return OK; +} +#endif + /**************************************************************************** * Name: stm32serial_ioctl * @@ -1880,7 +2658,7 @@ static int stm32serial_interrupt(int irq, void *context, void *arg) ****************************************************************************/ static int stm32serial_ioctl(struct file *filep, int cmd, - unsigned long arg) + unsigned long arg) { struct inode *inode = filep->f_inode; struct uart_dev_s *dev = inode->i_private; @@ -1915,7 +2693,6 @@ static int stm32serial_ioctl(struct file *filep, int cmd, #ifdef CONFIG_STM32_USART_SINGLEWIRE case TIOCSSINGLEWIRE: { - uint32_t cr; uint32_t cr1; uint32_t cr1_ue; irqstate_t flags; @@ -1936,7 +2713,7 @@ static int stm32serial_ioctl(struct file *filep, int cmd, * half-duplex mode. */ - cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); + uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { @@ -1995,7 +2772,6 @@ static int stm32serial_ioctl(struct file *filep, int cmd, #ifdef CONFIG_STM32_USART_INVERT case TIOCSINVERT: { - uint32_t cr; uint32_t cr1; uint32_t cr1_ue; irqstate_t flags; @@ -2014,7 +2790,7 @@ static int stm32serial_ioctl(struct file *filep, int cmd, /* Enable/disable signal inversion. */ - cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); + uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); if (arg & SER_INVERT_ENABLED_RX) { @@ -2047,7 +2823,6 @@ static int stm32serial_ioctl(struct file *filep, int cmd, #ifdef CONFIG_STM32_USART_SWAP case TIOCSSWAP: { - uint32_t cr; uint32_t cr1; uint32_t cr1_ue; irqstate_t flags; @@ -2066,7 +2841,7 @@ static int stm32serial_ioctl(struct file *filep, int cmd, /* Enable/disable Swap mode. */ - cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); + uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); if (arg == SER_SWAP_ENABLED) { @@ -2200,9 +2975,11 @@ static int stm32serial_ioctl(struct file *filep, int cmd, if (priv->tx_gpio != 0) { - uint32_t tx_break = GPIO_OUTPUT | - (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio); + uint32_t tx_break; + tx_break = GPIO_OUTPUT | + (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & + priv->tx_gpio); stm32_configgpio(tx_break); } @@ -2233,15 +3010,36 @@ static int stm32serial_ioctl(struct file *filep, int cmd, } break; # else - case TIOCSBRK: /* No BSD compatibility: Turn break on for M bit times */ - stm32serial_putreg(priv, STM32_USART_RQR_OFFSET, USART_RQR_SBKRQ); + case TIOCSBRK: /* No BSD compatibility: Send break for M bit times */ + { + irqstate_t flags; + + flags = enter_critical_section(); + stm32serial_putreg(priv, STM32_USART_RQR_OFFSET, + USART_RQR_SBKRQ); + leave_critical_section(flags); + } break; - case TIOCCBRK: /* No BSD compatibility: HW cannot stop the break */ + case TIOCCBRK: /* No BSD compatibility: The break is self-clearing */ break; # endif #endif +#ifdef HAVE_RS485 + case TIOCSRS485: /* Set RS485 mode, arg: pointer to struct serial_rs485 */ + { + ret = stm32serial_set_rs485_mode( + priv, (const struct serial_rs485 *)((uintptr_t)arg)); + } + break; + case TIOCGRS485: /* Get RS485 mode, arg: pointer to struct serial_rs485 */ + { + ret = stm32serial_get_rs485_mode( + priv, (struct serial_rs485 *)((uintptr_t)arg)); + } + break; +#endif default: ret = -ENOTTY; break; @@ -2262,7 +3060,7 @@ static int stm32serial_ioctl(struct file *filep, int cmd, #ifndef SERIAL_HAVE_ONLY_DMA static int stm32serial_receive(struct uart_dev_s *dev, - unsigned int *status) + unsigned int *status) { struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; @@ -2297,7 +3095,7 @@ static void stm32serial_rxint(struct uart_dev_s *dev, bool enable) struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; irqstate_t flags; - uint16_t ie; + uint32_t ie; /* USART receive interrupts: * @@ -2387,7 +3185,7 @@ static bool stm32serial_rxavailable(struct uart_dev_s *dev) #ifdef CONFIG_SERIAL_IFLOWCONTROL static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, - unsigned int nbuffered, bool upper) + unsigned int nbuffered, bool upper) { struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; @@ -2463,43 +3261,64 @@ static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, * Name: stm32serial_dmareceive * * Description: - * Called (usually) from the interrupt level to receive one - * character from the USART. Error bits associated with the - * receipt are provided in the return 'status'. + * Retrieve one character from the RX FIFO filled by circular DMA. Also + * report any USART error flags in *status. * ****************************************************************************/ #ifdef SERIAL_HAVE_DMA static int stm32serial_dmareceive(struct uart_dev_s *dev, - unsigned int *status) + unsigned int *status) { struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; - int c = 0; + unsigned int next; + int ch = -1; + uint32_t sr; - if (stm32serial_dmanextrx(priv) != priv->rxdmanext) + /* 1) Capture USART error flags */ + + sr = getreg32(priv->usartbase + STM32_USART_ISR_OFFSET); + *status = sr & (USART_ISR_ORE | USART_ISR_NF | + USART_ISR_FE | USART_ISR_PE); + + /* 2) Where will DMA write the next byte? */ + + next = stm32serial_dmanextrx(priv); + + /* 3) Pull one byte if available */ + + if (next != priv->rxdmanext) { - c = priv->rxfifo[priv->rxdmanext]; + ch = priv->rxfifo[priv->rxdmanext++]; - priv->rxdmanext++; - if (priv->rxdmanext == RXDMA_BUFFER_SIZE) + /* 4) End-of-buffer wrap or flow-control pause */ + + if (priv->rxdmanext >= RXDMA_BUFFER_SIZE) { #ifdef CONFIG_SERIAL_IFLOWCONTROL if (priv->iflow) { - /* RX DMA buffer full. RX paused, RTS line pulled up to prevent - * more input data from other end. - */ + /* Pause DMA callbacks */ + + stm32serial_dmarxint(&priv->dev, false); + + /* Assert RTS to halt sender */ + + (void)stm32serial_rxflowcontrol(&priv->dev, + RXDMA_BUFFER_SIZE, true); } else #endif { + /* Simply wrap to buffer start */ + priv->rxdmanext = 0; } } } - return c; + return ch; } #endif @@ -2514,28 +3333,10 @@ static int stm32serial_dmareceive(struct uart_dev_s *dev, #if defined(SERIAL_HAVE_DMA) static void stm32serial_dmareenable(struct stm32_serial_s *priv) { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Configure for non-circular DMA reception into the RX FIFO */ + struct stm32_gpdma_cfg_s dmacfg; - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_IFLOW_CONTROL_WORD); - } - else -#endif - { - /* Configure for circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_CONTROL_WORD); - } + serial_rxdmacfg(priv, &dmacfg); + stm32_dmasetup(priv->rxdma, &dmacfg); /* Reset our DMA shadow pointer to match the address just * programmed above. @@ -2694,9 +3495,10 @@ static void stm32serial_send(struct uart_dev_s *dev, int ch) (struct stm32_serial_s *)dev->priv; #ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) + if ((priv->rs485_flags & SER_RS485_ENABLED) != 0) { - stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); + stm32_gpiowrite(priv->rs485_dir_gpio, (bool) (priv->rs485_flags & + SER_RS485_RTS_ON_SEND)); } #endif @@ -2732,14 +3534,14 @@ static void stm32serial_txint(struct uart_dev_s *dev, bool enable) /* Set to receive an interrupt when the TX data register is empty */ #ifndef CONFIG_SUPPRESS_SERIAL_INTS - uint16_t ie = priv->ie | USART_CR1_TXEIE; + uint32_t ie = priv->ie | USART_CR1_TXEIE; /* If RS-485 is supported on this U[S]ART, then also enable the * transmission complete interrupt. */ # ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) + if ((priv->rs485_flags & SER_RS485_ENABLED) != 0) { ie |= USART_CR1_TCIE; } @@ -2793,47 +3595,57 @@ static bool stm32serial_txready(struct uart_dev_s *dev) * Name: stm32serial_dmarxcallback * * Description: - * This function checks the current DMA state and calls the generic - * serial stack when bytes appear to be available. + * DMA callback for USART RX. Called on half and full-transfer + * events. Reads and clears the GPDMA status flags, notifies the NuttX + * serial core of newly arrived bytes, signals end-of-buffer when a + * full transfer completes, handles RTS flow control restart, and + * clears any lingering UART error flags to keep RX-DMA running. + * + * Input Parameters: + * handle - DMA channel handle returned by stm32_dmachannel() + * status - Raw status byte passed by the DMA ISR (ignored here) + * arg - Pointer to the STM32 serial driver state + * (struct stm32_serial_s) + * + * Returned Value: + * None * ****************************************************************************/ #ifdef SERIAL_HAVE_DMA -static void stm32serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, +static void stm32serial_dmarxcallback(DMA_HANDLE handle, + uint8_t status, void *arg) { - struct stm32_serial_s *priv = (struct stm32_serial_s *)arg; + struct stm32_serial_s *priv = arg; if (priv->rxenable && stm32serial_dmarxavailable(&priv->dev)) { uart_recvchars(&priv->dev); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Re-enable RX DMA. */ - - stm32serial_dmaiflowrestart(priv); - } -#endif } - /* Get the masked USART status word to check and clear error flags. - * - * When wake-up from low power mode was not fast enough, UART is resumed - * too late and sometimes exactly when character was coming over UART, - * resulting to frame error. - * If error flag is not cleared, Rx DMA will be stuck. Clearing errors - * will release Rx DMA. + /* If it really was a full-buffer event, signal "done" so the + * serial core can rearm/restart the DMA behind the scenes: */ - priv->sr = stm32serial_getreg(priv, STM32_USART_ISR_OFFSET); +#ifdef CONFIG_SERIAL_IFLOWCONTROL + /* If you had paused the DMA on RTS flow control, restart it now */ - if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) != 0) + if (priv->iflow) + { + stm32serial_dmaiflowrestart(priv); + } +#endif + + /* Clear any USART framing/overrun errors so RX-DMA + * doesn't get stuck waiting for the UART to clear them. + */ + + priv->sr = getreg32(priv->usartbase + STM32_USART_ISR_OFFSET); + if (priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) { stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, - (USART_ICR_NCF | USART_ICR_ORECF | - USART_ICR_FECF)); + USART_ICR_ORECF | USART_ICR_NCF | USART_ICR_FECF); } } #endif @@ -2862,7 +3674,7 @@ static void stm32serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, #ifdef CONFIG_PM static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) + enum pm_state_e pmstate) { switch (pmstate) { @@ -2940,7 +3752,7 @@ static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, #ifdef CONFIG_PM static int stm32serial_pmprepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) + enum pm_state_e pmstate) { int n; @@ -3104,8 +3916,6 @@ void arm_serialinit(void) /* Register all remaining USARTs */ - strlcpy(devname, "/dev/ttySx", sizeof(devname)); - for (i = 0; i < STM32_NLPUART + STM32_NUSART + STM32_NUART; i++) { /* Don't create a device for non-configured ports. */ @@ -3126,7 +3936,7 @@ void arm_serialinit(void) /* Register USARTs as devices in increasing order */ - devname[9] = '0' + minor++; + snprintf(devname, sizeof(devname), "/dev/ttyS%u", minor++); uart_register(devname, &g_uart_devs[i]->dev); } #endif /* HAVE UART */ @@ -3208,9 +4018,10 @@ void up_putc(int ch) { #if CONSOLE_UART > 0 struct stm32_serial_s *priv = g_uart_devs[CONSOLE_UART - 1]; - uint16_t ie; + uint32_t ie; stm32serial_disableusartint(priv, &ie); + arm_lowputc(ch); stm32serial_restoreusartint(priv, ie); #endif diff --git a/arch/arm/src/common/stm32/stm32_uart_m33_v3.h b/arch/arm/src/common/stm32/stm32_uart_m33_v3.h index f9a0d136848..eeacf4d97fe 100644 --- a/arch/arm/src/common/stm32/stm32_uart_m33_v3.h +++ b/arch/arm/src/common/stm32/stm32_uart_m33_v3.h @@ -42,6 +42,27 @@ * device. */ +#if !defined(CONFIG_STM32_HAVE_UART12) +# undef CONFIG_STM32_UART12 +#endif +#if !defined(CONFIG_STM32_HAVE_USART11) +# undef CONFIG_STM32_USART11 +#endif +#if !defined(CONFIG_STM32_HAVE_USART10) +# undef CONFIG_STM32_USART10 +#endif +#if !defined(CONFIG_STM32_HAVE_UART9) +# undef CONFIG_STM32_UART9 +#endif +#if !defined(CONFIG_STM32_HAVE_UART8) +# undef CONFIG_STM32_UART8 +#endif +#if !defined(CONFIG_STM32_HAVE_UART7) +# undef CONFIG_STM32_UART7 +#endif +#if !defined(CONFIG_STM32_HAVE_USART6) +# undef CONFIG_STM32_USART6 +#endif #if !defined(CONFIG_STM32_HAVE_UART5) # undef CONFIG_STM32_UART5 #endif @@ -87,12 +108,44 @@ # undef CONFIG_STM32_UART5_SERIALDRIVER # undef CONFIG_STM32_UART5_1WIREDRIVER #endif +#if !defined(CONFIG_STM32_USART6) +# undef CONFIG_STM32_USART6_SERIALDRIVER +# undef CONFIG_STM32_USART6_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32_UART7) +# undef CONFIG_STM32_UART7_SERIALDRIVER +# undef CONFIG_STM32_UART7_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32_UART8) +# undef CONFIG_STM32_UART8_SERIALDRIVER +# undef CONFIG_STM32_UART8_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32_UART9) +# undef CONFIG_STM32_UART9_SERIALDRIVER +# undef CONFIG_STM32_UART9_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32_USART10) +# undef CONFIG_STM32_USART10_SERIALDRIVER +# undef CONFIG_STM32_USART10_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32_USART11) +# undef CONFIG_STM32_USART11_SERIALDRIVER +# undef CONFIG_STM32_USART11_1WIREDRIVER +#endif +#if !defined(CONFIG_STM32_UART12) +# undef CONFIG_STM32_UART12_SERIALDRIVER +# undef CONFIG_STM32_UART12_1WIREDRIVER +#endif /* Is there a USART enabled? */ #if defined(CONFIG_STM32_LPUART1) || defined(CONFIG_STM32_USART1) || \ defined(CONFIG_STM32_USART2) || defined(CONFIG_STM32_USART3) || \ - defined(CONFIG_STM32_UART4) || defined(CONFIG_STM32_UART5) + defined(CONFIG_STM32_UART4) || defined(CONFIG_STM32_UART5) || \ + defined(CONFIG_STM32_USART6) || defined(CONFIG_STM32_UART7) || \ + defined(CONFIG_STM32_UART8) || defined(CONFIG_STM32_UART9) || \ + defined(CONFIG_STM32_USART10) || defined(CONFIG_STM32_USART11) || \ + defined(CONFIG_STM32_UART12) # define HAVE_UART 1 #endif @@ -104,6 +157,13 @@ # undef CONFIG_USART3_SERIAL_CONSOLE # undef CONFIG_UART4_SERIAL_CONSOLE # undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 1 # define HAVE_CONSOLE 1 #elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART1_SERIALDRIVER) @@ -112,42 +172,193 @@ # undef CONFIG_USART3_SERIAL_CONSOLE # undef CONFIG_UART4_SERIAL_CONSOLE # undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 2 # define HAVE_CONSOLE 1 #elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART2_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE # undef CONFIG_USART1_SERIAL_CONSOLE # undef CONFIG_USART3_SERIAL_CONSOLE # undef CONFIG_UART4_SERIAL_CONSOLE # undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 3 # define HAVE_CONSOLE 1 #elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART3_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE # undef CONFIG_USART1_SERIAL_CONSOLE # undef CONFIG_USART2_SERIAL_CONSOLE # undef CONFIG_UART4_SERIAL_CONSOLE # undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 4 # define HAVE_CONSOLE 1 #elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART4_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE # undef CONFIG_USART1_SERIAL_CONSOLE # undef CONFIG_USART2_SERIAL_CONSOLE # undef CONFIG_USART3_SERIAL_CONSOLE # undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 5 # define HAVE_CONSOLE 1 #elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART5_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE # undef CONFIG_USART1_SERIAL_CONSOLE # undef CONFIG_USART2_SERIAL_CONSOLE # undef CONFIG_USART3_SERIAL_CONSOLE # undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 6 # define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART6_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE +# define CONSOLE_UART 7 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART7_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE +# define CONSOLE_UART 8 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART8_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE +# define CONSOLE_UART 9 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART9_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART9_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE +# define CONSOLE_UART 10 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART10_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART10_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE +# define CONSOLE_UART 11 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_USART11_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART11_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE +# define CONSOLE_UART 12 +# define HAVE_CONSOLE 1 +#elif defined(CONFIG_UART12_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART12_SERIALDRIVER) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_USART1_SERIAL_CONSOLE +# undef CONFIG_USART2_SERIAL_CONSOLE +# undef CONFIG_USART3_SERIAL_CONSOLE +# undef CONFIG_UART4_SERIAL_CONSOLE +# undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# define CONSOLE_UART 13 +# define HAVE_CONSOLE 1 #else # undef CONFIG_USART1_SERIAL_CONSOLE # undef CONFIG_USART2_SERIAL_CONSOLE # undef CONFIG_USART3_SERIAL_CONSOLE # undef CONFIG_UART4_SERIAL_CONSOLE # undef CONFIG_UART5_SERIAL_CONSOLE +# undef CONFIG_USART6_SERIAL_CONSOLE +# undef CONFIG_UART7_SERIAL_CONSOLE +# undef CONFIG_UART8_SERIAL_CONSOLE +# undef CONFIG_UART9_SERIAL_CONSOLE +# undef CONFIG_USART10_SERIAL_CONSOLE +# undef CONFIG_USART11_SERIAL_CONSOLE +# undef CONFIG_UART12_SERIAL_CONSOLE # define CONSOLE_UART 0 # undef HAVE_CONSOLE #endif @@ -157,11 +368,19 @@ */ #if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) +# undef CONFIG_LPUART1_RXDMA # undef CONFIG_USART1_RXDMA # undef CONFIG_USART2_RXDMA # undef CONFIG_USART3_RXDMA # undef CONFIG_UART4_RXDMA # undef CONFIG_UART5_RXDMA +# undef CONFIG_USART6_RXDMA +# undef CONFIG_UART7_RXDMA +# undef CONFIG_UART8_RXDMA +# undef CONFIG_UART9_RXDMA +# undef CONFIG_USART10_RXDMA +# undef CONFIG_USART11_RXDMA +# undef CONFIG_UART12_RXDMA #endif /* Disable the DMA configuration on all unused USARTs */ @@ -190,12 +409,44 @@ # undef CONFIG_UART5_RXDMA #endif +#ifndef CONFIG_STM32_USART6_SERIALDRIVER +# undef CONFIG_USART6_RXDMA +#endif + +#ifndef CONFIG_STM32_UART7_SERIALDRIVER +# undef CONFIG_UART7_RXDMA +#endif + +#ifndef CONFIG_STM32_UART8_SERIALDRIVER +# undef CONFIG_UART8_RXDMA +#endif + +#ifndef CONFIG_STM32_UART9_SERIALDRIVER +# undef CONFIG_UART9_RXDMA +#endif + +#ifndef CONFIG_STM32_USART10_SERIALDRIVER +# undef CONFIG_USART10_RXDMA +#endif + +#ifndef CONFIG_STM32_USART11_SERIALDRIVER +# undef CONFIG_USART11_RXDMA +#endif + +#ifndef CONFIG_STM32_UART12_SERIALDRIVER +# undef CONFIG_UART12_RXDMA +#endif + /* Is DMA available on any (enabled) USART? */ #undef SERIAL_HAVE_DMA #if defined(CONFIG_LPUART1_RXDMA) || defined(CONFIG_USART1_RXDMA) || \ defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \ - defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) + defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) || \ + defined(CONFIG_USART6_RXDMA) || defined(CONFIG_UART7_RXDMA) || \ + defined(CONFIG_UART8_RXDMA) || defined(CONFIG_UART9_RXDMA) || \ + defined(CONFIG_USART10_RXDMA) || defined(CONFIG_USART11_RXDMA) || \ + defined(CONFIG_UART12_RXDMA) # define SERIAL_HAVE_DMA 1 #endif @@ -214,6 +465,20 @@ # define SERIAL_HAVE_CONSOLE_DMA 1 #elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) # define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART9_SERIAL_CONSOLE) && defined(CONFIG_UART9_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART10_SERIAL_CONSOLE) && defined(CONFIG_USART10_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_USART11_SERIAL_CONSOLE) && defined(CONFIG_USART11_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 +#elif defined(CONFIG_UART12_SERIAL_CONSOLE) && defined(CONFIG_UART12_RXDMA) +# define SERIAL_HAVE_CONSOLE_DMA 1 #endif /* Is DMA used on all (enabled) USARTs */ @@ -231,13 +496,31 @@ # undef SERIAL_HAVE_ONLY_DMA #elif defined(CONFIG_STM32_UART5_SERIALDRIVER) && !defined(CONFIG_UART5_RXDMA) # undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_USART6_SERIALDRIVER) && !defined(CONFIG_USART6_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART7_SERIALDRIVER) && !defined(CONFIG_UART7_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART8_SERIALDRIVER) && !defined(CONFIG_UART8_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART9_SERIALDRIVER) && !defined(CONFIG_UART9_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_USART10_SERIALDRIVER) && !defined(CONFIG_USART10_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_USART11_SERIALDRIVER) && !defined(CONFIG_USART11_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA +#elif defined(CONFIG_STM32_UART12_SERIALDRIVER) && !defined(CONFIG_UART12_RXDMA) +# undef SERIAL_HAVE_ONLY_DMA #endif /* Is RS-485 used? */ #if defined(CONFIG_LPUART1_RS485) || defined(CONFIG_USART1_RS485) || \ defined(CONFIG_USART2_RS485) || defined(CONFIG_USART3_RS485) || \ - defined(CONFIG_UART4_RS485) || defined(CONFIG_UART5_RS485) + defined(CONFIG_UART4_RS485) || defined(CONFIG_UART5_RS485) || \ + defined(CONFIG_USART6_RS485) || defined(CONFIG_UART7_RS485) || \ + defined(CONFIG_UART8_RS485) || defined(CONFIG_UART9_RS485) || \ + defined(CONFIG_USART10_RS485) || defined(CONFIG_USART11_RS485) || \ + defined(CONFIG_UART12_RS485) # define HAVE_RS485 1 #endif diff --git a/arch/arm/src/stm32h5/CMakeLists.txt b/arch/arm/src/stm32h5/CMakeLists.txt index d483e540538..681c2585ffe 100644 --- a/arch/arm/src/stm32h5/CMakeLists.txt +++ b/arch/arm/src/stm32h5/CMakeLists.txt @@ -37,17 +37,12 @@ endif() list( APPEND SRCS - stm32_lowputc.c stm32_rcc.c stm32_pwr.c stm32_lse.c stm32_lsi.c stm32_sdmmc.c) -if(CONFIG_STM32_USART) - list(APPEND SRCS stm32_serial.c) -endif() - if(CONFIG_TIMER) list(APPEND SRCS stm32_tim_lowerhalf.c) endif() diff --git a/arch/arm/src/stm32h5/Kconfig b/arch/arm/src/stm32h5/Kconfig index 5af91140a54..175cb940da5 100644 --- a/arch/arm/src/stm32h5/Kconfig +++ b/arch/arm/src/stm32h5/Kconfig @@ -12,6 +12,7 @@ config STM32_H5_PERIPHERALS default y select STM32_HAVE_IP_EXTI_M33_V1 select STM32_HAVE_IP_GPIO_M33_V1 + select STM32_HAVE_IP_USART_M33_V3 select STM32_HAVE_DMA1 select STM32_HAVE_DMA2 select STM32_HAVE_I2C1 diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs index ee23773c917..75a96ddef47 100644 --- a/arch/arm/src/stm32h5/Make.defs +++ b/arch/arm/src/stm32h5/Make.defs @@ -40,14 +40,10 @@ endif # Required STM32H5 files -CHIP_CSRCS += stm32_lowputc.c stm32_rcc.c +CHIP_CSRCS += stm32_rcc.c CHIP_CSRCS += stm32_pwr.c CHIP_CSRCS += stm32_lse.c stm32_lsi.c stm32_sdmmc.c -ifeq ($(CONFIG_STM32_USART),y) -CHIP_CSRCS += stm32_serial.c -endif - ifeq ($(CONFIG_TIMER),y) CHIP_CSRCS += stm32_tim_lowerhalf.c endif diff --git a/arch/arm/src/stm32h5/hardware/stm32_uart.h b/arch/arm/src/stm32h5/hardware/stm32_uart.h deleted file mode 100644 index 80e42a844a9..00000000000 --- a/arch/arm/src/stm32h5/hardware/stm32_uart.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h5/hardware/stm32_uart.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_UART_H -#define __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_UART_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include "chip.h" - -#if defined(CONFIG_STM32_STM32H50XXX) || \ - defined(CONFIG_STM32_STM32H52XXX) || \ - defined(CONFIG_STM32_STM32H53XXX) || \ - defined(CONFIG_STM32_STM32H56XXX) || \ - defined(CONFIG_STM32_STM32H57XXX) -# include "hardware/stm32h5xxx_uart.h" -#else -# error "Unsupported STM32 H5 uart" -#endif - -#endif /* __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32_UART_H */ \ No newline at end of file diff --git a/arch/arm/src/stm32h5/hardware/stm32h56x_dmasigmap.h b/arch/arm/src/stm32h5/hardware/stm32h56x_dmasigmap.h index 3fc1c4fb9de..0f388d9f21c 100644 --- a/arch/arm/src/stm32h5/hardware/stm32h56x_dmasigmap.h +++ b/arch/arm/src/stm32h5/hardware/stm32h56x_dmasigmap.h @@ -215,4 +215,20 @@ #define GPDMA_TRIG_LPTIM6_CH1 (42) #define GPDMA_TRIG_LPTIM6_CH2 (43) -#endif /* __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32H56X_DMASIGMAP_H */ \ No newline at end of file +/* USART RX DMA request numbers */ + +#define STM32_LPUART1_RXDMA_REQ GPDMA_REQ_LPUART1_RX +#define STM32_USART1_RXDMA_REQ GPDMA_REQ_USART1_RX +#define STM32_USART2_RXDMA_REQ GPDMA_REQ_USART2_RX +#define STM32_USART3_RXDMA_REQ GPDMA_REQ_USART3_RX +#define STM32_UART4_RXDMA_REQ GPDMA_REQ_UART4_RX +#define STM32_UART5_RXDMA_REQ GPDMA_REQ_UART5_RX +#define STM32_USART6_RXDMA_REQ GPDMA_REQ_USART6_RX +#define STM32_UART7_RXDMA_REQ GPDMA_REQ_UART7_RX +#define STM32_UART8_RXDMA_REQ GPDMA_REQ_UART8_RX +#define STM32_UART9_RXDMA_REQ GPDMA_REQ_UART9_RX +#define STM32_USART10_RXDMA_REQ GPDMA_REQ_USART10_RX +#define STM32_USART11_RXDMA_REQ GPDMA_REQ_USART11_RX +#define STM32_UART12_RXDMA_REQ GPDMA_REQ_UART12_RX + +#endif /* __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32H56X_DMASIGMAP_H */ diff --git a/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h b/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h deleted file mode 100644 index 06bde190cf3..00000000000 --- a/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h +++ /dev/null @@ -1,464 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32H5XXX_UART_H -#define __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32H5XXX_UART_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "chip.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Register Offsets *********************************************************/ - -#define STM32_USART_CR1_OFFSET 0x0000 /* Control register 1 */ -#define STM32_USART_CR2_OFFSET 0x0004 /* Control register 2 */ -#define STM32_USART_CR3_OFFSET 0x0008 /* Control register 3 */ -#define STM32_USART_BRR_OFFSET 0x000c /* Baud Rate register */ -#define STM32_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ -#define STM32_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ -#define STM32_USART_RQR_OFFSET 0x0018 /* Request register */ -#define STM32_USART_ISR_OFFSET 0x001c /* Interrupt and status register */ -#define STM32_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ -#define STM32_USART_RDR_OFFSET 0x0024 /* Receive Data register */ -#define STM32_USART_TDR_OFFSET 0x0028 /* Transmit Data register */ -#define STM32_USART_PRESC_OFFSET 0x002c /* Prescaler register */ - -/* Register Addresses *******************************************************/ - -#if STM32_NLPUART > 0 -# define STM32_LPUART1_CR1 (STM32_LPUART1_BASE + STM32_USART_CR1_OFFSET) -# define STM32_LPUART1_CR2 (STM32_LPUART1_BASE + STM32_USART_CR2_OFFSET) -# define STM32_LPUART1_CR3 (STM32_LPUART1_BASE + STM32_USART_CR3_OFFSET) -# define STM32_LPUART1_BRR (STM32_LPUART1_BASE + STM32_USART_BRR_OFFSET) -# define STM32_LPUART1_GTPR (STM32_LPUART1_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_LPUART1_RTOR (STM32_LPUART1_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_LPUART1_RQR (STM32_LPUART1_BASE + STM32_USART_RQR_OFFSET) -# define STM32_LPUART1_ISR (STM32_LPUART1_BASE + STM32_USART_ISR_OFFSET) -# define STM32_LPUART1_ICR (STM32_LPUART1_BASE + STM32_USART_ICR_OFFSET) -# define STM32_LPUART1_RDR (STM32_LPUART1_BASE + STM32_USART_RDR_OFFSET) -# define STM32_LPUART1_TDR (STM32_LPUART1_BASE + STM32_USART_TDR_OFFSET) -# define STM32_LPUART1_PRESC (STM32_LPUART1_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 0 -# define STM32_USART1_CR1 (STM32_USART1_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART1_CR2 (STM32_USART1_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART1_CR3 (STM32_USART1_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART1_BRR (STM32_USART1_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART1_GTPR (STM32_USART1_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART1_RTOR (STM32_USART1_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART1_RQR (STM32_USART1_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART1_ISR (STM32_USART1_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART1_ICR (STM32_USART1_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART1_RDR (STM32_USART1_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART1_TDR (STM32_USART1_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART1_PRESC (STM32_USART1_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 1 -# define STM32_USART2_CR1 (STM32_USART2_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART2_CR2 (STM32_USART2_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART2_CR3 (STM32_USART2_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART2_BRR (STM32_USART2_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART2_GTPR (STM32_USART2_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART2_RTOR (STM32_USART2_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART2_RQR (STM32_USART2_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART2_ISR (STM32_USART2_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART2_ICR (STM32_USART2_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART2_RDR (STM32_USART2_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART2_TDR (STM32_USART2_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART2_PRESC (STM32_USART2_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 2 -# define STM32_USART3_CR1 (STM32_USART3_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART3_CR2 (STM32_USART3_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART3_CR3 (STM32_USART3_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART3_BRR (STM32_USART3_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART3_GTPR (STM32_USART3_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART3_RTOR (STM32_USART3_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART3_RQR (STM32_USART3_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART3_ISR (STM32_USART3_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART3_ICR (STM32_USART3_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART3_RDR (STM32_USART3_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART3_TDR (STM32_USART3_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART3_PRESC (STM32_USART3_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 4 -# define STM32_USART6_CR1 (STM32_USART6_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART6_CR2 (STM32_USART6_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART6_CR3 (STM32_USART6_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART6_BRR (STM32_USART6_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART6_GTPR (STM32_USART6_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART6_RTOR (STM32_USART6_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART6_RQR (STM32_USART6_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART6_ISR (STM32_USART6_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART6_ICR (STM32_USART6_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART6_RDR (STM32_USART6_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART6_TDR (STM32_USART6_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART6_PRESC (STM32_USART6_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 5 -# define STM32_USART10_CR1 (STM32_USART10_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART10_CR2 (STM32_USART10_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART10_CR3 (STM32_USART10_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART10_BRR (STM32_USART10_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART10_GTPR (STM32_USART10_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART10_RTOR (STM32_USART10_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART10_RQR (STM32_USART10_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART10_ISR (STM32_USART10_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART10_ICR (STM32_USART10_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART10_RDR (STM32_USART10_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART10_TDR (STM32_USART10_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART10_PRESC (STM32_USART10_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 6 -# define STM32_USART11_CR1 (STM32_USART11_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART11_CR2 (STM32_USART11_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART11_CR3 (STM32_USART11_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART11_BRR (STM32_USART11_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART11_GTPR (STM32_USART11_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART11_RTOR (STM32_USART11_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART11_RQR (STM32_USART11_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART11_ISR (STM32_USART11_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART11_ICR (STM32_USART11_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART11_RDR (STM32_USART11_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART11_TDR (STM32_USART11_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART11_PRESC (STM32_USART11_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUART > 0 -# define STM32_UART4_CR1 (STM32_UART4_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART4_CR2 (STM32_UART4_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART4_CR3 (STM32_UART4_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART4_BRR (STM32_UART4_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART4_GTPR (STM32_UART4_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART4_RTOR (STM32_UART4_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART4_RQR (STM32_UART4_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART4_ISR (STM32_UART4_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART4_ICR (STM32_UART4_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART4_RDR (STM32_UART4_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART4_TDR (STM32_UART4_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART4_PRESC (STM32_UART4_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUART > 1 -# define STM32_UART5_CR1 (STM32_UART5_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART5_CR2 (STM32_UART5_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART5_CR3 (STM32_UART5_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART5_BRR (STM32_UART5_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART5_GTPR (STM32_UART5_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART5_RTOR (STM32_UART5_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART5_RQR (STM32_UART5_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART5_ISR (STM32_UART5_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART5_ICR (STM32_UART5_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART5_RDR (STM32_UART5_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART5_TDR (STM32_UART5_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART5_PRESC (STM32_UART5_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUART > 2 -# define STM32_UART7_CR1 (STM32_UART7_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART7_CR2 (STM32_UART7_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART7_CR3 (STM32_UART7_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART7_BRR (STM32_UART7_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART7_GTPR (STM32_UART7_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART7_RTOR (STM32_UART7_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART7_RQR (STM32_UART7_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART7_ISR (STM32_UART7_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART7_ICR (STM32_UART7_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART7_RDR (STM32_UART7_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART7_TDR (STM32_UART7_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART7_PRESC (STM32_UART7_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUART > 3 -# define STM32_UART8_CR1 (STM32_UART8_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART8_CR2 (STM32_UART8_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART8_CR3 (STM32_UART8_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART8_BRR (STM32_UART8_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART8_GTPR (STM32_UART8_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART8_RTOR (STM32_UART8_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART8_RQR (STM32_UART8_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART8_ISR (STM32_UART8_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART8_ICR (STM32_UART8_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART8_RDR (STM32_UART8_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART8_TDR (STM32_UART8_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART8_PRESC (STM32_UART8_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUART > 4 -# define STM32_UART9_CR1 (STM32_UART9_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART9_CR2 (STM32_UART9_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART9_CR3 (STM32_UART9_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART9_BRR (STM32_UART9_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART9_GTPR (STM32_UART9_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART9_RTOR (STM32_UART9_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART9_RQR (STM32_UART9_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART9_ISR (STM32_UART9_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART9_ICR (STM32_UART9_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART9_RDR (STM32_UART9_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART9_TDR (STM32_UART9_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART9_PRESC (STM32_UART9_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUART > 5 -# define STM32_UART12_CR1 (STM32_UART12_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART12_CR2 (STM32_UART12_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART12_CR3 (STM32_UART12_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART12_BRR (STM32_UART12_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART12_GTPR (STM32_UART12_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART12_RTOR (STM32_UART12_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART12_RQR (STM32_UART12_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART12_ISR (STM32_UART12_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART12_ICR (STM32_UART12_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART12_RDR (STM32_UART12_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART12_TDR (STM32_UART12_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART12_PRESC (STM32_UART12_BASE + STM32_USART_PRESC_OFFSET) -#endif - -/* Register Bitfield Definitions ********************************************/ - -/* Control register 1 */ - -#define USART_CR1_UE (1 << 0) /* Bit 0: USART Enable */ -#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode */ -#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ -#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ -#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ -#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ -#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ -#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ -#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ -#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ -#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ -#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ -#define USART_CR1_M0 (1 << 12) /* Bit 12: Word length */ -#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ -#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ -#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ - -#define USART_CR1_DEDT_SHIFT (16) /* Bits 16..20 DE deactivation delay */ -#define USART_CR1_DEDT_MASK (0x1f << USART_CR1_DEDT_SHIFT) - -#define USART_CR1_DEAT_SHIFT (21) /* Bits 21..25 DE activation delay */ -#define USART_CR1_DEAT_MASK (0x1f << USART_CR1_DEAT_SHIFT) - -#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ -#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of block interrupt enable */ -#define USART_CR1_M1 (1 << 28) /* Bit 28: Word length */ -#define USART_CR1_FIFOEN (1 << 29) /* Bit 29: FIFO EN */ -#define USART_CR1_TXFEIE (1 << 30) /* Bit 30: TX FIFO empty interrupt enable */ -#define USART_CR1_RXFFIE (1 << 31) /* Bit 31: RX FIFO full interrupt enable */ - -#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE| \ - USART_CR1_TCIE|USART_CR1_TXEIE| \ - USART_CR1_PEIE|USART_CR1_CMIE| \ - USART_CR1_RTOIE|USART_CR1_EOBIE| \ - USART_CR1_TXFEIE|USART_CR1_RXFFIE) -#define LPUART_CR1_ALLINTS \ - (USART_CR1_IDLEIE | USART_CR1_RXNEIE | USART_CR1_TCIE | \ - USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_CMIE | \ - USART_CR1_TXFEIE | USART_CR1_RXFFIE | \ - USART_CR1_TXFEIE | USART_CR1_RXFFIE) - -/* Control register 2 */ - -#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: 7-bit/4-bit Address Detection */ -#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ -#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ -#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ -#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ -#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ -#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ - -#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ -#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) -# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ -# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ -# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ -# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ - -#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ -#define USART_CR2_SWAP (1 << 15) /* Bit 15: Swap TX/RX pins */ -#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ -#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ -#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ -#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ -#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto Baud rate enable */ - -#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Autobaud rate mode*/ -#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) -#define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* 00: Start bit */ -#define USART_CR2_ABRMOD_EDGES (1 << USART_CR2_ABRMOD_SHIFT) /* 01: Falling-to-falling edge -> frame must start with 10xxxxxx */ -#define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 10: 0x7F */ -#define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 11: 0x55 */ - -#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ - -#define USART_CR2_ADD_SHIFT (24) /* Bits 24-31: Address of the USART node */ -#define USART_CR2_ADD_MASK (0xff << USART_CR2_ADD_SHIFT) - -/* Control register 3 */ - -#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ -#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ -#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ -#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ -#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ -#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ -#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ -#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ -#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ -#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ -#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ -#define USART_CR3_ONEBIT (1 << 11) /* Bit 11: One sample bit method Enable */ -#define USART_CR3_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ -#define USART_CR3_DDRE (1 << 13) /* Bit 13: DMA disable on Reception error */ -#define USART_CR3_DEM (1 << 14) /* Bit 14: Driver Enable mode */ -#define USART_CR3_DEP (1 << 15) /* Bit 15: Driver Enable polarity selection */ -#define USART_CR3_SCARCNT2_SHIFT (17) /* Bits 17-19: Smart card auto retry count */ -#define USART_CR3_SCARCNT2_MASK (7 << USART_CR3_SCARCNT2_SHIFT) -#define USART_CR3_WUS_SHIFT (20) /* Bits 20-21: Wakeup from Stop mode interrupt flag selection */ -#define USART_CR3_WUS_MASK (3 << USART_CR3_WUS_SHIFT) -#define USART_CR3_WUS_ADDRESS (0 << USART_CR3_WUS_SHIFT) /* 00: WUF active on address match */ -#define USART_CR3_WUS_START (2 << USART_CR3_WUS_SHIFT) /* 10: WUF active on Start bit detection */ -#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) /* 11: WUF active on RXNE */ -#define USART_CR3_WUFIE (1 << 22) /* Bit 22: Wakeup from Stop mode interrupt enable */ -#define USART_CR3_TXFTIE (1 << 23) /* Bit 23: TXFIFO threshold interrupt enable */ -#define USART_CR3_TCBGTIE (1 << 24) /* Bit 24: Transmission Complete before guard time, interrupt enable */ -#define USART_CR3_RXFTCFG_SHIFT (25) /* Bits 25-27: Receive FIFO threshold configuration */ -#define USART_CR3_RXFTCFG_MASK (7 << USART_CR3_RXFTCFG_SHIFT) -#define USART_CR3_RXFTIE (1 << 28) /* Bit 28: RXFIFO threshold interrupt enable */ -#define USART_CR3_TXFTCFG_SHIFT (29) /* Bits 29-31: Transmit FIFO threshold configuration */ -#define USART_CR3_TXFTCFG_MASK (7 << USART_CR3_TXFTCFG_SHIFT) - -#define USART_CR3_TXFTCFG_0 (0) /* TX FIFO reaches 1/8 depth */ -#define USART_CR3_TXFTCFG_1 (1) /* TX FIFO reaches 1/4 depth */ -#define USART_CR3_TXFTCFG_2 (2) /* TX FIFO reaches 1/2 depth */ -#define USART_CR3_TXFTCFG_3 (3) /* TX FIFO reaches 3/4 depth */ -#define USART_CR3_TXFTCFG_4 (4) /* TX FIFO reaches 7/8 depth */ -#define USART_CR3_TXFTCFG_5 (5) /* TX FIFO reaches full depth */ - -#define USART_CR3_RXFTCFG_0 (0) /* RX FIFO reaches 1/8 depth */ -#define USART_CR3_RXFTCFG_1 (1) /* RX FIFO reaches 1/4 depth */ -#define USART_CR3_RXFTCFG_2 (2) /* RX FIFO reaches 1/2 depth */ -#define USART_CR3_RXFTCFG_3 (3) /* RX FIFO reaches 3/4 depth */ -#define USART_CR3_RXFTCFG_4 (4) /* RX FIFO reaches 7/8 depth */ -#define USART_CR3_RXFTCFG_5 (5) /* RX FIFO reaches full depth */ - -/* Baud Rate Register */ - -#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ -#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) -#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ -#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) - -/* Guard time and prescaler register */ - -#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ -#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) -#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ -#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) - -/* Receiver timeout register */ - -/* Request Register */ - -#define USART_CR1_SBRKQ (1 << 1) /* Bit 1: Send Break */ - -/* Interrupt and Status register */ - -#define USART_ISR_PE (1 << 0) /* Bit 0: Parity Error */ -#define USART_ISR_FE (1 << 1) /* Bit 1: Framing Error */ -#define USART_ISR_NF (1 << 2) /* Bit 2: Noise Error Flag */ -#define USART_ISR_ORE (1 << 3) /* Bit 3: OverRun Error */ -#define USART_ISR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ -#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ -#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission Complete */ -#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ -#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN Break Detection Flag */ -#define USART_ISR_CTSIF (1 << 9) /* Bit 9: CTS Interrupt Flag */ -#define USART_ISR_CTS (1 << 10) /* Bit 10: CTS Flag */ -#define USART_ISR_RTOF (1 << 11) /* Bit 11: Receiver timeout Flag */ -#define USART_ISR_EOBF (1 << 12) /* Bit 12: End of block Flag */ -#define USART_ISR_UDR (1 << 13) /* Bit 13: SPI slave underrun error flag */ -#define USART_ISR_ABRE (1 << 14) /* Bit 14: Auto baud rate Error */ -#define USART_ISR_ABRF (1 << 15) /* Bit 15: Auto baud rate Flag */ -#define USART_ISR_BUSY (1 << 16) /* Bit 16: Busy Flag */ -#define USART_ISR_CMF (1 << 17) /* Bit 17: Character match Flag */ -#define USART_ISR_SBKF (1 << 18) /* Bit 18: Send break Flag */ -#define USART_ISR_RWU (1 << 19) /* Bit 19: Receiver wakeup from Mute mode */ -#define USART_ISR_WUF (1 << 20) /* Bit 20: Wakeup from Stop mode Flag */ -#define USART_ISR_TEACK (1 << 21) /* Bit 21: Transmit enable acknowledge Flag */ -#define USART_ISR_REACK (1 << 22) /* Bit 22: Receive enable acknowledge Flag */ -#define USART_ISR_TXFE (1 << 23) /* Bit 23: TXFIFO empty */ -#define USART_ISR_RXFF (1 << 24) /* Bit 24: RXFIFO full */ -#define USART_ISR_TCBGT (1 << 25) /* Bit 25: Transmission complete before guard time flag */ -#define USART_ISR_RXFT (1 << 26) /* Bit 26: RXFIFO threshold reached */ -#define USART_ISR_TXFT (1 << 27) /* Bit 27: TXFIFO threshold reached */ - -/* ICR */ - -#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ -#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ -#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected clear flag */ -#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ -#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ -#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete clear flag */ -#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ -#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS clear flag */ -#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ -#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ -#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ -#define USART_ICR_WUCF (1 << 20) /* Bit 20: Wakeup from Stop mode clear flag */ - -/* Receive Data register */ - -#define USART_RDR_SHIFT (0) /* Bits 8:0: Data value */ -#define USART_RDR_MASK (0xff << USART_RDR_SHIFT) - -/* Transmit Data register */ - -#define USART_TDR_SHIFT (0) /* Bits 8:0: Data value */ -#define USART_TDR_MASK (0xff << USART_TDR_SHIFT) - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#endif /* __ARCH_ARM_SRC_STM32H5_HARDWARE_STM32H5XXX_UART_H */ diff --git a/arch/arm/src/stm32h5/stm32.h b/arch/arm/src/stm32h5/stm32.h index a5ef98353bc..fab0012f79d 100644 --- a/arch/arm/src/stm32h5/stm32.h +++ b/arch/arm/src/stm32h5/stm32.h @@ -39,6 +39,7 @@ #include "chip.h" #include "stm32_adc.h" #include "stm32_dbgmcu.h" +#include "stm32_dma.h" #include "stm32_dts.h" #include "stm32_flash.h" #include "stm32_gpio.h" diff --git a/arch/arm/src/stm32h5/stm32_lowputc.c b/arch/arm/src/stm32h5/stm32_lowputc.c deleted file mode 100644 index 16a0a613166..00000000000 --- a/arch/arm/src/stm32h5/stm32_lowputc.c +++ /dev/null @@ -1,552 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h5/stm32_lowputc.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include - -#include "arm_internal.h" -#include "chip.h" - -#include "stm32.h" -#include "stm32_rcc.h" -#include "stm32_gpio.h" -#include "stm32_uart.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Select USART parameters for the selected console */ - -#ifdef HAVE_CONSOLE -# if defined(CONFIG_LPUART1_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_LPUART1_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB3ENR -# define STM32_CONSOLE_APBEN RCC_APB3ENR_LPUART1EN -# define STM32_CONSOLE_BAUD CONFIG_LPUART1_BAUD -# define STM32_CONSOLE_BITS CONFIG_LPUART1_BITS -# define STM32_CONSOLE_PARITY CONFIG_LPUART1_PARITY -# define STM32_CONSOLE_2STOP CONFIG_LPUART1_2STOP -# define STM32_CONSOLE_TX GPIO_LPUART1_TX -# define STM32_CONSOLE_RX GPIO_LPUART1_RX -# ifdef CONFIG_LPUART1_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_LPUART1_RS485_DIR -# if (CONFIG_LPUART1_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART1_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART1_BASE -# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR -# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART1EN -# define STM32_CONSOLE_BAUD CONFIG_USART1_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART1_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART1_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART1_2STOP -# define STM32_CONSOLE_TX GPIO_USART1_TX -# define STM32_CONSOLE_RX GPIO_USART1_RX -# ifdef CONFIG_USART1_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR -# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART2_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART2_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_USART2EN -# define STM32_CONSOLE_BAUD CONFIG_USART2_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART2_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART2_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART2_2STOP -# define STM32_CONSOLE_TX GPIO_USART2_TX -# define STM32_CONSOLE_RX GPIO_USART2_RX -# ifdef CONFIG_USART2_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR -# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART3_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART3_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_USART3EN -# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART3_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP -# define STM32_CONSOLE_TX GPIO_USART3_TX -# define STM32_CONSOLE_RX GPIO_USART3_RX -# ifdef CONFIG_USART3_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR -# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART4_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART4_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_UART4EN -# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART4_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP -# define STM32_CONSOLE_TX GPIO_UART4_TX -# define STM32_CONSOLE_RX GPIO_UART4_RX -# ifdef CONFIG_UART4_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR -# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART5_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART5_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_UART5EN -# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART5_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP -# define STM32_CONSOLE_TX GPIO_UART5_TX -# define STM32_CONSOLE_RX GPIO_UART5_RX -# ifdef CONFIG_UART5_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR -# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART6_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART6_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_USART6EN -# define STM32_CONSOLE_BAUD CONFIG_USART6_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART6_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART6_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART6_2STOP -# define STM32_CONSOLE_TX GPIO_USART6_TX -# define STM32_CONSOLE_RX GPIO_USART6_RX -# ifdef CONFIG_USART6_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART6_RS485_DIR -# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART7_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART7_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_UART7EN -# define STM32_CONSOLE_BAUD CONFIG_UART7_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART7_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART7_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART7_2STOP -# define STM32_CONSOLE_TX GPIO_UART7_TX -# define STM32_CONSOLE_RX GPIO_UART7_RX -# ifdef CONFIG_UART7_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART7_RS485_DIR -# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART8_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART8_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_UART8EN -# define STM32_CONSOLE_BAUD CONFIG_UART8_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART8_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART8_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART8_2STOP -# define STM32_CONSOLE_TX GPIO_UART8_TX -# define STM32_CONSOLE_RX GPIO_UART8_RX -# ifdef CONFIG_UART8_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART8_RS485_DIR -# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART9_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART9_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_UART9EN -# define STM32_CONSOLE_BAUD CONFIG_UART9_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART9_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART9_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART9_2STOP -# define STM32_CONSOLE_TX GPIO_UART9_TX -# define STM32_CONSOLE_RX GPIO_UART9_RX -# ifdef CONFIG_UART9_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART9_RS485_DIR -# if (CONFIG_UART9_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART10_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART10_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_USART10EN -# define STM32_CONSOLE_BAUD CONFIG_USART10_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART10_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART10_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART10_2STOP -# define STM32_CONSOLE_TX GPIO_USART10_TX -# define STM32_CONSOLE_RX GPIO_USART10_RX -# ifdef CONFIG_USART10_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART10_RS485_DIR -# if (CONFIG_USART10_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART11_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART11_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_USART11EN -# define STM32_CONSOLE_BAUD CONFIG_USART11_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART11_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART11_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART11_2STOP -# define STM32_CONSOLE_TX GPIO_USART11_TX -# define STM32_CONSOLE_RX GPIO_USART11_RX -# ifdef CONFIG_USART11_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART11_RS485_DIR -# if (CONFIG_USART11_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART12_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART12_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1LENR -# define STM32_CONSOLE_APBEN RCC_APB1LENR_UART12EN -# define STM32_CONSOLE_BAUD CONFIG_UART12_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART12_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART12_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART12_2STOP -# define STM32_CONSOLE_TX GPIO_UART12_TX -# define STM32_CONSOLE_RX GPIO_UART12_RX -# ifdef CONFIG_UART12_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART12_RS485_DIR -# if (CONFIG_UART12_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# endif - - /* CR1 settings */ - -# if STM32_CONSOLE_BITS == 9 -# define USART_CR1_M0_VALUE USART_CR1_M0 -# define USART_CR1_M1_VALUE 0 -# elif STM32_CONSOLE_BITS == 7 -# define USART_CR1_M0_VALUE 0 -# define USART_CR1_M1_VALUE USART_CR1_M1 -# else /* 8 bits */ -# define USART_CR1_M0_VALUE 0 -# define USART_CR1_M1_VALUE 0 -# endif - -# if STM32_CONSOLE_PARITY == 1 /* odd parity */ -# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) -# elif STM32_CONSOLE_PARITY == 2 /* even parity */ -# define USART_CR1_PARITY_VALUE USART_CR1_PCE -# else /* no parity */ -# define USART_CR1_PARITY_VALUE 0 -# endif - -# if STM32_CONSOLE_BASE == STM32_LPUART1_BASE -# define USART_CR1_CLRBITS \ - (USART_CR1_UE | USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ - USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_M1 | \ - USART_CR1_MME | USART_CR1_OVER8 | USART_CR1_DEDT_MASK | \ - USART_CR1_DEAT_MASK | LPUART_CR1_ALLINTS) -# else -# define USART_CR1_CLRBITS \ - (USART_CR1_UE | USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ - USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_M1 | \ - USART_CR1_MME | USART_CR1_OVER8 | USART_CR1_DEDT_MASK | \ - USART_CR1_DEAT_MASK | USART_CR1_ALLINTS) -# endif - -# define USART_CR1_SETBITS (USART_CR1_M0_VALUE|USART_CR1_M1_VALUE|USART_CR1_PARITY_VALUE) - - /* CR2 settings */ - -# if STM32_CONSOLE_2STOP != 0 -# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 -# else -# define USART_CR2_STOP2_VALUE 0 -# endif - -# define USART_CR2_CLRBITS \ - (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ - USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ - USART_CR2_LINEN | USART_CR2_SWAP | USART_CR2_RXINV | USART_CR2_TXINV | \ - USART_CR2_DATAINV | USART_CR2_MSBFIRST | USART_CR2_ABREN | \ - USART_CR2_ABRMOD_MASK | USART_CR2_RTOEN | USART_CR2_ADD_MASK) - -# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE - - /* CR3 settings */ - -# define USART_CR3_CLRBITS \ - (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ - USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ - USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \ - USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | USART_CR3_DEP | \ - USART_CR3_SCARCNT2_MASK | USART_CR3_WUS_MASK | USART_CR3_WUFIE) - -# define USART_CR3_SETBITS 0 - -# undef USE_OVER8 - - /* Calculate USART BAUD rate divider */ -# if STM32_CONSOLE_BASE == STM32_LPUART1_BASE - - /* BRR = (256 * (APBCLOCK / Prescaler)) / (Baud rate) - * With Prescaler == 16, BRR = (16 * APBCLOCK / (Baud rate) - * Set Prescaler to 16 to support wide range of standard baud rates - */ - -# define STM32_BRR_VALUE \ - (((STM32_APBCLOCK & 0xf0000000) / STM32_CONSOLE_BAUD) << 4) + \ - (((STM32_APBCLOCK & 0x0fffffff) << 4) / STM32_CONSOLE_BAUD) -# define STM32_PRESC_VALUE 0x7 - -# else - - /* Baud rate for standard USART (SPI mode included): - * - * In case of oversampling by 16, the equation is: - * baud = fCK / UARTDIV - * UARTDIV = fCK / baud - * - * In case of oversampling by 8, the equation is: - * - * baud = 2 * fCK / UARTDIV - * UARTDIV = 2 * fCK / baud - */ - -# define STM32_USARTDIV8 \ - (((STM32_APBCLOCK << 1) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) -# define STM32_USARTDIV16 \ - ((STM32_APBCLOCK + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) - - /* Use oversamply by 8 only if the divisor is small. But what is small? */ - -# if STM32_USARTDIV8 > 2000 -# define STM32_BRR_VALUE STM32_USARTDIV16 -# else -# define USE_OVER8 1 -# define STM32_BRR_VALUE \ - ((STM32_USARTDIV8 & 0xfff0) | ((STM32_USARTDIV8 & 0x000f) >> 1)) -# endif -# endif -#endif /* HAVE_CONSOLE */ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_lowputc - * - * Description: - * Output one byte on the serial console - * - ****************************************************************************/ - -void arm_lowputc(char ch) -{ -#ifdef HAVE_CONSOLE - /* Wait until the TX data register is empty */ - - while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & - USART_ISR_TXE) == 0); -#ifdef STM32_CONSOLE_RS485_DIR - stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, - STM32_CONSOLE_RS485_DIR_POLARITY); -#endif - - /* Then send the character */ - - putreg32((uint32_t)ch, STM32_CONSOLE_BASE + STM32_USART_TDR_OFFSET); - -#ifdef STM32_CONSOLE_RS485_DIR - while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & - USART_ISR_TC) == 0); - stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, - !STM32_CONSOLE_RS485_DIR_POLARITY); -#endif - -#endif /* HAVE_CONSOLE */ -} - -/**************************************************************************** - * Name: stm32_lowsetup - * - * Description: - * This performs basic initialization of the USART used for the serial - * console. Its purpose is to get the console output available as soon - * as possible. - * - ****************************************************************************/ - -void stm32_lowsetup(void) -{ -#if defined(HAVE_UART) -#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) - uint32_t cr; -#endif - -#if defined(HAVE_CONSOLE) - /* Enable USART APB clock */ - - modifyreg32(STM32_CONSOLE_APBREG, 0, STM32_CONSOLE_APBEN); -#endif - - /* Enable the console USART and configure GPIO pins needed for rx/tx. - * - * NOTE: Clocking for selected U[S]ARTs was already provided in - * stm32_rcc.c - */ - -#ifdef STM32_CONSOLE_TX - stm32_configgpio(STM32_CONSOLE_TX); -#endif -#ifdef STM32_CONSOLE_RX - stm32_configgpio(STM32_CONSOLE_RX); -#endif - -#ifdef STM32_CONSOLE_RS485_DIR - stm32_configgpio(STM32_CONSOLE_RS485_DIR); - stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, - !STM32_CONSOLE_RS485_DIR_POLARITY); -#endif - - /* Enable and configure the selected console device */ - -#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) - /* Configure CR2 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); - cr &= ~USART_CR2_CLRBITS; - cr |= USART_CR2_SETBITS; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); - - /* Configure CR1 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); - cr &= ~USART_CR1_CLRBITS; - cr |= USART_CR1_SETBITS; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); - - /* Configure CR3 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); - cr &= ~USART_CR3_CLRBITS; - cr |= USART_CR3_SETBITS; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); - - /* Configure the USART Baud Rate */ - - putreg32(STM32_BRR_VALUE, - STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); - - /* Select oversampling by 8 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); -#ifdef USE_OVER8 - cr |= USART_CR1_OVER8; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); -#endif - - /* Enable Rx, Tx, and the USART */ - - cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); - -#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ -#endif /* HAVE_UART */ -} diff --git a/arch/arm/src/stm32h5/stm32_lowputc.h b/arch/arm/src/stm32h5/stm32_lowputc.h deleted file mode 100644 index 962497d1429..00000000000 --- a/arch/arm/src/stm32h5/stm32_lowputc.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h5/stm32_lowputc.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32H5_STM32_LOWPUTC_H -#define __ARCH_ARM_SRC_STM32H5_STM32_LOWPUTC_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "chip.h" - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Name: stm32_lowsetup - * - * Description: - * Called at the very beginning of _start. Performs low level - * initialization of serial console. - * - ****************************************************************************/ - -void stm32_lowsetup(void); - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_STM32H5_STM32_LOWPUTC_H */ diff --git a/arch/arm/src/stm32h5/stm32_rcc_m33.h b/arch/arm/src/stm32h5/stm32_rcc_m33.h index 19589c06f37..2961a12a8f4 100644 --- a/arch/arm/src/stm32h5/stm32_rcc_m33.h +++ b/arch/arm/src/stm32h5/stm32_rcc_m33.h @@ -29,6 +29,8 @@ #include +#include + #include "arm_internal.h" #include "chip.h" @@ -117,6 +119,252 @@ static inline void stm32_mco2config(uint32_t source, uint32_t div) putreg32(regval, STM32_RCC_CFGR1); } +/* USART clock and RCC definitions */ + +#define STM32_LPUART1_FREQUENCY STM32_PCLK3_FREQUENCY +#define STM32_LPUART1_RCC_REG STM32_RCC_APB3ENR +#define STM32_LPUART1_RCC_EN RCC_APB3ENR_LPUART1EN + +#if !defined(STM32_RCC_CCIPR1_USART1SEL) || \ + STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_RCCPCLK2 +# define STM32_USART1_FREQUENCY STM32_PCLK2_FREQUENCY +#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_PLL2QCK +# define STM32_USART1_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_PLL3QCK +# define STM32_USART1_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_HSIKERCK +# define STM32_USART1_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_CSIKERCK +# define STM32_USART1_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_LSECK +# define STM32_USART1_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported USART1 Clock Selection" +#endif + +#define STM32_USART1_RCC_REG STM32_RCC_APB2ENR +#define STM32_USART1_RCC_EN RCC_APB2ENR_USART1EN + +#if !defined(STM32_RCC_CCIPR1_USART2SEL) || \ + STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_RCCPCLK1 +# define STM32_USART2_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_PLL2QCK +# define STM32_USART2_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_PLL3QCK +# define STM32_USART2_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_HSIKERCK +# define STM32_USART2_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_CSIKERCK +# define STM32_USART2_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_LSECK +# define STM32_USART2_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported USART2 Clock Selection" +#endif + +#define STM32_USART2_RCC_REG STM32_RCC_APB1LENR +#define STM32_USART2_RCC_EN RCC_APB1LENR_USART2EN + +#if !defined(STM32_RCC_CCIPR1_USART3SEL) || \ + STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_RCCPCLK1 +# define STM32_USART3_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_PLL2QCK +# define STM32_USART3_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_PLL3QCK +# define STM32_USART3_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_HSIKERCK +# define STM32_USART3_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_CSIKERCK +# define STM32_USART3_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_LSECK +# define STM32_USART3_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported USART3 Clock Selection" +#endif + +#define STM32_USART3_RCC_REG STM32_RCC_APB1LENR +#define STM32_USART3_RCC_EN RCC_APB1LENR_USART3EN + +#if !defined(STM32_RCC_CCIPR1_UART4SEL) || \ + STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_RCCPCLK1 +# define STM32_UART4_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_PLL2QCK +# define STM32_UART4_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_PLL3QCK +# define STM32_UART4_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_HSIKERCK +# define STM32_UART4_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_CSIKERCK +# define STM32_UART4_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_LSECK +# define STM32_UART4_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported UART4 Clock Selection" +#endif + +#define STM32_UART4_RCC_REG STM32_RCC_APB1LENR +#define STM32_UART4_RCC_EN RCC_APB1LENR_UART4EN + +#if !defined(STM32_RCC_CCIPR1_UART5SEL) || \ + STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_RCCPCLK1 +# define STM32_UART5_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_PLL2QCK +# define STM32_UART5_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_PLL3QCK +# define STM32_UART5_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_HSIKERCK +# define STM32_UART5_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_CSIKERCK +# define STM32_UART5_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_LSECK +# define STM32_UART5_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported UART5 Clock Selection" +#endif + +#define STM32_UART5_RCC_REG STM32_RCC_APB1LENR +#define STM32_UART5_RCC_EN RCC_APB1LENR_UART5EN + +#if !defined(STM32_RCC_CCIPR1_USART6SEL) || \ + STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_RCCPCLK1 +# define STM32_USART6_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_PLL2QCK +# define STM32_USART6_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_PLL3QCK +# define STM32_USART6_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_HSIKERCK +# define STM32_USART6_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_CSIKERCK +# define STM32_USART6_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_LSECK +# define STM32_USART6_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported USART6 Clock Selection" +#endif + +#define STM32_USART6_RCC_REG STM32_RCC_APB1LENR +#define STM32_USART6_RCC_EN RCC_APB1LENR_USART6EN + +#if !defined(STM32_RCC_CCIPR1_UART7SEL) || \ + STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_RCCPCLK1 +# define STM32_UART7_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_PLL2QCK +# define STM32_UART7_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_PLL3QCK +# define STM32_UART7_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_HSIKERCK +# define STM32_UART7_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_CSIKERCK +# define STM32_UART7_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_LSECK +# define STM32_UART7_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported UART7 Clock Selection" +#endif + +#define STM32_UART7_RCC_REG STM32_RCC_APB1LENR +#define STM32_UART7_RCC_EN RCC_APB1LENR_UART7EN + +#if !defined(STM32_RCC_CCIPR1_UART8SEL) || \ + STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_RCCPCLK1 +# define STM32_UART8_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_PLL2QCK +# define STM32_UART8_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_PLL3QCK +# define STM32_UART8_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_HSIKERCK +# define STM32_UART8_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_CSIKERCK +# define STM32_UART8_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_LSECK +# define STM32_UART8_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported UART8 Clock Selection" +#endif + +#define STM32_UART8_RCC_REG STM32_RCC_APB1LENR +#define STM32_UART8_RCC_EN RCC_APB1LENR_UART8EN + +#if !defined(STM32_RCC_CCIPR1_UART9SEL) || \ + STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_RCCPCLK1 +# define STM32_UART9_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_PLL2QCK +# define STM32_UART9_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_PLL3QCK +# define STM32_UART9_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_HSIKERCK +# define STM32_UART9_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_CSIKERCK +# define STM32_UART9_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_LSECK +# define STM32_UART9_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported UART9 Clock Selection" +#endif + +#define STM32_UART9_RCC_REG STM32_RCC_APB1HENR +#define STM32_UART9_RCC_EN RCC_APB1HENR_UART9EN + +#if !defined(STM32_RCC_CCIPR1_USART10SEL) || \ + STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_RCCPCLK1 +# define STM32_USART10_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_PLL2QCK +# define STM32_USART10_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_PLL3QCK +# define STM32_USART10_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_HSIKERCK +# define STM32_USART10_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_CSIKERCK +# define STM32_USART10_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_LSECK +# define STM32_USART10_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported USART10 Clock Selection" +#endif + +#define STM32_USART10_RCC_REG STM32_RCC_APB1LENR +#define STM32_USART10_RCC_EN RCC_APB1LENR_USART10EN + +#if !defined(STM32_RCC_CCIPR2_USART11SEL) || \ + STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_RCCPCLK1 +# define STM32_USART11_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_PLL2QCK +# define STM32_USART11_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_PLL3QCK +# define STM32_USART11_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_HSIKERCK +# define STM32_USART11_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_CSIKERCK +# define STM32_USART11_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_LSECK +# define STM32_USART11_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported USART11 Clock Selection" +#endif + +#define STM32_USART11_RCC_REG STM32_RCC_APB1LENR +#define STM32_USART11_RCC_EN RCC_APB1LENR_USART11EN + +#if !defined(STM32_RCC_CCIPR2_UART12SEL) || \ + STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_RCCPCLK1 +# define STM32_UART12_FREQUENCY STM32_PCLK1_FREQUENCY +#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_PLL2QCK +# define STM32_UART12_FREQUENCY STM32_PLL2Q_FREQUENCY +#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_PLL3QCK +# define STM32_UART12_FREQUENCY STM32_PLL3Q_FREQUENCY +#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_HSIKERCK +# define STM32_UART12_FREQUENCY STM32_HSI_FREQUENCY +#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_CSIKERCK +# define STM32_UART12_FREQUENCY STM32_CSI_FREQUENCY +#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_LSECK +# define STM32_UART12_FREQUENCY STM32_LSE_FREQUENCY +#else +# error "Unsupported UART12 Clock Selection" +#endif + +#define STM32_UART12_RCC_REG STM32_RCC_APB1HENR +#define STM32_UART12_RCC_EN RCC_APB1HENR_UART12EN + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/arch/arm/src/stm32h5/stm32_serial.c b/arch/arm/src/stm32h5/stm32_serial.c deleted file mode 100644 index 08dc366471f..00000000000 --- a/arch/arm/src/stm32h5/stm32_serial.c +++ /dev/null @@ -1,4481 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h5/stm32_serial.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_SERIAL_TERMIOS -# include -#endif - -#include - -#include "chip.h" -#include "stm32_gpio.h" -#include "stm32_uart.h" -#include "stm32_dma.h" - -#include "stm32_rcc.h" -#include "arm_internal.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Some sanity checks *******************************************************/ - -/* DMA configuration */ - -/* If DMA is enabled on any USART, then very that other pre-requisites - * have also been selected. - * UART DMA1 DMA2 - * 1 X X - * 2 X - * 3 X - * 4 X - * 5 X - */ - -#ifdef CONFIG_SERIAL_IFLOWCONTROL -# warning STM32H5 Serial IFLOWCONTROL is untested -#endif - -#ifdef SERIAL_HAVE_DMA - -/* Verify that DMA has been enabled and the DMA channel has been defined. - */ - -#if !defined(CONFIG_STM32_DMA1) && !defined(CONFIG_STM32_DMA2) -# error STM32H5 Serial DMA requires one of DMA1 or DMA2 to be enabled -#endif - -/* Currently RS-485 support cannot be enabled when RXDMA is in use due to - * lack of testing - RS-485 support was developed on STM32F1x - */ - -# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ - (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ - (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ - (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ - (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) -# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" -# endif - -/* The DMA buffer size when using RX DMA to emulate a FIFO. - * - * When streaming data, the generic serial layer will be called - * every time the FIFO receives half this number of bytes. - * - * If there ever is a STM32H5 with D-cache, the buffer size - * should be an even multiple of ARMV7M_DCACHE_LINESIZE, so that it - * can be individually invalidated. - */ - -# if !defined(CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE) || \ - CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE == 0 -# define RXDMA_BUFFER_SIZE 32 -# else -# define RXDMA_BUFFER_SIZE ((CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE + 31) & ~31) -# endif - -#endif - -/* Power management definitions */ - -#if defined(CONFIG_PM) && !defined(CONFIG_STM32_PM_SERIAL_ACTIVITY) -# define CONFIG_STM32_PM_SERIAL_ACTIVITY 10 -#endif - -/* USART Unconfigure bits */ - -#define USART_UNCONFIGURE_RX (1 << 0) -#define USART_UNCONFIGURE_TX (1 << 1) -#define USART_UNCONFIGURE_DIR (1 << 2) - -/* Keep track if a Break was set - * - * Note: - * - * 1) This value is set in the priv->ie but never written to the control - * register. It must not collide with USART_CR1_USED_INTS or USART_CR3_EIE - * 2) USART_CR3_EIE is also carried in the up_dev_s ie member. - * - * See stm32serial_restoreusartint where the masking is done. - */ - -#ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT -# define USART_CR1_IE_BREAK_INPROGRESS_SHFTS 15 -# define USART_CR1_IE_BREAK_INPROGRESS (1 << USART_CR1_IE_BREAK_INPROGRESS_SHFTS) -#endif - -#ifdef USE_SERIALDRIVER -#ifdef HAVE_UART - -#if !defined STM32_RCC_CCIPR1_USART1SEL || STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_RCCPCLK2 -# define STM32_USART1_FREQUENCY STM32_PCLK2_FREQUENCY -#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_PLL2QCK -# define STM32_USART1_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_PLL3QCK -# define STM32_USART1_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_HSIKERCK -# define STM32_USART1_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_CSIKERCK -# define STM32_USART1_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART1SEL == RCC_CCIPR1_USART1SEL_LSECK -# define STM32_USART1_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported USART1 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_USART2SEL || STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_RCCPCLK1 -# define STM32_USART2_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_PLL2QCK -# define STM32_USART2_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_PLL3QCK -# define STM32_USART2_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_HSIKERCK -# define STM32_USART2_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_CSIKERCK -# define STM32_USART2_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART2SEL == RCC_CCIPR1_USART2SEL_LSECK -# define STM32_USART2_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported USART2 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_USART3SEL || STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_RCCPCLK1 -# define STM32_USART3_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_PLL2QCK -# define STM32_USART3_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_PLL3QCK -# define STM32_USART3_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_HSIKERCK -# define STM32_USART3_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_CSIKERCK -# define STM32_USART3_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART3SEL == RCC_CCIPR1_USART3SEL_LSECK -# define STM32_USART3_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported USART3 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_UART4SEL || STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_RCCPCLK1 -# define STM32_UART4_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_PLL2QCK -# define STM32_UART4_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_PLL3QCK -# define STM32_UART4_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_HSIKERCK -# define STM32_UART4_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_CSIKERCK -# define STM32_UART4_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART4SEL == RCC_CCIPR1_UART4SEL_LSECK -# define STM32_UART4_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported UART4 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_UART5SEL || STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_RCCPCLK1 -# define STM32_UART5_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_PLL2QCK -# define STM32_UART5_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_PLL3QCK -# define STM32_UART5_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_HSIKERCK -# define STM32_UART5_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_CSIKERCK -# define STM32_UART5_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART5SEL == RCC_CCIPR1_UART5SEL_LSECK -# define STM32_UART5_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported UART5 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_USART6SEL || STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_RCCPCLK1 -# define STM32_USART6_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_PLL2QCK -# define STM32_USART6_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_PLL3QCK -# define STM32_USART6_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_HSIKERCK -# define STM32_USART6_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_CSIKERCK -# define STM32_USART6_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART6SEL == RCC_CCIPR1_USART6SEL_LSECK -# define STM32_USART6_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported USART6 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_UART7SEL || STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_RCCPCLK1 -# define STM32_UART7_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_PLL2QCK -# define STM32_UART7_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_PLL3QCK -# define STM32_UART7_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_HSIKERCK -# define STM32_UART7_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_CSIKERCK -# define STM32_UART7_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART7SEL == RCC_CCIPR1_UART7SEL_LSECK -# define STM32_UART7_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported UART7 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_UART8SEL || STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_RCCPCLK1 -# define STM32_UART8_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_PLL2QCK -# define STM32_UART8_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_PLL3QCK -# define STM32_UART8_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_HSIKERCK -# define STM32_UART8_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_CSIKERCK -# define STM32_UART8_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART8SEL == RCC_CCIPR1_UART8SEL_LSECK -# define STM32_UART8_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported UART8 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_UART9SEL || STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_RCCPCLK1 -# define STM32_UART9_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_PLL2QCK -# define STM32_UART9_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_PLL3QCK -# define STM32_UART9_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_HSIKERCK -# define STM32_UART9_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_CSIKERCK -# define STM32_UART9_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_UART9SEL == RCC_CCIPR1_UART9SEL_LSECK -# define STM32_UART9_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported UART9 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR1_USART10SEL || STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_RCCPCLK1 -# define STM32_USART10_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_PLL2QCK -# define STM32_USART10_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_PLL3QCK -# define STM32_USART10_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_HSIKERCK -# define STM32_USART10_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_CSIKERCK -# define STM32_USART10_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR1_USART10SEL == RCC_CCIPR1_USART10SEL_LSECK -# define STM32_USART10_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported USART10 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR2_USART11SEL || STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_RCCPCLK1 -# define STM32_USART11_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_PLL2QCK -# define STM32_USART11_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_PLL3QCK -# define STM32_USART11_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_HSIKERCK -# define STM32_USART11_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_CSIKERCK -# define STM32_USART11_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR2_USART11SEL == RCC_CCIPR2_USART11SEL_LSECK -# define STM32_USART11_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported USART11 Clock Selection" -#endif - -#if !defined STM32_RCC_CCIPR2_UART12SEL || STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_RCCPCLK1 -# define STM32_UART12_FREQUENCY STM32_PCLK1_FREQUENCY -#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_PLL2QCK -# define STM32_UART12_FREQUENCY STM32_PLL2Q_FREQUENCY -#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_PLL3QCK -# define STM32_UART12_FREQUENCY STM32_PLL3Q_FREQUENCY -#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_HSIKERCK -# define STM32_UART12_FREQUENCY STM32_HSI_FREQUENCY -#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_CSIKERCK -# define STM32_UART12_FREQUENCY STM32_CSI_FREQUENCY -#elif STM32_RCC_CCIPR2_UART12SEL == RCC_CCIPR2_UART12SEL_LSECK -# define STM32_UART12_FREQUENCY STM32_LSE_FREQUENCY -#else -# error "Unsupported UART12 Clock Selection" -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct stm32_serial_s -{ - struct uart_dev_s dev; /* Generic UART device */ - uint32_t ie; /* Saved interrupt mask bits value */ - uint32_t sr; /* Saved status bits */ - - /* Has been initialized and HW is setup. */ - - bool initialized; - -#ifdef CONFIG_PM - bool suspended; /* UART device has been suspended. */ - - /* Interrupt mask value stored before suspending for stop mode. */ - - uint16_t suspended_ie; -#endif - - /* If termios are supported, then the following fields may vary at - * runtime. - */ - -#ifdef CONFIG_SERIAL_TERMIOS - uint8_t parity; /* 0=none, 1=odd, 2=even */ - uint8_t bits; /* Number of bits (7 or 8) */ - bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ -#ifdef CONFIG_SERIAL_OFLOWCONTROL - bool oflow; /* output flow control (CTS) enabled */ -#endif - uint32_t baud; /* Configured baud */ -#else - const uint8_t parity; /* 0=none, 1=odd, 2=even */ - const uint8_t bits; /* Number of bits (7 or 8) */ - const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ -#ifdef CONFIG_SERIAL_OFLOWCONTROL - const bool oflow; /* output flow control (CTS) enabled */ -#endif - const uint32_t baud; /* Configured baud */ -#endif - const uint8_t irq; /* IRQ associated with this USART */ - const uint32_t apbclock; /* Peripheral kernel clock frequency */ - const uint32_t usartbase; /* Base address of USART registers */ - const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ - const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ -#endif -#ifdef CONFIG_SERIAL_OFLOWCONTROL - const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ -#endif - const bool iflow; /* input flow control (RTS) enabled */ - - /* RX DMA state */ - -#ifdef SERIAL_HAVE_DMA - DMA_HANDLE rxdma; /* currently-open receive DMA stream */ - bool rxenable; /* DMA-based reception en/disable */ -#ifdef CONFIG_PM - bool rxdmasusp; /* Rx DMA suspended */ -#endif - uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ - uint16_t rxdma_req; /* GPDMA Request number */ - char *const rxfifo; /* Receive DMA buffer */ -#endif - -#ifdef HAVE_RS485 - const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ - uint8_t rs485_flags; /* U[S]ART RS-485 flags - * (compatible with struct serial_rs485) - */ -#endif - const uint8_t unconfigure; /* Unconfigure pins on close */ - const bool islpuart; /* Is this device a Low Power UART? */ - spinlock_t lock; - const bool wakefromlowpower; /* Enable interrupt to wake from low power mode */ - const uint8_t wus; /* Wake from low power configuration. USART_CR3_WUS_* */ -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_UART_CONFIG -static void stm32serial_setformat(struct uart_dev_s *dev); -#endif -static int stm32serial_setup(struct uart_dev_s *dev); -static void stm32serial_shutdown(struct uart_dev_s *dev); -static int stm32serial_attach(struct uart_dev_s *dev); -static void stm32serial_detach(struct uart_dev_s *dev); -static int stm32serial_interrupt(int irq, void *context, void *arg); -static int stm32serial_ioctl(struct file *filep, - int cmd, unsigned long arg); -#ifndef SERIAL_HAVE_ONLY_DMA -static int stm32serial_receive(struct uart_dev_s *dev, - unsigned int *status); -static void stm32serial_rxint(struct uart_dev_s *dev, bool enable); -static bool stm32serial_rxavailable(struct uart_dev_s *dev); -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, - unsigned int nbuffered, bool upper); -#endif -static void stm32serial_send(struct uart_dev_s *dev, int ch); -static void stm32serial_txint(struct uart_dev_s *dev, bool enable); -static bool stm32serial_txready(struct uart_dev_s *dev); - -#ifdef SERIAL_HAVE_DMA -static int stm32serial_dmasetup(struct uart_dev_s *dev); -static void stm32serial_dmashutdown(struct uart_dev_s *dev); -static int stm32serial_dmareceive(struct uart_dev_s *dev, - unsigned int *status); -static void stm32serial_dmareenable(struct stm32_serial_s *priv); -#ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool stm32serial_dmaiflowrestart(struct stm32_serial_s *priv); -#endif -static void stm32serial_dmarxint(struct uart_dev_s *dev, bool enable); -static bool stm32serial_dmarxavailable(struct uart_dev_s *dev); - -static void stm32serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, - void *arg); -#endif - -#ifdef CONFIG_PM -static void stm32serial_setsuspend(struct uart_dev_s *dev, bool suspend); -static void stm32serial_pm_setsuspend(bool suspend); -static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); -static int stm32serial_pmprepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); -#endif - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static const struct uart_ops_s g_uart_ops = -{ - .setup = stm32serial_setup, - .shutdown = stm32serial_shutdown, - .attach = stm32serial_attach, - .detach = stm32serial_detach, - .ioctl = stm32serial_ioctl, - .receive = stm32serial_receive, - .rxint = stm32serial_rxint, - .rxavailable = stm32serial_rxavailable, -# ifdef CONFIG_SERIAL_IFLOWCONTROL - .rxflowcontrol = stm32serial_rxflowcontrol, -# endif - .send = stm32serial_send, - .txint = stm32serial_txint, - .txready = stm32serial_txready, - .txempty = stm32serial_txready, -}; -#endif - -#ifdef SERIAL_HAVE_DMA -static const struct uart_ops_s g_uart_dma_ops = -{ - .setup = stm32serial_dmasetup, - .shutdown = stm32serial_dmashutdown, - .attach = stm32serial_attach, - .detach = stm32serial_detach, - .ioctl = stm32serial_ioctl, - .receive = stm32serial_dmareceive, - .rxint = stm32serial_dmarxint, - .rxavailable = stm32serial_dmarxavailable, -# ifdef CONFIG_SERIAL_IFLOWCONTROL - .rxflowcontrol = stm32serial_rxflowcontrol, -# endif - .send = stm32serial_send, - .txint = stm32serial_txint, - .txready = stm32serial_txready, - .txempty = stm32serial_txready, -}; -#endif - -/* I/O buffers */ - -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER -static char g_lpuart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE]; -static char g_lpuart1txbuffer[CONFIG_LPUART1_TXBUFSIZE]; -# ifdef CONFIG_LPUART1_RXDMA -static char g_lpuart1rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART1_SERIALDRIVER -static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; -static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; -# ifdef CONFIG_USART1_RXDMA -static char g_usart1rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART2_SERIALDRIVER -static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; -static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; -# ifdef CONFIG_USART2_RXDMA -static char g_usart2rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART3_SERIALDRIVER -static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; -static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; -# ifdef CONFIG_USART3_RXDMA -static char g_usart3rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART4_SERIALDRIVER -static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; -static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; -# ifdef CONFIG_UART4_RXDMA -static char g_uart4rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART5_SERIALDRIVER -static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; -static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; -# ifdef CONFIG_UART5_RXDMA -static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART6_SERIALDRIVER -static char g_usart6rxbuffer[CONFIG_USART6_RXBUFSIZE]; -static char g_usart6txbuffer[CONFIG_USART6_TXBUFSIZE]; -# ifdef CONFIG_USART6_RXDMA -static char g_usart6rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART7_SERIALDRIVER -static char g_uart7rxbuffer[CONFIG_UART7_RXBUFSIZE]; -static char g_uart7txbuffer[CONFIG_UART7_TXBUFSIZE]; -# ifdef CONFIG_UART7_RXDMA -static char g_uart7rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART8_SERIALDRIVER -static char g_uart8rxbuffer[CONFIG_UART8_RXBUFSIZE]; -static char g_uart8txbuffer[CONFIG_UART8_TXBUFSIZE]; -# ifdef CONFIG_UART8_RXDMA -static char g_uart8rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART10_SERIALDRIVER -static char g_usart10rxbuffer[CONFIG_USART10_RXBUFSIZE]; -static char g_usart10txbuffer[CONFIG_USART10_TXBUFSIZE]; -# ifdef CONFIG_USART10_RXDMA -static char g_usart10rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART11_SERIALDRIVER -static char g_usart11rxbuffer[CONFIG_USART11_RXBUFSIZE]; -static char g_usart11txbuffer[CONFIG_USART11_TXBUFSIZE]; -# ifdef CONFIG_USART11_RXDMA -static char g_usart11rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART12_SERIALDRIVER -static char g_uart12rxbuffer[CONFIG_UART12_RXBUFSIZE]; -static char g_uart12txbuffer[CONFIG_UART12_TXBUFSIZE]; -# ifdef CONFIG_UART12_RXDMA -static char g_uart12rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -/* This describes the state of the STM32 USART1 ports. */ - -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER -static struct stm32_serial_s g_lpuart1priv = -{ - .dev = - { -# if CONSOLE_UART == 1 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_LPUART1_RXBUFSIZE, - .buffer = g_lpuart1rxbuffer, - }, - .xmit = - { - .size = CONFIG_LPUART1_TXBUFSIZE, - .buffer = g_lpuart1txbuffer, - }, -# ifdef CONFIG_LPUART1_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_lpuart1priv, - }, - - .islpuart = true, - .irq = STM32_IRQ_LPUART1, - .parity = CONFIG_LPUART1_PARITY, - .bits = CONFIG_LPUART1_BITS, - .stopbits2 = CONFIG_LPUART1_2STOP, - .baud = CONFIG_LPUART1_BAUD, - .apbclock = STM32_PCLK3_FREQUENCY, - .usartbase = STM32_LPUART1_BASE, - .tx_gpio = GPIO_LPUART1_TX, - .rx_gpio = GPIO_LPUART1_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_LPUART1_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_LPUART1_RTS, -# endif -# ifdef CONFIG_LPUART1_RXDMA - .rxfifo = g_lpuart1rxfifo, - .rxdma_req = GPDMA_REQ_LPUART1_RX, -# endif - -# ifdef CONFIG_USART1_RS485 - .rs485_dir_gpio = GPIO_LPUART1_RS485_DIR, -# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_LPUART1_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_LPUART1_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_LPUART1_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -}; -#endif - -#ifdef CONFIG_STM32_USART1_SERIALDRIVER -static struct stm32_serial_s g_usart1priv = -{ - .dev = - { -# if CONSOLE_UART == 2 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART1_RXBUFSIZE, - .buffer = g_usart1rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART1_TXBUFSIZE, - .buffer = g_usart1txbuffer, - }, -# ifdef CONFIG_USART1_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart1priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_USART1, - .parity = CONFIG_USART1_PARITY, - .bits = CONFIG_USART1_BITS, - .stopbits2 = CONFIG_USART1_2STOP, - .baud = CONFIG_USART1_BAUD, - .apbclock = STM32_USART1_FREQUENCY, - .usartbase = STM32_USART1_BASE, - .tx_gpio = GPIO_USART1_TX, - .rx_gpio = GPIO_USART1_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART1_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART1_RTS, -# endif -# ifdef CONFIG_USART1_RXDMA - .rxfifo = g_usart1rxfifo, - .rxdma_req = GPDMA_REQ_USART1_RX, -# endif - -# ifdef CONFIG_USART1_RS485 - .rs485_dir_gpio = GPIO_USART1_RS485_DIR, -# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_USART1_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_USART1_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_USART1_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_USART1_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART1_WUS) - .wakefromlowpower = true, - .wus = CONFIG_USART1_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 USART2 port. */ - -#ifdef CONFIG_STM32_USART2_SERIALDRIVER -static struct stm32_serial_s g_usart2priv = -{ - .dev = - { -# if CONSOLE_UART == 3 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART2_RXBUFSIZE, - .buffer = g_usart2rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART2_TXBUFSIZE, - .buffer = g_usart2txbuffer, - }, -# ifdef CONFIG_USART2_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart2priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_USART2, - .parity = CONFIG_USART2_PARITY, - .bits = CONFIG_USART2_BITS, - .stopbits2 = CONFIG_USART2_2STOP, - .baud = CONFIG_USART2_BAUD, - .apbclock = STM32_USART2_FREQUENCY, - .usartbase = STM32_USART2_BASE, - .tx_gpio = GPIO_USART2_TX, - .rx_gpio = GPIO_USART2_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART2_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART2_RTS, -# endif -# ifdef CONFIG_USART2_RXDMA - .rxfifo = g_usart2rxfifo, - .rxdma_req = GPDMA_REQ_USART2_RX, -# endif - -# ifdef CONFIG_USART2_RS485 - .rs485_dir_gpio = GPIO_USART2_RS485_DIR, -# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_USART2_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_USART2_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_USART2_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_USART2_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART2_WUS) - .wakefromlowpower = true, - .wus = CONFIG_USART2_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 USART3 port. */ - -#ifdef CONFIG_STM32_USART3_SERIALDRIVER -static struct stm32_serial_s g_usart3priv = -{ - .dev = - { -# if CONSOLE_UART == 4 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART3_RXBUFSIZE, - .buffer = g_usart3rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART3_TXBUFSIZE, - .buffer = g_usart3txbuffer, - }, -# ifdef CONFIG_USART3_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart3priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_USART3, - .parity = CONFIG_USART3_PARITY, - .bits = CONFIG_USART3_BITS, - .stopbits2 = CONFIG_USART3_2STOP, - .baud = CONFIG_USART3_BAUD, - .apbclock = STM32_USART3_FREQUENCY, - .usartbase = STM32_USART3_BASE, - .tx_gpio = GPIO_USART3_TX, - .rx_gpio = GPIO_USART3_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART3_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART3_RTS, -# endif -# ifdef CONFIG_USART3_RXDMA - .rxfifo = g_usart3rxfifo, - .rxdma_req = GPDMA_REQ_USART3_RX, -# endif - -# ifdef CONFIG_USART3_RS485 - .rs485_dir_gpio = GPIO_USART3_RS485_DIR, -# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_USART3_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_USART3_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_USART3_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_USART3_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART3_WUS) - .wakefromlowpower = true, - .wus = CONFIG_USART3_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 UART4 port. */ - -#ifdef CONFIG_STM32_UART4_SERIALDRIVER -static struct stm32_serial_s g_uart4priv = -{ - .dev = - { -# if CONSOLE_UART == 5 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART4_RXBUFSIZE, - .buffer = g_uart4rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART4_TXBUFSIZE, - .buffer = g_uart4txbuffer, - }, -# ifdef CONFIG_UART4_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart4priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_UART4, - .parity = CONFIG_UART4_PARITY, - .bits = CONFIG_UART4_BITS, - .stopbits2 = CONFIG_UART4_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART4_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART4_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART4_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART4_RTS, -# endif - .baud = CONFIG_UART4_BAUD, - .apbclock = STM32_UART4_FREQUENCY, - .usartbase = STM32_UART4_BASE, - .tx_gpio = GPIO_UART4_TX, - .rx_gpio = GPIO_UART4_RX, -# ifdef CONFIG_UART4_RXDMA - .rxfifo = g_uart4rxfifo, - .rxdma_req = GPDMA_REQ_UART4_RX, -# endif - -# ifdef CONFIG_UART4_RS485 - .rs485_dir_gpio = GPIO_UART4_RS485_DIR, -# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_UART4_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_UART4_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_UART4_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_UART4_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART4_WUS) - .wakefromlowpower = true, - .wus = CONFIG_UART4_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 UART5 port. */ - -#ifdef CONFIG_STM32_UART5_SERIALDRIVER -static struct stm32_serial_s g_uart5priv = -{ - .dev = - { -# if CONSOLE_UART == 6 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART5_RXBUFSIZE, - .buffer = g_uart5rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART5_TXBUFSIZE, - .buffer = g_uart5txbuffer, - }, -# ifdef CONFIG_UART5_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart5priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_UART5, - .parity = CONFIG_UART5_PARITY, - .bits = CONFIG_UART5_BITS, - .stopbits2 = CONFIG_UART5_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART5_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART5_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART5_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART5_RTS, -# endif - .baud = CONFIG_UART5_BAUD, - .apbclock = STM32_UART5_FREQUENCY, - .usartbase = STM32_UART5_BASE, - .tx_gpio = GPIO_UART5_TX, - .rx_gpio = GPIO_UART5_RX, -# ifdef CONFIG_UART5_RXDMA - .rxfifo = g_uart5rxfifo, - .rxdma_req = GPDMA_REQ_UART5_RX, -# endif - -# ifdef CONFIG_UART5_RS485 - .rs485_dir_gpio = GPIO_UART5_RS485_DIR, -# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_UART5_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_UART5_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_UART5_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_UART5_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART5_WUS) - .wakefromlowpower = true, - .wus = CONFIG_UART5_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 USART6 port. */ - -#ifdef CONFIG_STM32_USART6_SERIALDRIVER -static struct stm32_serial_s g_usart6priv = -{ - .dev = - { -# if CONSOLE_UART == 7 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART6_RXBUFSIZE, - .buffer = g_usart6rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART6_TXBUFSIZE, - .buffer = g_usart6txbuffer, - }, -# ifdef CONFIG_USART6_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart6priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_USART6, - .parity = CONFIG_USART6_PARITY, - .bits = CONFIG_USART6_BITS, - .stopbits2 = CONFIG_USART6_2STOP, - .baud = CONFIG_USART6_BAUD, - .apbclock = STM32_USART6_FREQUENCY, - .usartbase = STM32_USART6_BASE, - .tx_gpio = GPIO_USART6_TX, - .rx_gpio = GPIO_USART6_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART6_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART6_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART6_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART6_RTS, -# endif -# ifdef CONFIG_USART6_RXDMA - .rxfifo = g_usart6rxfifo, - .rxdma_req = GPDMA_REQ_USART6_RX, -# endif - -# ifdef CONFIG_USART6_RS485 - .rs485_dir_gpio = GPIO_USART6_RS485_DIR, -# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_USART6_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_USART6_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_USART6_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_USART6_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART6_WUS) - .wakefromlowpower = true, - .wus = CONFIG_USART6_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 UART7 port. */ - -#ifdef CONFIG_STM32_UART7_SERIALDRIVER -static struct stm32_serial_s g_uart7priv = -{ - .dev = - { -# if CONSOLE_UART == 8 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART7_RXBUFSIZE, - .buffer = g_uart7rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART7_TXBUFSIZE, - .buffer = g_uart7txbuffer, - }, -# ifdef CONFIG_UART7_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart7priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_UART7, - .parity = CONFIG_UART7_PARITY, - .bits = CONFIG_UART7_BITS, - .stopbits2 = CONFIG_UART7_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART7_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART7_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART7_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART7_RTS, -# endif - .baud = CONFIG_UART7_BAUD, - .apbclock = STM32_UART7_FREQUENCY, - .usartbase = STM32_UART7_BASE, - .tx_gpio = GPIO_UART7_TX, - .rx_gpio = GPIO_UART7_RX, -# ifdef CONFIG_UART7_RXDMA - .rxfifo = g_uart7rxfifo, - .rxdma_req = GPDMA_REQ_UART7_RX, -# endif - -# ifdef CONFIG_UART7_RS485 - .rs485_dir_gpio = GPIO_UART7_RS485_DIR, -# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_UART7_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_UART7_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_UART7_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_UART7_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART7_WUS) - .wakefromlowpower = true, - .wus = CONFIG_UART7_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 UART8 port. */ - -#ifdef CONFIG_STM32_UART8_SERIALDRIVER -static struct stm32_serial_s g_uart8priv = -{ - .dev = - { -# if CONSOLE_UART == 9 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART8_RXBUFSIZE, - .buffer = g_uart8rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART8_TXBUFSIZE, - .buffer = g_uart8txbuffer, - }, -# ifdef CONFIG_UART8_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart8priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_UART8, - .parity = CONFIG_UART8_PARITY, - .bits = CONFIG_UART8_BITS, - .stopbits2 = CONFIG_UART8_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART8_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART8_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART8_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART8_RTS, -# endif - .baud = CONFIG_UART8_BAUD, - .apbclock = STM32_UART8_FREQUENCY, - .usartbase = STM32_UART8_BASE, - .tx_gpio = GPIO_UART8_TX, - .rx_gpio = GPIO_UART8_RX, -# ifdef CONFIG_UART8_RXDMA - .rxfifo = g_uart8rxfifo, - .rxdma_req = GPDMA_REQ_UART8_RX, -# endif - -# ifdef CONFIG_UART8_RS485 - .rs485_dir_gpio = GPIO_UART8_RS485_DIR, -# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_UART8_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_UART8_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_UART8_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_UART8_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART8_WUS) - .wakefromlowpower = true, - .wus = CONFIG_UART8_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 UART9 port. */ - -#ifdef CONFIG_STM32_UART9_SERIALDRIVER -static struct stm32_serial_s g_uart9priv = -{ - .dev = - { -# if CONSOLE_UART == 10 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART9_RXBUFSIZE, - .buffer = g_uart9rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART9_TXBUFSIZE, - .buffer = g_uart9txbuffer, - }, -# ifdef CONFIG_UART9_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart9priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_UART9, - .parity = CONFIG_UART9_PARITY, - .bits = CONFIG_UART9_BITS, - .stopbits2 = CONFIG_UART9_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART9_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART9_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART9_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART9_RTS, -# endif - .baud = CONFIG_UART9_BAUD, - .apbclock = STM32_UART9_FREQUENCY, - .usartbase = STM32_UART9_BASE, - .tx_gpio = GPIO_UART9_TX, - .rx_gpio = GPIO_UART9_RX, -# ifdef CONFIG_UART9_RXDMA - .rxfifo = g_uart9rxfifo, - .rxdma_req = GPDMA_REQ_UART9_RX, -# endif - -# ifdef CONFIG_UART9_RS485 - .rs485_dir_gpio = GPIO_UART9_RS485_DIR, -# if (CONFIG_UART9_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_UART9_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_UART9_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_UART9_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_UART9_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART9_WUS) - .wakefromlowpower = true, - .wus = CONFIG_UART9_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 USART10 port. */ - -#ifdef CONFIG_STM32_USART10_SERIALDRIVER -static struct stm32_serial_s g_usart10priv = -{ - .dev = - { -# if CONSOLE_UART == 11 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART10_RXBUFSIZE, - .buffer = g_usart10rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART10_TXBUFSIZE, - .buffer = g_usart10txbuffer, - }, -# ifdef CONFIG_USART10_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart10priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_USART10, - .parity = CONFIG_USART10_PARITY, - .bits = CONFIG_USART10_BITS, - .stopbits2 = CONFIG_USART10_2STOP, - .baud = CONFIG_USART10_BAUD, - .apbclock = STM32_USART10_FREQUENCY, - .usartbase = STM32_USART10_BASE, - .tx_gpio = GPIO_USART10_TX, - .rx_gpio = GPIO_USART10_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART10_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART10_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART10_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART10_RTS, -# endif -# ifdef CONFIG_USART10_RXDMA - .rxfifo = g_usart10rxfifo, - .rxdma_req = GPDMA_REQ_USART10_RX, -# endif - -# ifdef CONFIG_USART10_RS485 - .rs485_dir_gpio = GPIO_USART10_RS485_DIR, -# if (CONFIG_USART10_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_USART10_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_USART10_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_USART10_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_USART10_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART10_WUS) - .wakefromlowpower = true, - .wus = CONFIG_USART10_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 USART11 port. */ - -#ifdef CONFIG_STM32_USART11_SERIALDRIVER -static struct stm32_serial_s g_usart11priv = -{ - .dev = - { -# if CONSOLE_UART == 12 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART11_RXBUFSIZE, - .buffer = g_usart11rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART11_TXBUFSIZE, - .buffer = g_usart11txbuffer, - }, -# ifdef CONFIG_USART11_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart11priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_USART11, - .parity = CONFIG_USART11_PARITY, - .bits = CONFIG_USART11_BITS, - .stopbits2 = CONFIG_USART11_2STOP, - .baud = CONFIG_USART11_BAUD, - .apbclock = STM32_USART11_FREQUENCY, - .usartbase = STM32_USART11_BASE, - .tx_gpio = GPIO_USART11_TX, - .rx_gpio = GPIO_USART11_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART11_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART11_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART11_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART11_RTS, -# endif -# ifdef CONFIG_USART11_RXDMA - .rxfifo = g_usart11rxfifo, - .rxdma_req = GPDMA_REQ_USART11_RX, -# endif - -# ifdef CONFIG_USART11_RS485 - .rs485_dir_gpio = GPIO_USART11_RS485_DIR, -# if (CONFIG_USART11_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_USART11_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_USART11_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_USART11_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_USART11_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART11_WUS) - .wakefromlowpower = true, - .wus = CONFIG_USART11_WUS, -#endif -}; -#endif - -/* This describes the state of the STM32 UART12 port. */ - -#ifdef CONFIG_STM32_UART12_SERIALDRIVER -static struct stm32_serial_s g_uart12priv = -{ - .dev = - { -# if CONSOLE_UART == 13 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART12_RXBUFSIZE, - .buffer = g_uart12rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART12_TXBUFSIZE, - .buffer = g_uart12txbuffer, - }, -# ifdef CONFIG_UART12_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart12priv, - }, - - .islpuart = false, - .irq = STM32_IRQ_UART12, - .parity = CONFIG_UART12_PARITY, - .bits = CONFIG_UART12_BITS, - .stopbits2 = CONFIG_UART12_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART12_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART12_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART12_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART12_RTS, -# endif - .baud = CONFIG_UART12_BAUD, - .apbclock = STM32_UART12_FREQUENCY, - .usartbase = STM32_UART12_BASE, - .tx_gpio = GPIO_UART12_TX, - .rx_gpio = GPIO_UART12_RX, -# ifdef CONFIG_UART12_RXDMA - .rxfifo = g_uart12rxfifo, - .rxdma_req = GPDMA_REQ_UART12_RX, -# endif - -# ifdef CONFIG_UART12_RS485 - .rs485_dir_gpio = GPIO_UART12_RS485_DIR, -# if (CONFIG_UART12_RS485_DIR_POLARITY == 0) - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, -# else - .rs485_flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, -# endif -# endif - .lock = SP_UNLOCKED, - .unconfigure = 0 -#if defined(CONFIG_UART12_UNCONFIG_RX_ON_CLOSE) - | - USART_UNCONFIGURE_RX -#endif -#if defined(CONFIG_UART12_UNCONFIG_TX_ON_CLOSE) - | - USART_UNCONFIGURE_TX -#endif -#if defined(CONFIG_UART12_UNCONFIG_DIR_ON_CLOSE) - | - USART_UNCONFIGURE_DIR -#endif - , -#if defined(CONFIG_UART12_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART12_WUS) - .wakefromlowpower = true, - .wus = CONFIG_UART12_WUS, -#endif -}; -#endif - -/* This table lets us iterate over the configured USARTs */ - -static struct stm32_serial_s * const - g_uart_devs[STM32_NLPUART + STM32_NUSART + STM32_NUART] = -{ -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER - [0] = &g_lpuart1priv, -#endif -#ifdef CONFIG_STM32_USART1_SERIALDRIVER - [1] = &g_usart1priv, -#endif -#ifdef CONFIG_STM32_USART2_SERIALDRIVER - [2] = &g_usart2priv, -#endif -#ifdef CONFIG_STM32_USART3_SERIALDRIVER - [3] = &g_usart3priv, -#endif -#ifdef CONFIG_STM32_UART4_SERIALDRIVER - [4] = &g_uart4priv, -#endif -#ifdef CONFIG_STM32_UART5_SERIALDRIVER - [5] = &g_uart5priv, -#endif -#ifdef CONFIG_STM32_USART6_SERIALDRIVER - [6] = &g_usart6priv, -#endif -#ifdef CONFIG_STM32_UART7_SERIALDRIVER - [7] = &g_uart7priv, -#endif -#ifdef CONFIG_STM32_UART8_SERIALDRIVER - [8] = &g_uart8priv, -#endif -#ifdef CONFIG_STM32_UART9_SERIALDRIVER - [9] = &g_uart9priv, -#endif -#ifdef CONFIG_STM32_USART10_SERIALDRIVER - [10] = &g_usart10priv, -#endif -#ifdef CONFIG_STM32_USART11_SERIALDRIVER - [11] = &g_usart11priv, -#endif -#ifdef CONFIG_STM32_UART12_SERIALDRIVER - [12] = &g_uart12priv, -#endif -}; - -#ifdef CONFIG_PM -struct serialpm_s -{ - struct pm_callback_s pm_cb; - bool serial_suspended; -}; - -static struct serialpm_s g_serialpm = -{ - .pm_cb.notify = stm32serial_pmnotify, - .pm_cb.prepare = stm32serial_pmprepare, - .serial_suspended = false -}; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32serial_getreg - ****************************************************************************/ - -static inline -uint32_t stm32serial_getreg(struct stm32_serial_s *priv, int offset) -{ - return getreg32(priv->usartbase + offset); -} - -/**************************************************************************** - * Name: stm32serial_putreg - ****************************************************************************/ - -static inline -void stm32serial_putreg(struct stm32_serial_s *priv, - int offset, uint32_t value) -{ - putreg32(value, priv->usartbase + offset); -} - -/**************************************************************************** - * Name: stm32serial_setusartint - ****************************************************************************/ - -static inline -void stm32serial_setusartint(struct stm32_serial_s *priv, - uint16_t ie) -{ - uint32_t cr; - - /* Save the interrupt mask */ - - priv->ie = ie; - - /* And restore the interrupt state (see the interrupt enable/usage table - * above) - */ - - cr = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr &= ~(USART_CR1_USED_INTS); - cr |= (ie & (USART_CR1_USED_INTS)); - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr); - - cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - cr &= ~USART_CR3_EIE; - cr |= (ie & USART_CR3_EIE); - stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, cr); -} - -/**************************************************************************** - * Name: up_restoreusartint - ****************************************************************************/ - -static void stm32serial_restoreusartint(struct stm32_serial_s *priv, - uint16_t ie) -{ - irqstate_t flags; - - flags = spin_lock_irqsave(&priv->lock); - - stm32serial_setusartint(priv, ie); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/**************************************************************************** - * Name: stm32serial_disableusartint - ****************************************************************************/ - -static void stm32serial_disableusartint(struct stm32_serial_s *priv, - uint16_t *ie) -{ - irqstate_t flags; - - flags = spin_lock_irqsave(&priv->lock); - - if (ie) - { - uint32_t cr1; - uint32_t cr3; - - /* USART interrupts: - * - * Enable Status Meaning Usage - * ---------------- -------------- ---------------------- ------------- - * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) - * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to - * be Read - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only RS-485) - * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register - * Empty - * USART_CR1_PEIE USART_ISR_PE Parity Error - * - * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) - * USART_CR3_EIE USART_ISR_FE Framing Error - * " " USART_ISR_NF Noise Flag - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) - */ - - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr3 = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - - /* Return the current interrupt mask value for the used interrupts. - * Notice that this depends on the fact that none of the used interrupt - * enable bits overlap. This logic would fail if we needed the break - * interrupt! - */ - - *ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); - } - - /* Disable all interrupts */ - - stm32serial_setusartint(priv, 0); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/**************************************************************************** - * Name: stm32serial_dmanextrx - * - * Description: - * Returns the index into the RX FIFO where the DMA will place the next - * byte that it receives. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static int stm32serial_dmanextrx(struct stm32_serial_s *priv) -{ - size_t dmaresidual; - - dmaresidual = stm32_dmaresidual(priv->rxdma); - - return (RXDMA_BUFFER_SIZE - (int)dmaresidual); -} -#endif - -/**************************************************************************** - * Name: stm32serial_setformat - * - * Description: - * Set the serial line format and speed. - * - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_UART_CONFIG -static void stm32serial_setformat(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t regval; - uint32_t brr; - uint32_t cr1; - - /* This first implementation is for U[S]ARTs that support oversampling - * by 8 in additional to the standard oversampling by 16. - */ -#ifdef CONFIG_STM32_LPUART1 - if (priv->islpuart == true) - { - /* LPUART BRR (19:00) = (256*apbclock_hz/baud_rate) */ - - uint32_t apbclock_whole = priv->apbclock; - uint32_t clock_baud_ratio = apbclock_whole / priv->baud; - uint32_t presc_reg = 0x0; - - /* LPUART PRESC (3:0) - * Divide the apbclock if necessary for low baud rates - * 3 * baud_rate <= apbclock_whole <= 4096 * baud_rate - */ - - if (clock_baud_ratio <= 4096) - { - presc_reg = 0x0; - } - else if (clock_baud_ratio > 4096 && clock_baud_ratio <= 8192) - { - presc_reg = 0x1; - apbclock_whole >>= 1; - } - else if (clock_baud_ratio > 8192 && clock_baud_ratio <= 16384) - { - presc_reg = 0x2; - apbclock_whole >>= 2; - } - else if (clock_baud_ratio > 16384 && clock_baud_ratio <= 24576) - { - presc_reg = 0x3; - apbclock_whole /= 6; - } - else if (clock_baud_ratio > 24576 && clock_baud_ratio <= 32768) - { - presc_reg = 0x4; - apbclock_whole >>= 3; - } - else if (clock_baud_ratio > 32768 && clock_baud_ratio <= 40960) - { - presc_reg = 0x5; - apbclock_whole /= 10; - } - else if (clock_baud_ratio > 40960 && clock_baud_ratio <= 49152) - { - presc_reg = 0x6; - apbclock_whole /= 12; - } - else if (clock_baud_ratio > 32768 && clock_baud_ratio <= 65536) - { - presc_reg = 0x7; - apbclock_whole >>= 4; - } - else if (clock_baud_ratio > 65536 && clock_baud_ratio <= 131072) - { - presc_reg = 0x8; - apbclock_whole >>= 5; - } - else if (clock_baud_ratio > 131072 && clock_baud_ratio <= 262144) - { - presc_reg = 0x9; - apbclock_whole >>= 6; - } - else if (clock_baud_ratio > 262144 && clock_baud_ratio <= 524288) - { - presc_reg = 0xa; - apbclock_whole >>= 7; - } - else - { - presc_reg = 0xb; - apbclock_whole >>= 8; - } - - /* Write the PRESC register */ - - stm32serial_putreg(priv, STM32_USART_PRESC_OFFSET, presc_reg); - - /* Set the LPUART BRR value after setting Prescaler - * BRR = ( (256 * apbclock_whole) + baud_rate / 2 ) / baud_rate - */ - - brr = (((uint64_t)apbclock_whole << 8) + (priv->baud >> 1)) / \ - priv->baud; - } - else -#endif /* CONFIG_STM32_LPUART1 */ - { - uint32_t usartdiv8; - - /* In case of oversampling by 8, the equation is: - * - * baud = 2 * fCK / usartdiv8 - * usartdiv8 = 2 * fCK / baud - */ - - usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; - - /* Baud rate for standard USART (SPI mode included): - * - * In case of oversampling by 16, the equation is: - * baud = fCK / usartdiv16 - * usartdiv16 = fCK / baud - * = 2 * usartdiv8 - */ - - /* Use oversamply by 8 only if divisor is small. But what is small? */ - - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - if (usartdiv8 > 2000) - { - /* Use usartdiv16 */ - - brr = (usartdiv8 + 1) >> 1; - - /* Clear oversampling by 8 to enable oversampling by 16 */ - - cr1 &= ~USART_CR1_OVER8; - } - else - { - DEBUGASSERT(usartdiv8 >= 8); - - /* Perform mysterious operations on bits 0-3 */ - - brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); - - /* Set oversampling by 8 */ - - cr1 |= USART_CR1_OVER8; - } - } - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - stm32serial_putreg(priv, STM32_USART_BRR_OFFSET, brr); - - /* Configure parity mode */ - - regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); - - if (priv->parity == 1) /* Odd parity */ - { - regval |= (USART_CR1_PCE | USART_CR1_PS); - } - else if (priv->parity == 2) /* Even parity */ - { - regval |= USART_CR1_PCE; - } - - /* Configure word length (parity uses one of configured bits) - * - * Default: 1 start, 8 data (no parity), n stop, OR - * 1 start, 7 data + parity, n stop - */ - - if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) - { - /* Select: 1 start, 8 data + parity, n stop, OR - * 1 start, 9 data (no parity), n stop. - */ - - regval |= USART_CR1_M0; - } - else if (priv->bits == 7 && priv->parity == 0) - { - /* Select: 1 start, 7 data (no parity), n stop, OR - */ - - regval |= USART_CR1_M1; - } - - /* Else Select: 1 start, 7 data + parity, n stop, OR - * 1 start, 8 data (no parity), n stop. - */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - - /* Configure STOP bits */ - - regval = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); - regval &= ~(USART_CR2_STOP_MASK); - - if (priv->stopbits2) - { - regval |= USART_CR2_STOP2; - } - - stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, regval); - - /* Configure hardware flow control */ - - regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); - -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32_FLOWCONTROL_BROKEN) - if (priv->iflow && (priv->rts_gpio != 0)) - { - regval |= USART_CR3_RTSE; - } -#endif - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->oflow && (priv->cts_gpio != 0)) - { - regval |= USART_CR3_CTSE; - } -#endif - - stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); -} -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ - -/**************************************************************************** - * Name: stm32serial_setsuspend - * - * Description: - * Suspend or resume serial peripheral. - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void stm32serial_setsuspend(struct uart_dev_s *dev, bool suspend) -{ - struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; -#ifdef SERIAL_HAVE_DMA - bool dmarestored = false; -#endif - - if (priv->suspended == suspend) - { - return; - } - - priv->suspended = suspend; - - if (suspend) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Force RTS high to prevent further Rx. */ - - stm32_configgpio((priv->rts_gpio & ~GPIO_MODE_MASK) - | (GPIO_OUTPUT | GPIO_OUTPUT_SET)); - } -#endif - - /* Disable interrupts to prevent Tx. */ - - stm32serial_disableusartint(priv, &priv->suspended_ie); - - /* Wait last Tx to complete. */ - - while ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & - USART_ISR_TC) == 0); - -#ifdef SERIAL_HAVE_DMA - if (priv->dev.ops == &g_uart_dma_ops && !priv->rxdmasusp) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow && priv->rxdmanext == RXDMA_BUFFER_SIZE) - { - /* Rx DMA in non-circular iflow mode and already stopped - * at end of DMA buffer. No need to suspend. - */ - } - else -#endif - { - /* Suspend Rx DMA. */ - - stm32h5_dmastop(priv->rxdma); - priv->rxdmasusp = true; - } - } -#endif - } - else - { -#ifdef SERIAL_HAVE_DMA - if (priv->dev.ops == &g_uart_dma_ops && priv->rxdmasusp) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - stm32serial_dmaiflowrestart(priv); - } - else -#endif - { - /* This USART does not have HW flow-control. Unconditionally - * re-enable DMA (might loss unprocessed bytes received - * to DMA buffer before suspending). - */ - - stm32serial_dmareenable(priv); - priv->rxdmasusp = false; - } - - dmarestored = true; - } -#endif - - /* Re-enable interrupts to resume Tx. */ - - stm32serial_restoreusartint(priv, priv->suspended_ie); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Restore peripheral RTS control. */ - - stm32_configgpio(priv->rts_gpio); - } -#endif - } - -#ifdef SERIAL_HAVE_DMA - if (dmarestored) - { - irqstate_t flags; - - flags = enter_critical_section(); - - /* Perform initial Rx DMA buffer fetch to wake-up serial device - * activity. - */ - - if (priv->rxdma != NULL) - { - stm32serial_dmarxcallback(priv->rxdma, 0, priv); - } - - leave_critical_section(flags); - } -#endif -} -#endif - -/**************************************************************************** - * Name: stm32serial_pm_setsuspend - * - * Description: - * Suspend or resume serial peripherals for/from deep-sleep/stop modes. - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void stm32serial_pm_setsuspend(bool suspend) -{ - int n; - - /* Already in desired state? */ - - if (suspend == g_serialpm.serial_suspended) - { - return; - } - - g_serialpm.serial_suspended = suspend; - - for (n = 0; n < STM32_NLPUART + STM32_NUSART + STM32_NUART; n++) - { - struct stm32_serial_s *priv = g_uart_devs[n]; - - if (!priv || !priv->initialized) - { - continue; - } - - stm32serial_setsuspend(&priv->dev, suspend); - } -} -#endif - -/**************************************************************************** - * Name: stm32serial_setapbclock - * - * Description: - * Enable or disable APB clock for the USART peripheral - * - * Input Parameters: - * dev - A reference to the UART driver state structure - * on - Enable clock if 'on' is 'true' and disable if 'false' - * - ****************************************************************************/ - -static void stm32serial_setapbclock(struct uart_dev_s *dev, bool on) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t rcc_en; - uint32_t regaddr; - - /* Determine which USART to configure */ - - switch (priv->usartbase) - { - default: - return; -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER - case STM32_LPUART1_BASE: - rcc_en = RCC_APB3ENR_LPUART1EN ; - regaddr = STM32_RCC_APB3ENR; - break; -#endif -#ifdef CONFIG_STM32_USART1_SERIALDRIVER - case STM32_USART1_BASE: - rcc_en = RCC_APB2ENR_USART1EN ; - regaddr = STM32_RCC_APB2ENR; - break; -#endif -#ifdef CONFIG_STM32_USART2_SERIALDRIVER - case STM32_USART2_BASE: - rcc_en = RCC_APB1LENR_USART2EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_USART3_SERIALDRIVER - case STM32_USART3_BASE: - rcc_en = RCC_APB1LENR_USART3EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_UART4_SERIALDRIVER - case STM32_UART4_BASE: - rcc_en = RCC_APB1LENR_UART4EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_UART5_SERIALDRIVER - case STM32_UART5_BASE: - rcc_en = RCC_APB1LENR_UART5EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_USART6_SERIALDRIVER - case STM32_USART6_BASE: - rcc_en = RCC_APB1LENR_USART6EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_UART7_SERIALDRIVER - case STM32_UART7_BASE: - rcc_en = RCC_APB1LENR_UART7EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_UART8_SERIALDRIVER - case STM32_UART8_BASE: - rcc_en = RCC_APB1LENR_UART8EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_UART9_SERIALDRIVER - case STM32_UART9_BASE: - rcc_en = RCC_APB1HENR_UART9EN; - regaddr = STM32_RCC_APB1HENR; - break; -#endif - -#ifdef CONFIG_STM32_USART10_SERIALDRIVER - case STM32_USART10_BASE: - rcc_en = RCC_APB1LENR_USART10EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_USART11_SERIALDRIVER - case STM32_USART11_BASE: - rcc_en = RCC_APB1LENR_USART11EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32_UART12_SERIALDRIVER - case STM32_UART12_BASE: - rcc_en = RCC_APB1HENR_UART12EN; - regaddr = STM32_RCC_APB1HENR; - break; -#endif - } - - /* Enable/disable APB 1/2 clock for USART */ - - if (on) - { - modifyreg32(regaddr, 0, rcc_en); - } - else - { - modifyreg32(regaddr, rcc_en, 0); - } -} - -/**************************************************************************** - * Name: stm32serial_setup - * - * Description: - * Configure the USART baud, bits, parity, etc. This method is called the - * first time that the serial port is opened. - * - ****************************************************************************/ - -static int stm32serial_setup(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - -#ifndef CONFIG_SUPPRESS_UART_CONFIG - uint32_t regval; - - /* Note: The logic here depends on the fact that that the USART module - * was enabled in stm32_lowsetup(). - */ - - /* Enable USART APB1/2 clock */ - - stm32serial_setapbclock(dev, true); - - /* Configure pins for USART use */ - - if (priv->tx_gpio != 0) - { - stm32_configgpio(priv->tx_gpio); - } - - if (priv->rx_gpio != 0) - { - stm32_configgpio(priv->rx_gpio); - } - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->cts_gpio != 0) - { - stm32_configgpio(priv->cts_gpio); - } -#endif - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->rts_gpio != 0) - { - uint32_t config = priv->rts_gpio; - -#ifdef CONFIG_STM32_FLOWCONTROL_BROKEN - /* Instead of letting hw manage this pin, we will bitbang */ - - config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; -#endif - stm32_configgpio(config); - } -#endif - -#ifdef HAVE_RS485 - if ((priv->rs485_flags & SER_RS485_ENABLED) != 0) - { - stm32_configgpio(priv->rs485_dir_gpio); - stm32_gpiowrite(priv->rs485_dir_gpio, - (bool) (priv->rs485_flags & SER_RS485_RTS_AFTER_SEND)); - } -#endif - - /* Configure CR2 */ - - /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ - - regval = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); - if (priv->islpuart == true) - { - regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN); - } - else - { - regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | - USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); - } - - /* Configure STOP bits */ - - if (priv->stopbits2) - { - regval |= USART_CR2_STOP2; - } - - stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, regval); - - /* Configure CR1 */ - - /* Clear UE, TE, RE, and all interrupt enable bits */ - - regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - -#ifdef CONFIG_STM32_LPUART1 - if (priv->islpuart == true) - { - regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | - LPUART_CR1_ALLINTS); - } - else -#endif - { - regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | - USART_CR1_ALLINTS); - } - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - - /* Configure CR3 */ - - /* Clear CTSE, RTSE, and all interrupt enable bits */ - - regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | - USART_CR3_EIE | USART_CR3_WUFIE); - - if (priv->wakefromlowpower) - { - regval |= USART_CR3_WUFIE; - regval |= (priv->wus << USART_CR3_WUS_SHIFT); - } - - stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); - - /* Configure the USART line format and speed. */ - - stm32serial_setformat(dev); - - /* Enable Rx, Tx, and the USART */ - - regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | - USART_CR1_FIFOEN); - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ - - /* Set up the cached interrupt enables value */ - - priv->ie = 0; - - /* Mark device as initialized. */ - - priv->initialized = true; - - return OK; -} - -/**************************************************************************** - * Name: serial_rxdmacfg - * - * Description: - * Generate the required DMA configuration structure for oneshot mode based - * on the serial configuration. - * - * Input Parameters: - * priv - serial instance structure - * cfg - DMA configuration structure - * circular - 0 = oneshot, 1 = circular - * - * Returned Value: - * None - ****************************************************************************/ - - #ifdef SERIAL_HAVE_DMA -static void serial_rxdmacfg(struct stm32_serial_s *priv, - struct stm32_gpdma_cfg_s *cfg) -{ - cfg->src_addr = priv->usartbase + STM32_USART_RDR_OFFSET; - cfg->dest_addr = (uint32_t)priv->rxfifo; - - cfg->request = priv->rxdma_req; - - cfg->priority = GPMDACFG_PRIO_LH; - - cfg->mode = GPDMACFG_MODE_CIRC; - - cfg->ntransfers = RXDMA_BUFFER_SIZE; - - /* Write SDW and DDW to 0 for 8-bit beats */ - - cfg->tr1 = GPDMA_CXTR1_DINC; /* dest-inc, source fixed */ -} -#endif - -/**************************************************************************** - * Name: stm32serial_dmasetup - * - * Description: - * Configure and start circular RX DMA for USART: - * - Allocate a GPDMA channel - * - Set up source (USART RDR), destination (RX buffer), REQSEL, - * circular mode - * - Program DMA and reset read index - * - Enable USART CR3.DMAR - * - Start DMA with half‑ and full‑transfer callbacks - * - * Returned Value: - * OK on success; negative errno on failure. - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static int stm32serial_dmasetup(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; - struct stm32_gpdma_cfg_s dmacfg; - uint32_t regval; - int ret; - - if (!dev->isconsole) - { - ret = stm32serial_setup(dev); - if (ret != OK) - { - return ret; - } - } - - priv->rxdma = stm32_dmachannel(GPDMA_TTYPE_P2M); - if (!priv->rxdma) - { - return -EBUSY; - } - - serial_rxdmacfg(priv, &dmacfg); - - stm32_dmasetup(priv->rxdma, &dmacfg); - - priv->rxdmanext = 0; - - regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - regval |= USART_CR3_DMAR; - stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Start the DMA channel, and arrange for callbacks at the full point - * in the FIFO. After buffer gets full, hardware flow-control kicks - * in and DMA transfer is stopped. - */ - - stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, - (void *)priv, false); - } - else -#endif - { - /* Start the DMA channel, and arrange for callbacks at the half and - * full points in the FIFO. This ensures that we have half a FIFO - * worth of time to claim bytes before they are overwritten. - */ - - stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, - (void *)priv, true); - } - - return OK; -} -#endif - -/**************************************************************************** - * Name: stm32serial_shutdown - * - * Description: - * Disable the USART. This method is called when the serial - * port is closed - * - ****************************************************************************/ - -static void stm32serial_shutdown(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t regval; - - /* Mark device as uninitialized. */ - - priv->initialized = false; - - /* Disable all interrupts */ - - stm32serial_disableusartint(priv, NULL); - - /* Disable USART APB1/2 clock */ - - stm32serial_setapbclock(dev, false); - - /* Disable Rx, Tx, and the UART */ - - regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - - /* Release pins. "If the serial-attached device is powered down, the TX - * pin causes back-powering, potentially confusing the device to the point - * of complete lock-up." - * - * REVISIT: Is unconfiguring the pins appropriate for all device? If not, - * then this may need to be a configuration option. - */ - - if ((priv->unconfigure & USART_UNCONFIGURE_TX) && (priv->tx_gpio != 0)) - { - stm32_unconfiggpio(priv->tx_gpio); - } - - if ((priv->unconfigure & USART_UNCONFIGURE_RX) && (priv->rx_gpio != 0)) - { - stm32_unconfiggpio(priv->rx_gpio); - } - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->cts_gpio != 0) - { - stm32_unconfiggpio(priv->cts_gpio); - } -#endif - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->rts_gpio != 0) - { - stm32_unconfiggpio(priv->rts_gpio); - } -#endif - -#ifdef HAVE_RS485 - if ((priv->rs485_dir_gpio != 0) && - (priv->unconfigure & USART_UNCONFIGURE_DIR)) - { - stm32_unconfiggpio(priv->rs485_dir_gpio); - } -#endif -} - -/**************************************************************************** - * Name: stm32serial_dmashutdown - * - * Description: - * Disable the USART. This method is called when the serial - * port is closed - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static void stm32serial_dmashutdown(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - /* Perform the normal UART shutdown */ - - stm32serial_shutdown(dev); - - /* Stop the DMA channel */ - - stm32_dmastop(priv->rxdma); - - priv->rxenable = false; - - /* Release the DMA channel */ - - stm32_dmafree(priv->rxdma); - priv->rxdma = NULL; -} -#endif - -/**************************************************************************** - * Name: stm32serial_attach - * - * Description: - * Configure the USART to operation in interrupt driven mode. This method - * is called when the serial port is opened. Normally, this is just after - * the setup() method is called, however, the serial console may operate in - * a non-interrupt driven mode during the boot phase. - * - * RX and TX interrupts are not enabled when by the attach method (unless - * the hardware supports multiple levels of interrupt enabling). The RX - * and TX interrupts are not enabled until the txint() and rxint() methods - * are called. - * - ****************************************************************************/ - -static int stm32serial_attach(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - int ret; - - /* Attach and enable the IRQ */ - - ret = irq_attach(priv->irq, stm32serial_interrupt, priv); - - if (ret == OK) - { - /* Enable the interrupt (RX and TX interrupts are still disabled - * in the USART - */ - - up_enable_irq(priv->irq); - } - - return ret; -} - -/**************************************************************************** - * Name: stm32serial_detach - * - * Description: - * Detach USART interrupts. This method is called when the serial port is - * closed normally just before the shutdown method is called. The - * exception is the serial console which is never shutdown. - * - ****************************************************************************/ - -static void stm32serial_detach(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - up_disable_irq(priv->irq); - irq_detach(priv->irq); -} - -/**************************************************************************** - * Name: stm32serial_interrupt - * - * Description: - * This is the USART interrupt handler. It will be invoked when an - * interrupt is received on the 'irq'. It should call uart_xmitchars or - * uart_recvchars to perform the appropriate data transfers. The - * interrupt handling logic must be able to map the 'arg' to the - * appropriate uart_dev_s structure in order to call these functions. - * - ****************************************************************************/ - -static int stm32serial_interrupt(int irq, void *context, void *arg) -{ - struct stm32_serial_s *priv = (struct stm32_serial_s *)arg; - int passes; - bool handled; - - DEBUGASSERT(priv != NULL); - - /* Report serial activity to the power management logic */ - -#if defined(CONFIG_PM) && CONFIG_STM32_PM_SERIAL_ACTIVITY > 0 - pm_activity(PM_IDLE_DOMAIN, CONFIG_STM32_PM_SERIAL_ACTIVITY); -#endif - - /* Loop until there are no characters to be transferred or, - * until we have been looping for a long time. - */ - - handled = true; - for (passes = 0; passes < 256 && handled; passes++) - { - handled = false; - - /* Get the masked USART status word. */ - - priv->sr = stm32serial_getreg(priv, STM32_USART_ISR_OFFSET); - - /* USART interrupts: - * - * Enable Status Meaning Usage - * ---------------- -------------- ---------------------- ------------- - * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) - * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to - * be Read - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only RS-485) - * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register - * Empty - * USART_CR1_PEIE USART_ISR_PE Parity Error - * - * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) - * USART_CR3_EIE USART_ISR_FE Framing Error - * " " USART_ISR_NE Noise Error - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) - * USART_CR3_WUFIE USART_ISR_WUF wake up from low power - * - * NOTE: Some of these status bits must be cleared by explicitly - * writing one to the ICR register: USART_ICR_CTSCF, USART_ICR_LBDCF. - * None of those are currently being used. - */ - -#ifdef HAVE_RS485 - /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. - * Note - this should be first, to have the most recent TC bit value - * from SR register - sending data affects TC, but without refresh we - * will not know that... - */ - - if ((priv->sr & USART_ISR_TC) != 0 && - (priv->ie & USART_CR1_TCIE) != 0 && - (priv->ie & USART_CR1_TXEIE) == 0) - { - stm32_gpiowrite(priv->rs485_dir_gpio, - (bool) (priv->rs485_flags & - SER_RS485_RTS_AFTER_SEND)); - stm32serial_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); - } -#endif - - /* Wake up from low power mode interrupt */ - - if ((priv->sr & USART_ISR_WUF) != 0) - { - stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, USART_ICR_WUCF); - } - - /* Handle incoming, receive bytes. */ - - if ((priv->sr & USART_ISR_RXNE) != 0 && - (priv->ie & USART_CR1_RXNEIE) != 0) - { - /* Received data ready... process incoming bytes. NOTE the check - * for RXNEIE: We cannot call uart_recvchards of RX interrupts are - * disabled. - */ - - uart_recvchars(&priv->dev); - handled = true; - } - - /* We may still have to read from the DR register to clear any pending - * error conditions. - */ - - else if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) - != 0) - { - /* These errors are cleared by writing the corresponding bit to the - * interrupt clear register (ICR). - */ - - stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, - (USART_ICR_NCF | USART_ICR_ORECF | - USART_ICR_FECF)); - } - - /* Handle outgoing, transmit bytes */ - - if ((priv->sr & USART_ISR_TXE) != 0 && - (priv->ie & USART_CR1_TXEIE) != 0) - { - /* Transmit data register empty ... process outgoing bytes */ - - uart_xmitchars(&priv->dev); - handled = true; - } - } - - return OK; -} - -/**************************************************************************** - * Name: stm32serial_set_rs485_mode - * - * Description: - * Handle mode set ioctl (TIOCSRS485) to enable - * and disable RS-485 mode. This is part of the serial ioctl logic. - * - * - ****************************************************************************/ - -#ifdef HAVE_RS485 -static inline int stm32serial_set_rs485_mode(struct stm32_serial_s *priv, - const struct serial_rs485 *mode) -{ - irqstate_t flags; - - DEBUGASSERT(priv && mode); - if (priv->rs485_dir_gpio == 0) - { - /* Can't configure RS485 dir pin if pin is not defined */ - - return -ENOTTY; - } - - flags = enter_critical_section(); - priv->sr = stm32serial_getreg(priv, STM32_USART_ISR_OFFSET); - - priv->rs485_flags = mode->flags & - (SER_RS485_ENABLED | - SER_RS485_RTS_ON_SEND | - SER_RS485_RTS_AFTER_SEND | - SER_RS485_RX_DURING_TX); -/* Cases: - * Enabling, serial transfer currently in progress: - * Set the pin to the transfer in progress state and let the interrupt take - * care of it - * Enabling, no serial transfer currently in progress: - * Set the pin to the no transfer in progress state. - */ - - if (mode->flags & SER_RS485_ENABLED) - { - stm32_configgpio(priv->rs485_dir_gpio); - if ((priv->sr & USART_ISR_TC) != 0) - { - /* Transmission is complete, set to "after send' state */ - - stm32_gpiowrite(priv->rs485_dir_gpio, (bool) (priv->rs485_flags & - SER_RS485_RTS_AFTER_SEND)); - } - else - { - /* Transmission is currently in progress, set to "on send" state */ - - stm32_gpiowrite(priv->rs485_dir_gpio, (bool) (priv->rs485_flags & - SER_RS485_RTS_ON_SEND)); - } - } - else - { - if (priv->unconfigure & USART_UNCONFIGURE_DIR) - { - stm32_unconfiggpio(priv->rs485_dir_gpio); - } - } - - leave_critical_section(flags); - return OK; -} -#endif - -/**************************************************************************** - * Name: stm32serial_get_rs485_mode - * - * Description: - * Handle RS485 mode get ioctl (TIOCGRS485) to get the - * current RS-485 mode. - * - ****************************************************************************/ - -#ifdef HAVE_RS485 -static inline int stm32serial_get_rs485_mode(struct stm32_serial_s *priv, - struct serial_rs485 *mode) -{ - irqstate_t flags; - - DEBUGASSERT(priv && mode); - flags = enter_critical_section(); - - /* Assume disabled */ - - memset(mode, 0, sizeof(struct serial_rs485)); - - mode->flags = priv->rs485_flags & - (SER_RS485_ENABLED | - SER_RS485_RTS_ON_SEND | - SER_RS485_RTS_AFTER_SEND | - SER_RS485_RX_DURING_TX); - - leave_critical_section(flags); - return OK; -} -#endif - -/**************************************************************************** - * Name: stm32serial_ioctl - * - * Description: - * All ioctl calls will be routed through this method - * - ****************************************************************************/ - -static int stm32serial_ioctl(struct file *filep, int cmd, - unsigned long arg) -{ - struct inode *inode = filep->f_inode; - struct uart_dev_s *dev = inode->i_private; - struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; - int ret = OK; - - UNUSED(inode); - UNUSED(dev); - UNUSED(priv); - - switch (cmd) - { -#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT - case TIOCSERGSTRUCT: - { - struct stm32_serial_s *user; - - user = (struct stm32_serial_s *)arg; - - if (!user) - { - ret = -EINVAL; - } - else - { - memcpy(user, dev, sizeof(struct stm32_serial_s)); - } - } - break; -#endif - -#ifdef CONFIG_STM32_USART_SINGLEWIRE - case TIOCSSINGLEWIRE: - { - uint32_t cr1; - uint32_t cr1_ue; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE, HDSEL can only be written when UE=0 */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Change the TX port to be open-drain/push-pull and enable/disable - * half-duplex mode. - */ - - uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); - - if ((arg & SER_SINGLEWIRE_ENABLED) != 0) - { - uint32_t gpio_val = GPIO_OPENDRAIN; - - if ((arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLUP) - { - gpio_val |= GPIO_PULLUP; - } - else - { - gpio_val |= GPIO_FLOAT; - } - - if ((arg & SER_SINGLEWIRE_PULL_MASK) == - SER_SINGLEWIRE_PULLDOWN) - { - gpio_val |= GPIO_PULLDOWN; - } - else - { - gpio_val |= GPIO_FLOAT; - } - - if (priv->tx_gpio != 0) - { - stm32_configgpio((priv->tx_gpio & - ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | - gpio_val); - } - - cr |= USART_CR3_HDSEL; - } - else - { - if (priv->tx_gpio != 0) - { - stm32_configgpio((priv->tx_gpio & - ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | - GPIO_PUSHPULL); - } - - cr &= ~USART_CR3_HDSEL; - } - - stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, cr); - - /* Re-enable UE if appropriate */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); - } - break; -#endif - -#ifdef CONFIG_STM32_USART_INVERT - case TIOCSINVERT: - { - uint32_t cr1; - uint32_t cr1_ue; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE, {R,T}XINV can only be written when UE=0 */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Enable/disable signal inversion. */ - - uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); - - if (arg & SER_INVERT_ENABLED_RX) - { - cr |= USART_CR2_RXINV; - } - else - { - cr &= ~USART_CR2_RXINV; - } - - if (arg & SER_INVERT_ENABLED_TX) - { - cr |= USART_CR2_TXINV; - } - else - { - cr &= ~USART_CR2_TXINV; - } - - stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, cr); - - /* Re-enable UE if appropriate */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); - } - break; -#endif - -#ifdef CONFIG_STM32_USART_SWAP - case TIOCSSWAP: - { - uint32_t cr1; - uint32_t cr1_ue; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE, SWAP can only be written when UE=0 */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Enable/disable Swap mode. */ - - uint32_t cr = stm32serial_getreg(priv, STM32_USART_CR2_OFFSET); - - if (arg == SER_SWAP_ENABLED) - { - cr |= USART_CR2_SWAP; - } - else - { - cr &= ~USART_CR2_SWAP; - } - - stm32serial_putreg(priv, STM32_USART_CR2_OFFSET, cr); - - /* Re-enable UE if appropriate */ - - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); - } - break; -#endif - -#ifdef CONFIG_SERIAL_TERMIOS - case TCGETS: - { - struct termios *termiosp = (struct termios *)arg; - - if (!termiosp) - { - ret = -EINVAL; - break; - } - - cfsetispeed(termiosp, priv->baud); - - /* Note that since we only support 8/9 bit modes and - * there is no way to report 9-bit mode, we always claim 8. - */ - - termiosp->c_cflag = - ((priv->parity != 0) ? PARENB : 0) | - ((priv->parity == 1) ? PARODD : 0) | - ((priv->stopbits2) ? CSTOPB : 0) | -#ifdef CONFIG_SERIAL_OFLOWCONTROL - ((priv->oflow) ? CCTS_OFLOW : 0) | -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL - ((priv->iflow) ? CRTS_IFLOW : 0) | -#endif - CS8; - - /* TODO: CRTS_IFLOW, CCTS_OFLOW */ - } - break; - - case TCSETS: - { - struct termios *termiosp = (struct termios *)arg; - - if (!termiosp) - { - ret = -EINVAL; - break; - } - - /* Perform some sanity checks before accepting any changes */ - - if (((termiosp->c_cflag & CSIZE) != CS8) -#ifdef CONFIG_SERIAL_OFLOWCONTROL - || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL - || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) -#endif - ) - { - ret = -EINVAL; - break; - } - - if (termiosp->c_cflag & PARENB) - { - priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; - } - else - { - priv->parity = 0; - } - - priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; -#ifdef CONFIG_SERIAL_OFLOWCONTROL - priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL - priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; -#endif - - /* Note that since there is no way to request 9-bit mode - * and no way to support 5/6/7-bit modes, we ignore them - * all here. - */ - - /* Note that only cfgetispeed is used because we have knowledge - * that only one speed is supported. - */ - - priv->baud = cfgetispeed(termiosp); - - /* Effect the changes immediately - note that we do not implement - * TCSADRAIN / TCSAFLUSH - */ - - stm32serial_setformat(dev); - } - break; -#endif /* CONFIG_SERIAL_TERMIOS */ - -#ifdef CONFIG_STM32_USART_BREAKS -# ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT - case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ - { - irqstate_t flags; - - flags = enter_critical_section(); - - /* Disable any further tx activity */ - - priv->ie |= USART_CR1_IE_BREAK_INPROGRESS; - - stm32serial_txint(dev, false); - - /* Configure TX as a GPIO output pin and Send a break signal */ - - if (priv->tx_gpio != 0) - { - uint32_t tx_break = GPIO_OUTPUT | - (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio); - - stm32_configgpio(tx_break); - } - - leave_critical_section(flags); - } - break; - - case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ - { - irqstate_t flags; - - flags = enter_critical_section(); - - /* Configure TX back to U(S)ART */ - - if (priv->tx_gpio != 0) - { - stm32_configgpio(priv->tx_gpio); - } - - priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS; - - /* Enable further tx activity */ - - stm32serial_txint(dev, true); - - leave_critical_section(flags); - } - break; -# else - case TIOCSBRK: /* No BSD compatibility: Turn break on for M bit times */ - { - uint32_t cr1; - irqstate_t flags; - - flags = enter_critical_section(); - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, - cr1 | USART_CR1_SBK); - leave_critical_section(flags); - } - break; - - case TIOCCBRK: /* No BSD compatibility: May turn off break too soon */ - { - uint32_t cr1; - irqstate_t flags; - - flags = enter_critical_section(); - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, - cr1 & ~USART_CR1_SBK); - leave_critical_section(flags); - } - break; -# endif -#endif -#ifdef HAVE_RS485 - case TIOCSRS485: /* Set RS485 mode, arg: pointer to struct serial_rs485 */ - { - ret = stm32serial_set_rs485_mode( - priv, (const struct serial_rs485 *)((uintptr_t)arg)); - } - break; - - case TIOCGRS485: /* Get RS485 mode, arg: pointer to struct serial_rs485 */ - { - ret = stm32serial_get_rs485_mode( - priv, (struct serial_rs485 *)((uintptr_t)arg)); - } - break; -#endif - default: - ret = -ENOTTY; - break; - } - - return ret; -} - -/**************************************************************************** - * Name: stm32serial_receive - * - * Description: - * Called (usually) from the interrupt level to receive one - * character from the USART. Error bits associated with the - * receipt are provided in the return 'status'. - * - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static int stm32serial_receive(struct uart_dev_s *dev, - unsigned int *status) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t rdr; - - /* Get the Rx byte */ - - rdr = stm32serial_getreg(priv, STM32_USART_RDR_OFFSET); - - /* Get the Rx byte plux error information. Return those in status */ - - *status = priv->sr << 16 | rdr; - priv->sr = 0; - - /* Then return the actual received byte */ - - return rdr & 0xff; -} -#endif - -/**************************************************************************** - * Name: stm32serial_rxint - * - * Description: - * Call to enable or disable RX interrupts - * - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static void stm32serial_rxint(struct uart_dev_s *dev, bool enable) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - irqstate_t flags; - uint16_t ie; - - /* USART receive interrupts: - * - * Enable Status Meaning Usage - * ---------------- -------------- ---------------------- ---------- - * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) - * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready - * to be Read - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR1_PEIE USART_ISR_PE Parity Error - * - * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) - * USART_CR3_EIE USART_ISR_FE Framing Error - * " " USART_ISR_NF Noise Flag - * " " USART_ISR_ORE Overrun Error Detected - */ - - flags = enter_critical_section(); - ie = priv->ie; - if (enable) - { - /* Receive an interrupt when their is anything in the Rx data - * register (or an Rx timeout occurs). - */ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -#ifdef CONFIG_USART_ERRINTS - ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); -#else - ie |= USART_CR1_RXNEIE; -#endif -#endif - } - else - { - ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); - } - - /* Then set the new interrupt state */ - - stm32serial_restoreusartint(priv, ie); - leave_critical_section(flags); -} -#endif - -/**************************************************************************** - * Name: stm32serial_rxavailable - * - * Description: - * Return true if the receive register is not empty - * - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static bool stm32serial_rxavailable(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - return ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & - USART_ISR_RXNE) != 0); -} -#endif - -/**************************************************************************** - * Name: stm32serial_rxflowcontrol - * - * Description: - * Called when Rx buffer is full (or exceeds configured watermark levels - * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). - * Return true if UART activated RX flow control to block more incoming - * data - * - * Input Parameters: - * dev - UART device instance - * nbuffered - the number of characters currently buffered - * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is - * not defined the value will be 0 for an empty buffer or the - * defined buffer size for a full buffer) - * upper - true indicates the upper watermark was crossed where - * false indicates the lower watermark has been crossed - * - * Returned Value: - * true if RX flow control activated. - * - ****************************************************************************/ - -#ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool stm32serial_rxflowcontrol(struct uart_dev_s *dev, - unsigned int nbuffered, bool upper) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - -#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ - defined(CONFIG_STM32_FLOWCONTROL_BROKEN) - if (priv->iflow && (priv->rts_gpio != 0)) - { - /* Assert/de-assert nRTS set it high resume/stop sending */ - - stm32_gpiowrite(priv->rts_gpio, upper); - - if (upper) - { - /* With heavy Rx traffic, RXNE might be set and data pending. - * Returning 'true' in such case would cause RXNE left unhandled - * and causing interrupt storm. Sending end might be also be slow - * to react on nRTS, and returning 'true' here would prevent - * processing that data. - * - * Therefore, return 'false' so input data is still being processed - * until sending end reacts on nRTS signal and stops sending more. - */ - - return false; - } - - return upper; - } - -#else - if (priv->iflow) - { - /* Is the RX buffer full? */ - - if (upper) - { - /* Disable Rx interrupt to prevent more data being from - * peripheral. When hardware RTS is enabled, this will - * prevent more data from coming in. - * - * This function is only called when UART recv buffer is full, - * that is: "dev->recv.head + 1 == dev->recv.tail". - * - * Logic in "uart_read" will automatically toggle Rx interrupts - * when buffer is read empty and thus we do not have to re- - * enable Rx interrupts. - */ - - uart_disablerxint(dev); - return true; - } - - /* No.. The RX buffer is empty */ - - else - { - /* We might leave Rx interrupt disabled if full recv buffer was - * read empty. Enable Rx interrupt to make sure that more input is - * received. - */ - - uart_enablerxint(dev); - } - } -#endif - - return false; -} -#endif - -/**************************************************************************** - * Name: stm32serial_dmareceive - * - * Description: - * Retrieve one character from the RX FIFO filled by circular DMA. Also - * report any USART error flags in *status. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static int stm32serial_dmareceive(struct uart_dev_s *dev, - unsigned int *status) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - unsigned int next; - int ch = -1; - uint32_t sr; - - /* 1) Capture USART error flags */ - - sr = getreg32(priv->usartbase + STM32_USART_ISR_OFFSET); - *status = sr & (USART_ISR_ORE | USART_ISR_NF | - USART_ISR_FE | USART_ISR_PE); - - /* 2) Where will DMA write the next byte? */ - - next = stm32serial_dmanextrx(priv); - - /* 3) Pull one byte if available */ - - if (next != priv->rxdmanext) - { - ch = priv->rxfifo[priv->rxdmanext++]; - - /* 4) End‑of‑buffer wrap or flow‑control pause */ - - if (priv->rxdmanext >= RXDMA_BUFFER_SIZE) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Pause DMA callbacks */ - - stm32serial_dmarxint(&priv->dev, false); - - /* Assert RTS to halt sender */ - - (void)stm32serial_rxflowcontrol(&priv->dev, - RXDMA_BUFFER_SIZE, true); - } - else -#endif - { - /* Simply wrap to buffer start */ - - priv->rxdmanext = 0; - } - } - } - - return ch; -} -#endif - -/**************************************************************************** - * Name: stm32serial_dmareenable - * - * Description: - * Call to re-enable RX DMA. - * - ****************************************************************************/ - -#if defined(SERIAL_HAVE_DMA) -static void stm32serial_dmareenable(struct stm32_serial_s *priv) -{ - struct stm32_gpdma_cfg_s dmacfg; - - serial_rxdmacfg(priv, &dmacfg); - stm32_dmasetup(priv->rxdma, &dmacfg); - - /* Reset our DMA shadow pointer to match the address just - * programmed above. - */ - - priv->rxdmanext = 0; - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Start the DMA channel, and arrange for callbacks at the full point - * in the FIFO. After buffer gets full, hardware flow-control kicks - * in and DMA transfer is stopped. - */ - - stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, - (void *)priv, false); - } - else -#endif - { - /* Start the DMA channel, and arrange for callbacks at the half and - * full points in the FIFO. This ensures that we have half a FIFO - * worth of time to claim bytes before they are overwritten. - */ - - stm32_dmastart(priv->rxdma, stm32serial_dmarxcallback, - (void *)priv, true); - } - -#ifdef CONFIG_PM - /* Clear DMA suspended flag. */ - - priv->rxdmasusp = false; -#endif -} -#endif - -/**************************************************************************** - * Name: stm32serial_dmaiflowrestart - * - * Description: - * Call to restart RX DMA for input flow-controlled USART - * - ****************************************************************************/ - -#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) -static bool stm32serial_dmaiflowrestart(struct stm32_serial_s *priv) -{ - if (!priv->rxenable) - { - /* Rx not enabled by upper layer. */ - - return false; - } - - if (priv->rxdmanext != RXDMA_BUFFER_SIZE) - { -#ifdef CONFIG_PM - if (priv->rxdmasusp) - { - /* Rx DMA in suspended state. */ - - if (stm32serial_dmarxavailable(&priv->dev)) - { - /* DMA buffer has unprocessed data, do not re-enable yet. */ - - return false; - } - } - else -#endif - { - return false; - } - } - - /* DMA is stopped or suspended and DMA buffer does not have pending data, - * re-enabling without data loss is now safe. - */ - - stm32serial_dmareenable(priv); - - return true; -} -#endif - -/**************************************************************************** - * Name: stm32serial_dmarxint - * - * Description: - * Call to enable or disable RX interrupts - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static void stm32serial_dmarxint(struct uart_dev_s *dev, bool enable) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - /* En/disable DMA reception. - * - * Note that it is not safe to check for available bytes and immediately - * pass them to uart_recvchars as that could potentially recurse back - * to us again. Instead, bytes must wait until the next up_dma_poll or - * DMA event. - */ - - priv->rxenable = enable; - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Re-enable RX DMA. */ - - stm32serial_dmaiflowrestart(priv); - } -#endif -} -#endif - -/**************************************************************************** - * Name: stm32serial_dmarxavailable - * - * Description: - * Return true if the receive register is not empty - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static bool stm32serial_dmarxavailable(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - /* Compare our receive pointer to the current DMA pointer, if they - * do not match, then there are bytes to be received. - */ - - return (stm32serial_dmanextrx(priv) != priv->rxdmanext); -} -#endif - -/**************************************************************************** - * Name: stm32serial_send - * - * Description: - * This method will send one byte on the USART - * - ****************************************************************************/ - -static void stm32serial_send(struct uart_dev_s *dev, int ch) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - -#ifdef HAVE_RS485 - if ((priv->rs485_flags & SER_RS485_ENABLED) != 0) - { - stm32_gpiowrite(priv->rs485_dir_gpio, (bool) (priv->rs485_flags & - SER_RS485_RTS_ON_SEND)); - } -#endif - - stm32serial_putreg(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch); -} - -/**************************************************************************** - * Name: stm32serial_txint - * - * Description: - * Call to enable or disable TX interrupts - * - ****************************************************************************/ - -static void stm32serial_txint(struct uart_dev_s *dev, bool enable) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - irqstate_t flags; - - /* USART transmit interrupts: - * - * Enable Status Meaning Usage - * --------------- ------------- ---------------------------- ------------- - * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only RS-485) - * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty - * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) - */ - - flags = enter_critical_section(); - if (enable) - { - /* Set to receive an interrupt when the TX data register is empty */ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - uint16_t ie = priv->ie | USART_CR1_TXEIE; - - /* If RS-485 is supported on this U[S]ART, then also enable the - * transmission complete interrupt. - */ - -# ifdef HAVE_RS485 - if ((priv->rs485_flags & SER_RS485_ENABLED) != 0) - { - ie |= USART_CR1_TCIE; - } -# endif - -# ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT - if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS) - { - leave_critical_section(flags); - return; - } -# endif - - stm32serial_restoreusartint(priv, ie); - - /* Fake a TX interrupt here by just calling uart_xmitchars() with - * interrupts disabled (note this may recurse). - */ - - uart_xmitchars(dev); -#endif - } - else - { - /* Disable the TX interrupt */ - - stm32serial_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); - } - - leave_critical_section(flags); -} - -/**************************************************************************** - * Name: stm32serial_txready - * - * Description: - * Return true if the transmit data register is empty - * - ****************************************************************************/ - -static bool stm32serial_txready(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - return ((stm32serial_getreg(priv, STM32_USART_ISR_OFFSET) & - USART_ISR_TXE) != 0); -} - -/**************************************************************************** - * Name: stm32serial_dmarxcallback - * - * Description: - * DMA callback for STM32H5 USART RX. Called on half and full‐transfer - * events. Reads and clears the GPDMA status flags, notifies the NuttX - * serial core of newly arrived bytes, signals end‐of‐buffer when a - * full transfer completes, handles RTS flow control restart, and - * clears any lingering UART error flags to keep RX‐DMA running. - * - * Input Parameters: - * handle - DMA channel handle returned by stm32_dmachannel() - * status - Raw status byte passed by the DMA ISR (ignored here) - * arg - Pointer to the STM32 serial driver state - * (struct stm32_serial_s) - * - * Returned Value: - * None - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static void stm32serial_dmarxcallback(DMA_HANDLE handle, - uint8_t status, - void *arg) -{ - struct stm32_serial_s *priv = arg; - - /* pull whatever is in the buffer now */ - - uart_recvchars(&priv->dev); - - /* If it really was a full‑buffer event, signal “done” so the - * serial core can rearm/restart the DMA behind the scenes: - */ - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - /* If you had paused the DMA on RTS flow control, restart it now */ - - if (priv->iflow) - { - stm32serial_dmaiflowrestart(priv); - } -#endif - - /* Clear any USART framing/overrun errors so RX‑DMA - * doesn’t get stuck waiting for the UART to clear them. - */ - - priv->sr = getreg32(priv->usartbase + STM32_USART_ISR_OFFSET); - if (priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) - { - stm32serial_putreg(priv, STM32_USART_ICR_OFFSET, - USART_ICR_ORECF | USART_ICR_NCF | USART_ICR_FECF); - } -} -#endif - -/**************************************************************************** - * Name: stm32serial_pmnotify - * - * Description: - * Notify the driver of new power state. This callback is called after - * all drivers have had the opportunity to prepare for the new power state. - * - * Input Parameters: - * - * cb - Returned to the driver. The driver version of the callback - * structure may include additional, driver-specific state data at - * the end of the structure. - * - * pmstate - Identifies the new PM state - * - * Returned Value: - * None - The driver already agreed to transition to the low power - * consumption state when when it returned OK to the prepare() call. - * - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void stm32serial_pmnotify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) -{ - switch (pmstate) - { - case PM_NORMAL: - { - stm32serial_pm_setsuspend(false); - } - break; - - case PM_IDLE: - { - stm32serial_pm_setsuspend(false); - } - break; - - case PM_STANDBY: - { - /* TODO: Alternative configuration and logic for enabling serial in - * Stop 1 mode with HSI16 missing. Current logic allows - * suspending serial peripherals for Stop 0/1/2 when serial - * Rx/Tx buffers are empty (checked in pmprepare). - */ - - stm32serial_pm_setsuspend(true); - } - break; - - case PM_SLEEP: - { - stm32serial_pm_setsuspend(true); - } - break; - - default: - - /* Should not get here */ - - break; - } -} -#endif - -/**************************************************************************** - * Name: stm32serial_pmprepare - * - * Description: - * Request the driver to prepare for a new power state. This is a warning - * that the system is about to enter into a new power state. The driver - * should begin whatever operations that may be required to enter power - * state. The driver may abort the state change mode by returning a - * non-zero value from the callback function. - * - * Input Parameters: - * - * cb - Returned to the driver. The driver version of the callback - * structure may include additional, driver-specific state data at - * the end of the structure. - * - * pmstate - Identifies the new PM state - * - * Returned Value: - * Zero - (OK) means the event was successfully processed and that the - * driver is prepared for the PM state change. - * - * Non-zero - means that the driver is not prepared to perform the tasks - * needed achieve this power setting and will cause the state - * change to be aborted. NOTE: The prepare() method will also - * be called when reverting from lower back to higher power - * consumption modes (say because another driver refused a - * lower power state change). Drivers are not permitted to - * return non-zero values when reverting back to higher power - * consumption modes! - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static int stm32serial_pmprepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) -{ - int n; - - /* Logic to prepare for a reduced power state goes here. */ - - switch (pmstate) - { - case PM_NORMAL: - case PM_IDLE: - break; - - case PM_STANDBY: - case PM_SLEEP: - -#ifdef SERIAL_HAVE_DMA - /* Flush Rx DMA buffers before checking state of serial device - * buffers. - */ - - stm32_serial_dma_poll(); -#endif - - /* Check if any of the active ports have data pending on Tx/Rx - * buffers. - */ - - for (n = 0; n < STM32_NLPUART + STM32_NUSART + STM32_NUART; n++) - { - struct stm32_serial_s *priv = g_uart_devs[n]; - - if (!priv || !priv->initialized) - { - /* Not active, skip. */ - - continue; - } - - if (priv->suspended) - { - /* Port already suspended, skip. */ - - continue; - } - - /* Check if port has data pending (Rx & Tx). */ - - if (priv->dev.xmit.head != priv->dev.xmit.tail) - { - return ERROR; - } - - if (priv->dev.recv.head != priv->dev.recv.tail) - { - return ERROR; - } - } - break; - - default: - - /* Should not get here */ - - break; - } - - return OK; -} -#endif - -#endif /* HAVE_UART */ -#endif /* USE_SERIALDRIVER */ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#ifdef USE_SERIALDRIVER - -/**************************************************************************** - * Name: arm_earlyserialinit - * - * Description: - * Performs the low level USART initialization early in debug so that the - * serial console will be available during boot up. This must be called - * before arm_serialinit. - * - ****************************************************************************/ - -#ifdef USE_EARLYSERIALINIT -void arm_earlyserialinit(void) -{ -#ifdef HAVE_UART - unsigned i; - - /* Disable all USART interrupts */ - - for (i = 0; i < STM32_NLPUART + STM32_NUSART + STM32_NUART; i++) - { - if (g_uart_devs[i]) - { - stm32serial_disableusartint(g_uart_devs[i], NULL); - } - } - - /* Configure whichever one is the console */ - -#if CONSOLE_UART > 0 - stm32serial_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); -#endif -#endif /* HAVE UART */ -} -#endif /* USE_EARLYSERIALINIT */ - -/**************************************************************************** - * Name: arm_serialinit - * - * Description: - * Register serial console and serial ports. This assumes - * that arm_earlyserialinit was called previously. - * - ****************************************************************************/ - -void arm_serialinit(void) -{ -#ifdef HAVE_UART - char devname[16]; - unsigned i; - unsigned minor = 0; -#ifdef CONFIG_PM - int ret; -#endif - - /* Register to receive power management callbacks */ - -#ifdef CONFIG_PM - ret = pm_register(&g_serialpm.pm_cb); - DEBUGASSERT(ret == OK); - UNUSED(ret); -#endif - - /* Register the console */ - -#if CONSOLE_UART > 0 - uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); - -#ifndef CONFIG_STM32_SERIAL_DISABLE_REORDERING - /* If not disabled, register the console UART to ttyS0 and exclude - * it from initializing it further down - */ - - uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); - minor = 1; -#endif - -#ifdef SERIAL_HAVE_CONSOLE_DMA - /* If we need to re-initialise the console to enable DMA do that here. */ - - stm32serial_dmasetup(&g_uart_devs[CONSOLE_UART - 1]->dev); -#endif -#endif /* CONSOLE_UART > 0 */ - - /* Register all remaining USARTs */ - - strlcpy(devname, "/dev/ttySx", sizeof(devname)); - - for (i = 0; i < STM32_NLPUART + STM32_NUSART + STM32_NUART; i++) - { - /* Don't create a device for non-configured ports. */ - - if (g_uart_devs[i] == 0) - { - continue; - } - -#ifndef CONFIG_STM32_SERIAL_DISABLE_REORDERING - /* Don't create a device for the console - we did that above */ - - if (g_uart_devs[i]->dev.isconsole) - { - continue; - } -#endif - - /* Register USARTs as devices in increasing order */ - - devname[9] = '0' + minor++; - uart_register(devname, &g_uart_devs[i]->dev); - } -#endif /* HAVE UART */ -} - -/**************************************************************************** - * Name: stm32_serial_dma_poll - * - * Description: - * Checks receive DMA buffers for received bytes that have not accumulated - * to the point where the DMA half/full interrupt has triggered. - * - * This function should be called from a timer or other periodic context. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -void stm32_serial_dma_poll(void) -{ - irqstate_t flags; - - flags = enter_critical_section(); - -#ifdef CONFIG_LPUART1_RXDMA - if (g_lpuart1priv.rxdma != NULL) - { - stm32serial_dmarxcallback(g_lpuart1priv.rxdma, 0, &g_lpuart1priv); - } -#endif - -#ifdef CONFIG_USART1_RXDMA - if (g_usart1priv.rxdma != NULL) - { - stm32serial_dmarxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); - } -#endif - -#ifdef CONFIG_USART2_RXDMA - if (g_usart2priv.rxdma != NULL) - { - stm32serial_dmarxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); - } -#endif - -#ifdef CONFIG_USART3_RXDMA - if (g_usart3priv.rxdma != NULL) - { - stm32serial_dmarxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); - } -#endif - -#ifdef CONFIG_UART4_RXDMA - if (g_uart4priv.rxdma != NULL) - { - stm32serial_dmarxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); - } -#endif - -#ifdef CONFIG_UART5_RXDMA - if (g_uart5priv.rxdma != NULL) - { - stm32serial_dmarxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); - } -#endif - - leave_critical_section(flags); -} -#endif - -/**************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug writes - * - ****************************************************************************/ - -void up_putc(int ch) -{ -#if CONSOLE_UART > 0 - struct stm32_serial_s *priv = g_uart_devs[CONSOLE_UART - 1]; - uint16_t ie; - - stm32serial_disableusartint(priv, &ie); - - /* Check for LF */ - - if (ch == '\n') - { - /* Add CR */ - - arm_lowputc('\r'); - } - - arm_lowputc(ch); - stm32serial_restoreusartint(priv, ie); -#endif -} - -#else /* USE_SERIALDRIVER */ - -/**************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug writes - * - ****************************************************************************/ - -void up_putc(int ch) -{ -#if CONSOLE_UART > 0 - /* Check for LF */ - - if (ch == '\n') - { - /* Add CR */ - - arm_lowputc('\r'); - } - - arm_lowputc(ch); -#endif -} - -#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32h5/stm32_uart.h b/arch/arm/src/stm32h5/stm32_uart.h deleted file mode 100644 index f6530cf94bb..00000000000 --- a/arch/arm/src/stm32h5/stm32_uart.h +++ /dev/null @@ -1,575 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h5/stm32_uart.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_STC_STM32H5_STM32_UART_H -#define __ARCH_ARM_STC_STM32H5_STM32_UART_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -#include "chip.h" - -#if defined(CONFIG_STM32_STM32H5XXXX) -# include "hardware/stm32_uart.h" -#else -# error "Unsupported STM32H5 chip" -#endif - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Make sure that we have not enabled more U[S]ARTs than are supported by the - * device. - */ - -#if !defined(CONFIG_STM32_HAVE_UART12) -# undef CONFIG_STM32_UART12 -#endif -#if !defined(CONFIG_STM32_HAVE_USART11) -# undef CONFIG_STM32_USART11 -#endif -#if !defined(CONFIG_STM32_HAVE_USART10) -# undef CONFIG_STM32_USART10 -#endif -#if !defined(CONFIG_STM32_HAVE_UART9) -# undef CONFIG_STM32_UART9 -#endif -#if !defined(CONFIG_STM32_HAVE_UART8) -# undef CONFIG_STM32_UART8 -#endif -#if !defined(CONFIG_STM32_HAVE_UART7) -# undef CONFIG_STM32_UART7 -#endif -#if !defined(CONFIG_STM32_HAVE_USART6) -# undef CONFIG_STM32_USART6 -#endif -#if !defined(CONFIG_STM32_HAVE_UART5) -# undef CONFIG_STM32_UART5 -#endif -#if !defined(CONFIG_STM32_HAVE_UART4) -# undef CONFIG_STM32_UART4 -#endif -#if !defined(CONFIG_STM32_HAVE_USART3) -# undef CONFIG_STM32_USART3 -#endif -#if !defined(CONFIG_STM32_HAVE_USART2) -# undef CONFIG_STM32_USART2 -#endif -#if !defined(CONFIG_STM32_HAVE_USART1) -# undef CONFIG_STM32_USART1 -#endif -#if !defined(CONFIG_STM32_HAVE_LPUART1) -# undef CONFIG_STM32_LPUART1 -#endif - -/* Sanity checks */ - -#if !defined(CONFIG_STM32_LPUART1) -# undef CONFIG_STM32_LPUART1_SERIALDRIVER -# undef CONFIG_STM32_LPUART1_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART1) -# undef CONFIG_STM32_USART1_SERIALDRIVER -# undef CONFIG_STM32_USART1_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART2) -# undef CONFIG_STM32_USART2_SERIALDRIVER -# undef CONFIG_STM32_USART2_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART3) -# undef CONFIG_STM32_USART3_SERIALDRIVER -# undef CONFIG_STM32_USART3_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART4) -# undef CONFIG_STM32_UART4_SERIALDRIVER -# undef CONFIG_STM32_UART4_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART5) -# undef CONFIG_STM32_UART5_SERIALDRIVER -# undef CONFIG_STM32_UART5_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART6) -# undef CONFIG_STM32_USART6_SERIALDRIVER -# undef CONFIG_STM32_USART6_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART7) -# undef CONFIG_STM32_UART7_SERIALDRIVER -# undef CONFIG_STM32_UART7_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART8) -# undef CONFIG_STM32_UART8_SERIALDRIVER -# undef CONFIG_STM32_UART8_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART9) -# undef CONFIG_STM32_UART9_SERIALDRIVER -# undef CONFIG_STM32_UART9_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART10) -# undef CONFIG_STM32_USART10_SERIALDRIVER -# undef CONFIG_STM32_USART10_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART11) -# undef CONFIG_STM32_USART11_SERIALDRIVER -# undef CONFIG_STM32_USART11_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART12) -# undef CONFIG_STM32_UART12_SERIALDRIVER -# undef CONFIG_STM32_UART12_1WIREDRIVER -#endif - -/* Is there a USART enabled? */ - -#if defined(CONFIG_STM32_LPUART1) || defined(CONFIG_STM32_USART1) || \ - defined(CONFIG_STM32_USART2) || defined(CONFIG_STM32_USART3) || \ - defined(CONFIG_STM32_UART4) || defined(CONFIG_STM32_UART5) || \ - defined(CONFIG_STM32_USART6) || defined(CONFIG_STM32_UART7) || \ - defined(CONFIG_STM32_UART8) || defined(CONFIG_STM32_UART9) || \ - defined(CONFIG_STM32_USART10) || defined(CONFIG_STM32_USART11) || \ - defined(CONFIG_STM32_USART12) -# define HAVE_UART 1 -#endif - -/* Is there a serial console? */ - -#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_STM32_LPUART1_SERIALDRIVER) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 1 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART1_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 2 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART2_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 3 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART3_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 4 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART4_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 5 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART5_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 6 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART6_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 7 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART7_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 8 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART8_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 9 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART9_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART9_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 10 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_USART10_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART10_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 11 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_USART11_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART11_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_UART12_SERIAL_CONSOLE -# define CONSOLE_UART 12 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART12_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART12_SERIALDRIVER) -# undef CONFIG_LPUART1_SERIAL_CONSOLE -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# undef CONFIG_UART9_SERIAL_CONSOLE -# undef CONFIG_USART10_SERIAL_CONSOLE -# undef CONFIG_USART11_SERIAL_CONSOLE -# define CONSOLE_UART 13 -# define HAVE_CONSOLE 1 -#else -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# define CONSOLE_UART 0 -# undef HAVE_CONSOLE -#endif - -/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX - * configuration - */ - -#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) -# undef CONFIG_USART1_RXDMA -# undef CONFIG_USART2_RXDMA -# undef CONFIG_USART3_RXDMA -# undef CONFIG_UART4_RXDMA -# undef CONFIG_UART5_RXDMA -# undef CONFIG_USART7_RXDMA -# undef CONFIG_UART7_RXDMA -# undef CONFIG_UART8_RXDMA -# undef CONFIG_UART9_RXDMA -# undef CONFIG_USART10_RXDMA -# undef CONFIG_USART11_RXDMA -# undef CONFIG_UART12_RXDMA -#endif - -/* Disable the DMA configuration on all unused USARTs */ - -#ifndef CONFIG_STM32_LPUART1_SERIALDRIVER -# undef CONFIG_LPUART1_RXDMA -#endif - -#ifndef CONFIG_STM32_USART1_SERIALDRIVER -# undef CONFIG_USART1_RXDMA -#endif - -#ifndef CONFIG_STM32_USART2_SERIALDRIVER -# undef CONFIG_USART2_RXDMA -#endif - -#ifndef CONFIG_STM32_USART3_SERIALDRIVER -# undef CONFIG_USART3_RXDMA -#endif - -#ifndef CONFIG_STM32_UART4_SERIALDRIVER -# undef CONFIG_UART4_RXDMA -#endif - -#ifndef CONFIG_STM32_UART5_SERIALDRIVER -# undef CONFIG_UART5_RXDMA -#endif - -#ifndef CONFIG_STM32_USART6_SERIALDRIVER -# undef CONFIG_USART6_RXDMA -#endif - -#ifndef CONFIG_STM32_UART7_SERIALDRIVER -# undef CONFIG_UART7_RXDMA -#endif - -#ifndef CONFIG_STM32_UART8_SERIALDRIVER -# undef CONFIG_UART8_RXDMA -#endif - -#ifndef CONFIG_STM32_UART9_SERIALDRIVER -# undef CONFIG_UART9_RXDMA -#endif - -#ifndef CONFIG_STM32_USART10_SERIALDRIVER -# undef CONFIG_USART10_RXDMA -#endif - -#ifndef CONFIG_STM32_USART11_SERIALDRIVER -# undef CONFIG_USART11_RXDMA -#endif - -#ifndef CONFIG_STM32_UART12_SERIALDRIVER -# undef CONFIG_UART12_RXDMA -#endif - -/* Is DMA available on any (enabled) USART? */ - -#undef SERIAL_HAVE_DMA -#if defined(CONFIG_LPUART1_RXDMA) || defined(CONFIG_USART1_RXDMA) || \ - defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \ - defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) || \ - defined(CONFIG_USART6_RXDMA) || defined(CONFIG_UART7_RXDMA) || \ - defined(CONFIG_UART8_RXDMA) || defined(CONFIG_UART9_RXDMA) || \ - defined(CONFIG_USART10_RXDMA) || defined(CONFIG_USART11_RXDMA) || \ - defined(CONFIG_USART12_RXDMA) -# define SERIAL_HAVE_DMA 1 -#endif - -/* Is DMA used on the console UART? */ - -#undef SERIAL_HAVE_CONSOLE_DMA -#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_LPUART1_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART9_SERIAL_CONSOLE) && defined(CONFIG_UART9_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_USART10_SERIAL_CONSOLE) && defined(CONFIG_USART10_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_USART11_SERIAL_CONSOLE) && defined(CONFIG_USART11_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART12_SERIAL_CONSOLE) && defined(CONFIG_UART12_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#endif - -/* Is DMA used on all (enabled) USARTs */ - -#define SERIAL_HAVE_ONLY_DMA 1 -#if defined(CONFIG_STM32_LPUART1_SERIALDRIVER) && !defined(CONFIG_LPUART1_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART1_SERIALDRIVER) && !defined(CONFIG_USART1_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART2_SERIALDRIVER) && !defined(CONFIG_USART2_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART3_SERIALDRIVER) && !defined(CONFIG_USART3_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART4_SERIALDRIVER) && !defined(CONFIG_UART4_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART5_SERIALDRIVER) && !defined(CONFIG_UART5_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART6_SERIALDRIVER) && !defined(CONFIG_USART6_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART7_SERIALDRIVER) && !defined(CONFIG_UART7_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART8_SERIALDRIVER) && !defined(CONFIG_UART8_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART9_SERIALDRIVER) && !defined(CONFIG_UART9_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART10_SERIALDRIVER) && !defined(CONFIG_USART10_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART11_SERIALDRIVER) && !defined(CONFIG_USART11_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART12_SERIALDRIVER) && !defined(CONFIG_UART12_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#endif - -/* Is RS-485 used? */ - -#if defined(CONFIG_LPUART1_RS485) || defined(CONFIG_USART1_RS485) || \ - defined(CONFIG_USART2_RS485) || defined(CONFIG_USART3_RS485) || \ - defined(CONFIG_UART4_RS485) || defined(CONFIG_UART5_RS485) || \ - defined(CONFIG_USART6_RS485) || defined(CONFIG_UART7_RS485) || \ - defined(CONFIG_UART8_RS485) || defined(CONFIG_UART9_RS485) || \ - defined(CONFIG_USART10_RS485) || defined(CONFIG_USART11_RS485) || \ - defined(CONFIG_UART12_RS485) -# define HAVE_RS485 1 -#endif - -#ifdef HAVE_RS485 -# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) -#else -# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) -#endif - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32_serial_dma_poll - * - * Description: - * Must be called periodically if any STM32 UART is configured for DMA. - * The DMA callback is triggered for each fifo size/2 bytes, but this can - * result in some bytes being transferred but not collected if the incoming - * data is not a whole multiple of half the FIFO size. - * - * May be safely called from either interrupt or thread context. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -void stm32_serial_dma_poll(void); -#endif - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_STC_STM32H5_STM32_UART_H */