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 */