diff --git a/arch/arm/src/common/stm32/Kconfig.have b/arch/arm/src/common/stm32/Kconfig.have index 829b51534d0..cb7fa87d3fa 100644 --- a/arch/arm/src/common/stm32/Kconfig.have +++ b/arch/arm/src/common/stm32/Kconfig.have @@ -1069,6 +1069,9 @@ config STM32_HAVE_USART_H5 config STM32_HAVE_USART_RXFIFO_THRESHOLD bool +config STM32_HAVE_USART_WUS + bool + config STM32_HAVE_USART_UNCONFIG_ON_CLOSE bool default y if ARCH_CHIP_STM32H5 diff --git a/arch/arm/src/common/stm32/Kconfig.uart b/arch/arm/src/common/stm32/Kconfig.uart index 78ee35c0e34..679b076ec2b 100644 --- a/arch/arm/src/common/stm32/Kconfig.uart +++ b/arch/arm/src/common/stm32/Kconfig.uart @@ -1227,6 +1227,286 @@ config UART8_RXFIFO_THRES endif # STM32_UART8 +config USART1_WAKE_FROM_LOW_POWER + bool "USART1 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS && STM32_USART && STM32_USART1_SERIALDRIVER + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config USART1_WUS + int "USART1 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on USART1_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +config USART2_WAKE_FROM_LOW_POWER + bool "USART2 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS && STM32_USART && STM32_USART2_SERIALDRIVER + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config USART2_WUS + int "USART2 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on USART2_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +if STM32_USART3 + +config USART3_WAKE_FROM_LOW_POWER + bool "USART3 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config USART3_WUS + int "USART3 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on USART3_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_USART3 + +if STM32_UART4 + +config UART4_WAKE_FROM_LOW_POWER + bool "UART4 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config UART4_WUS + int "UART4 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on UART4_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_UART4 + +if STM32_UART5 + +config UART5_WAKE_FROM_LOW_POWER + bool "UART5 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config UART5_WUS + int "UART5 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on UART5_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_UART5 + +if STM32_USART6 + +config USART6_WAKE_FROM_LOW_POWER + bool "USART6 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config USART6_WUS + int "USART6 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on USART6_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_USART6 + +if STM32_UART7 + +config UART7_WAKE_FROM_LOW_POWER + bool "UART7 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config UART7_WUS + int "UART7 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on UART7_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_UART7 + +if STM32_UART8 + +config UART8_WAKE_FROM_LOW_POWER + bool "UART8 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config UART8_WUS + int "UART8 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on UART8_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_UART8 + +if STM32_UART9 + +config UART9_WAKE_FROM_LOW_POWER + bool "UART9 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config UART9_WUS + int "UART9 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on UART9_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_UART9 + +if STM32_USART10 + +config USART10_WAKE_FROM_LOW_POWER + bool "USART10 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config USART10_WUS + int "USART10 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on USART10_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_USART10 + +if STM32_USART11 + +config USART11_WAKE_FROM_LOW_POWER + bool "USART11 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config USART11_WUS + int "USART11 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on USART11_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_USART11 + +if STM32_UART12 + +config UART12_WAKE_FROM_LOW_POWER + bool "UART12 Enable wake from low power mode" + default n + depends on STM32_HAVE_USART_WUS + ---help--- + Enable the wake from low power mode interrupt. + NOTE: The UART must be clocked from a clock source which is not disabled during stop + for this to work + +config UART12_WUS + int "UART12 Wake from low power interrupt selection" + default 2 + range 0 3 + depends on UART12_WAKE_FROM_LOW_POWER + ---help--- + 0 = WUF active on address match (as defined by ADD[7:0] and ADDM7) + 1 = Reserved. + 2 = WUF active on start bit detection + 3 = WUF active on RXNE/RXFNE. + +endif # STM32_UART12 + config STM32_USART_INVERT bool "Signal Invert Support" depends on STM32_USART diff --git a/arch/arm/src/stm32h5/Kconfig b/arch/arm/src/stm32h5/Kconfig index 8aba6121e9b..09a0a520970 100644 --- a/arch/arm/src/stm32h5/Kconfig +++ b/arch/arm/src/stm32h5/Kconfig @@ -29,6 +29,7 @@ config STM32_H5_PERIPHERALS select STM32_HAVE_USBDRD_HOST select STM32_HAVE_ADC_H5 select STM32_HAVE_USART_H5 + select STM32_HAVE_USART_WUS select STM32_HAVE_I2C_H5 select STM32_HAVE_CRC select STM32_HAVE_IP_WDG_M3M4_V1 diff --git a/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h b/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h index d9fb24d703e..29415266db5 100644 --- a/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h +++ b/arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h @@ -823,7 +823,7 @@ #define RCC_CCIPR1_USART1SEL_SHIFT (0) #define RCC_CCIPR1_USART1SEL_MASK (7 << RCC_CCIPR1_USART1SEL_SHIFT) -# define RCC_CCIPR1_USART1SEL_RCCPCLK1 (0 << RCC_CCIPR1_USART1SEL_SHIFT) +# define RCC_CCIPR1_USART1SEL_RCCPCLK2 (0 << RCC_CCIPR1_USART1SEL_SHIFT) # define RCC_CCIPR1_USART1SEL_PLL2QCK (1 << RCC_CCIPR1_USART1SEL_SHIFT) # define RCC_CCIPR1_USART1SEL_PLL3QCK (2 << RCC_CCIPR1_USART1SEL_SHIFT) # define RCC_CCIPR1_USART1SEL_HSIKERCK (3 << RCC_CCIPR1_USART1SEL_SHIFT) @@ -866,14 +866,14 @@ # define RCC_CCIPR1_UART5SEL_CSIKERCK (4 << RCC_CCIPR1_UART5SEL_SHIFT) # define RCC_CCIPR1_UART5SEL_LSECK (5 << RCC_CCIPR1_UART5SEL_SHIFT) -#define RCC_CCIPR1_UART6SEL_SHIFT (15) -#define RCC_CCIPR1_UART6SEL_MASK (7 << RCC_CCIPR1_UART6SEL_SHIFT) -# define RCC_CCIPR1_UART6SEL_RCCPCLK1 (0 << RCC_CCIPR1_UART6SEL_SHIFT) -# define RCC_CCIPR1_UART6SEL_PLL2QCK (1 << RCC_CCIPR1_UART6SEL_SHIFT) -# define RCC_CCIPR1_UART6SEL_PLL3QCK (2 << RCC_CCIPR1_UART6SEL_SHIFT) -# define RCC_CCIPR1_UART6SEL_HSIKERCK (3 << RCC_CCIPR1_UART6SEL_SHIFT) -# define RCC_CCIPR1_UART6SEL_CSIKERCK (4 << RCC_CCIPR1_UART6SEL_SHIFT) -# define RCC_CCIPR1_UART6SEL_LSECK (5 << RCC_CCIPR1_UART6SEL_SHIFT) +#define RCC_CCIPR1_USART6SEL_SHIFT (15) +#define RCC_CCIPR1_USART6SEL_MASK (7 << RCC_CCIPR1_USART6SEL_SHIFT) +# define RCC_CCIPR1_USART6SEL_RCCPCLK1 (0 << RCC_CCIPR1_USART6SEL_SHIFT) +# define RCC_CCIPR1_USART6SEL_PLL2QCK (1 << RCC_CCIPR1_USART6SEL_SHIFT) +# define RCC_CCIPR1_USART6SEL_PLL3QCK (2 << RCC_CCIPR1_USART6SEL_SHIFT) +# define RCC_CCIPR1_USART6SEL_HSIKERCK (3 << RCC_CCIPR1_USART6SEL_SHIFT) +# define RCC_CCIPR1_USART6SEL_CSIKERCK (4 << RCC_CCIPR1_USART6SEL_SHIFT) +# define RCC_CCIPR1_USART6SEL_LSECK (5 << RCC_CCIPR1_USART6SEL_SHIFT) #define RCC_CCIPR1_UART7SEL_SHIFT (18) #define RCC_CCIPR1_UART7SEL_MASK (7 << RCC_CCIPR1_UART7SEL_SHIFT) @@ -924,14 +924,14 @@ # define RCC_CCIPR2_USART11SEL_CSIKERCK (4 << RCC_CCIPR2_USART11SEL_SHIFT) # define RCC_CCIPR2_USART11SEL_LSECK (5 << RCC_CCIPR2_USART11SEL_SHIFT) -#define RCC_CCIPR2_USART12SEL_SHIFT (4) -#define RCC_CCIPR2_USART12SEL_MASK (7 << RCC_CCIPR2_USART12SEL_SHIFT) -# define RCC_CCIPR2_USART12SEL_RCCPCLK1 (0 << RCC_CCIPR2_USART12SEL_SHIFT) -# define RCC_CCIPR2_USART12SEL_PLL2QCK (1 << RCC_CCIPR2_USART12SEL_SHIFT) -# define RCC_CCIPR2_USART12SEL_PLL3QCK (2 << RCC_CCIPR2_USART12SEL_SHIFT) -# define RCC_CCIPR2_USART12SEL_HSIKERCK (3 << RCC_CCIPR2_USART12SEL_SHIFT) -# define RCC_CCIPR2_USART12SEL_CSIKERCK (4 << RCC_CCIPR2_USART12SEL_SHIFT) -# define RCC_CCIPR2_USART12SEL_LSECK (5 << RCC_CCIPR2_USART12SEL_SHIFT) +#define RCC_CCIPR2_UART12SEL_SHIFT (4) +#define RCC_CCIPR2_UART12SEL_MASK (7 << RCC_CCIPR2_UART12SEL_SHIFT) +# define RCC_CCIPR2_UART12SEL_RCCPCLK1 (0 << RCC_CCIPR2_UART12SEL_SHIFT) +# define RCC_CCIPR2_UART12SEL_PLL2QCK (1 << RCC_CCIPR2_UART12SEL_SHIFT) +# define RCC_CCIPR2_UART12SEL_PLL3QCK (2 << RCC_CCIPR2_UART12SEL_SHIFT) +# define RCC_CCIPR2_UART12SEL_HSIKERCK (3 << RCC_CCIPR2_UART12SEL_SHIFT) +# define RCC_CCIPR2_UART12SEL_CSIKERCK (4 << RCC_CCIPR2_UART12SEL_SHIFT) +# define RCC_CCIPR2_UART12SEL_LSECK (5 << RCC_CCIPR2_UART12SEL_SHIFT) #define RCC_CCIPR2_LPTIM1SEL_SHIFT (8) #define RCC_CCIPR2_LPTIM1SEL_MASK (7 << RCC_CCIPR2_LPTIM1SEL_SHIFT) diff --git a/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h b/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h index 3e9cf171976..06bde190cf3 100644 --- a/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h +++ b/arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h @@ -277,14 +277,19 @@ #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_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 */ @@ -350,6 +355,27 @@ #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 */ @@ -396,6 +422,11 @@ #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 */ diff --git a/arch/arm/src/stm32h5/stm32_serial.c b/arch/arm/src/stm32h5/stm32_serial.c index 361c67872be..08dc366471f 100644 --- a/arch/arm/src/stm32h5/stm32_serial.c +++ b/arch/arm/src/stm32h5/stm32_serial.c @@ -150,6 +150,198 @@ #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 ****************************************************************************/ @@ -157,8 +349,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. */ @@ -194,7 +386,7 @@ struct stm32_serial_s const uint32_t baud; /* Configured baud */ #endif const uint8_t irq; /* IRQ associated with this USART */ - const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + 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 */ @@ -228,6 +420,8 @@ struct stm32_serial_s 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_* */ }; /**************************************************************************** @@ -536,7 +730,7 @@ static struct stm32_serial_s g_usart1priv = .bits = CONFIG_USART1_BITS, .stopbits2 = CONFIG_USART1_2STOP, .baud = CONFIG_USART1_BAUD, - .apbclock = STM32_PCLK2_FREQUENCY, + .apbclock = STM32_USART1_FREQUENCY, .usartbase = STM32_USART1_BASE, .tx_gpio = GPIO_USART1_TX, .rx_gpio = GPIO_USART1_RX, @@ -576,6 +770,10 @@ static struct stm32_serial_s g_usart1priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_USART1_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART1_WUS) + .wakefromlowpower = true, + .wus = CONFIG_USART1_WUS, +#endif }; #endif @@ -613,7 +811,7 @@ static struct stm32_serial_s g_usart2priv = .bits = CONFIG_USART2_BITS, .stopbits2 = CONFIG_USART2_2STOP, .baud = CONFIG_USART2_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_USART2_FREQUENCY, .usartbase = STM32_USART2_BASE, .tx_gpio = GPIO_USART2_TX, .rx_gpio = GPIO_USART2_RX, @@ -653,6 +851,10 @@ static struct stm32_serial_s g_usart2priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_USART2_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART2_WUS) + .wakefromlowpower = true, + .wus = CONFIG_USART2_WUS, +#endif }; #endif @@ -690,7 +892,7 @@ static struct stm32_serial_s g_usart3priv = .bits = CONFIG_USART3_BITS, .stopbits2 = CONFIG_USART3_2STOP, .baud = CONFIG_USART3_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_USART3_FREQUENCY, .usartbase = STM32_USART3_BASE, .tx_gpio = GPIO_USART3_TX, .rx_gpio = GPIO_USART3_RX, @@ -730,6 +932,10 @@ static struct stm32_serial_s g_usart3priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_USART3_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART3_WUS) + .wakefromlowpower = true, + .wus = CONFIG_USART3_WUS, +#endif }; #endif @@ -775,7 +981,7 @@ static struct stm32_serial_s g_uart4priv = .rts_gpio = GPIO_UART4_RTS, # endif .baud = CONFIG_UART4_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_UART4_FREQUENCY, .usartbase = STM32_UART4_BASE, .tx_gpio = GPIO_UART4_TX, .rx_gpio = GPIO_UART4_RX, @@ -807,6 +1013,10 @@ static struct stm32_serial_s g_uart4priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_UART4_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART4_WUS) + .wakefromlowpower = true, + .wus = CONFIG_UART4_WUS, +#endif }; #endif @@ -852,7 +1062,7 @@ static struct stm32_serial_s g_uart5priv = .rts_gpio = GPIO_UART5_RTS, # endif .baud = CONFIG_UART5_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_UART5_FREQUENCY, .usartbase = STM32_UART5_BASE, .tx_gpio = GPIO_UART5_TX, .rx_gpio = GPIO_UART5_RX, @@ -884,6 +1094,10 @@ static struct stm32_serial_s g_uart5priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_UART5_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART5_WUS) + .wakefromlowpower = true, + .wus = CONFIG_UART5_WUS, +#endif }; #endif @@ -921,7 +1135,7 @@ static struct stm32_serial_s g_usart6priv = .bits = CONFIG_USART6_BITS, .stopbits2 = CONFIG_USART6_2STOP, .baud = CONFIG_USART6_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_USART6_FREQUENCY, .usartbase = STM32_USART6_BASE, .tx_gpio = GPIO_USART6_TX, .rx_gpio = GPIO_USART6_RX, @@ -961,6 +1175,10 @@ static struct stm32_serial_s g_usart6priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_USART6_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART6_WUS) + .wakefromlowpower = true, + .wus = CONFIG_USART6_WUS, +#endif }; #endif @@ -1006,7 +1224,7 @@ static struct stm32_serial_s g_uart7priv = .rts_gpio = GPIO_UART7_RTS, # endif .baud = CONFIG_UART7_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_UART7_FREQUENCY, .usartbase = STM32_UART7_BASE, .tx_gpio = GPIO_UART7_TX, .rx_gpio = GPIO_UART7_RX, @@ -1038,6 +1256,10 @@ static struct stm32_serial_s g_uart7priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_UART7_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART7_WUS) + .wakefromlowpower = true, + .wus = CONFIG_UART7_WUS, +#endif }; #endif @@ -1083,7 +1305,7 @@ static struct stm32_serial_s g_uart8priv = .rts_gpio = GPIO_UART8_RTS, # endif .baud = CONFIG_UART8_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_UART8_FREQUENCY, .usartbase = STM32_UART8_BASE, .tx_gpio = GPIO_UART8_TX, .rx_gpio = GPIO_UART8_RX, @@ -1115,6 +1337,10 @@ static struct stm32_serial_s g_uart8priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_UART8_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART8_WUS) + .wakefromlowpower = true, + .wus = CONFIG_UART8_WUS, +#endif }; #endif @@ -1160,7 +1386,7 @@ static struct stm32_serial_s g_uart9priv = .rts_gpio = GPIO_UART9_RTS, # endif .baud = CONFIG_UART9_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_UART9_FREQUENCY, .usartbase = STM32_UART9_BASE, .tx_gpio = GPIO_UART9_TX, .rx_gpio = GPIO_UART9_RX, @@ -1192,6 +1418,10 @@ static struct stm32_serial_s g_uart9priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_UART9_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART9_WUS) + .wakefromlowpower = true, + .wus = CONFIG_UART9_WUS, +#endif }; #endif @@ -1229,7 +1459,7 @@ static struct stm32_serial_s g_usart10priv = .bits = CONFIG_USART10_BITS, .stopbits2 = CONFIG_USART10_2STOP, .baud = CONFIG_USART10_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_USART10_FREQUENCY, .usartbase = STM32_USART10_BASE, .tx_gpio = GPIO_USART10_TX, .rx_gpio = GPIO_USART10_RX, @@ -1269,6 +1499,10 @@ static struct stm32_serial_s g_usart10priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_USART10_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART10_WUS) + .wakefromlowpower = true, + .wus = CONFIG_USART10_WUS, +#endif }; #endif @@ -1306,7 +1540,7 @@ static struct stm32_serial_s g_usart11priv = .bits = CONFIG_USART11_BITS, .stopbits2 = CONFIG_USART11_2STOP, .baud = CONFIG_USART11_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_USART11_FREQUENCY, .usartbase = STM32_USART11_BASE, .tx_gpio = GPIO_USART11_TX, .rx_gpio = GPIO_USART11_RX, @@ -1346,6 +1580,10 @@ static struct stm32_serial_s g_usart11priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_USART11_WAKE_FROM_LOW_POWER) && defined(CONFIG_USART11_WUS) + .wakefromlowpower = true, + .wus = CONFIG_USART11_WUS, +#endif }; #endif @@ -1391,7 +1629,7 @@ static struct stm32_serial_s g_uart12priv = .rts_gpio = GPIO_UART12_RTS, # endif .baud = CONFIG_UART12_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .apbclock = STM32_UART12_FREQUENCY, .usartbase = STM32_UART12_BASE, .tx_gpio = GPIO_UART12_TX, .rx_gpio = GPIO_UART12_RX, @@ -1423,6 +1661,10 @@ static struct stm32_serial_s g_uart12priv = USART_UNCONFIGURE_DIR #endif , +#if defined(CONFIG_UART12_WAKE_FROM_LOW_POWER) && defined(CONFIG_UART12_WUS) + .wakefromlowpower = true, + .wus = CONFIG_UART12_WUS, +#endif }; #endif @@ -2239,19 +2481,21 @@ 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); #ifdef CONFIG_STM32_LPUART1 if (priv->islpuart == true) { - regval &= ~(USART_CR1_TE | USART_CR1_RE | LPUART_CR1_ALLINTS); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + LPUART_CR1_ALLINTS); } else #endif { - regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); + regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | + USART_CR1_ALLINTS); } stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); @@ -2262,7 +2506,13 @@ static int stm32serial_setup(struct uart_dev_s *dev) regval = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET); regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | - USART_CR3_EIE); + 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); @@ -2273,7 +2523,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 */ @@ -2622,6 +2873,7 @@ static int stm32serial_interrupt(int irq, void *context, void *arg) * " " 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. @@ -2646,6 +2898,13 @@ static int stm32serial_interrupt(int irq, void *context, void *arg) } #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 && diff --git a/arch/arm/src/stm32h5/stm32h5xx_rcc.c b/arch/arm/src/stm32h5/stm32h5xx_rcc.c index 049d9cdb464..b73b90aa9ce 100644 --- a/arch/arm/src/stm32h5/stm32h5xx_rcc.c +++ b/arch/arm/src/stm32h5/stm32h5xx_rcc.c @@ -706,6 +706,91 @@ static inline void rcc_enableapb3(void) static inline void rcc_enableccip(void) { + /* Configure UART source clock */ +#if defined(STM32_RCC_CCIPR1_USART1SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_USART1SEL_MASK; + regval |= STM32_RCC_CCIPR1_USART1SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_USART2SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_USART2SEL_MASK; + regval |= STM32_RCC_CCIPR1_USART2SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_USART3SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_USART3SEL_MASK; + regval |= STM32_RCC_CCIPR1_USART3SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_UART4SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_UART4SEL_MASK; + regval |= STM32_RCC_CCIPR1_UART4SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_UART5SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_UART5SEL_MASK; + regval |= STM32_RCC_CCIPR1_UART5SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_USART6SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_USART6SEL_MASK; + regval |= STM32_RCC_CCIPR1_USART6SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_UART7SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_UART7SEL_MASK; + regval |= STM32_RCC_CCIPR1_UART7SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_UART8SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_UART8SEL_MASK; + regval |= STM32_RCC_CCIPR1_UART8SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_UART9SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_UART9SEL_MASK; + regval |= STM32_RCC_CCIPR1_UART9SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR1_USART10SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR1); + + regval &= ~RCC_CCIPR1_USART10SEL_MASK; + regval |= STM32_RCC_CCIPR1_USART10SEL; + putreg32(regval, STM32_RCC_CCIPR1); +#endif +#if defined(STM32_RCC_CCIPR2_USART11SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR2); + + regval &= ~RCC_CCIPR2_USART11SEL_MASK; + regval |= STM32_RCC_CCIPR2_USART11SEL; + putreg32(regval, STM32_RCC_CCIPR2); +#endif +#if defined(STM32_RCC_CCIPR2_UART12SEL) + uint32_t regval = getreg32(STM32_RCC_CCIPR2); + + regval &= ~RCC_CCIPR2_UART12SEL_MASK; + regval |= STM32_RCC_CCIPR2_UART12SEL; + putreg32(regval, STM32_RCC_CCIPR2); +#endif } /**************************************************************************** @@ -876,6 +961,9 @@ void stm32_stdclockconfig(void) regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_HSION; /* Enable HSI */ +#ifdef STM32_BOARD_HSIKERON_ENABLE + regval |= RCC_CR_HSIKERON; /* Keep HSI on during stop mode */ +#endif #if defined(STM32_BOARD_HSIDIV) regval &= ~RCC_CR_HSIDIV_MASK; @@ -1025,6 +1113,12 @@ void stm32_stdclockconfig(void) regval |= RCC_CR_PLL2ON; putreg32(regval, STM32_RCC_CR); + /* Wait until PLL2 is ready */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL2RDY) == 0) + { + } + #ifdef STM32_PLLCFG_PLL2FRACR regval = STM32_PLLCFG_PLL2FRACR; putreg32(regval, STM32_RCC_PLL2FRACR);