This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit fa1d52a64dc5b18eef6b418fc435007f7873f006
Author: Liam Howatt <[email protected]>
AuthorDate: Fri Sep 18 14:34:18 2026 -0400

    arch/arm/stm32h5: Add USART wake from low power.
    
    Support USART waking from low power modes, allow keeping
    HSI running in STOP mode, allow specifying clock source
    for USARTs, add some missing register and field definitions.
    
    stm32 common Kconfigs:
    Add common STM32 UART config options USARTx_WAKE_FROM_LOW_POWER and 
USARTx_WUS
    for USART to cause wake up from low power modes.
    
    stm32h5 board configs:
    Allow board.h to choose the clock source of each USART.
    Allow board.h to express that HSI should continue running
    in low power modes.
    
    stm32h5 RCC:
    Set the clock source for each USART if specified in the
    board configs (STM32_RCC_CCIPR1_USARTxSEL).
    Keep HSI on in STOP mode if specified in the board configs
    (STM32_BOARD_HSIKERON_ENABLE).
    
    stm32h5 serial driver:
    Use the new USARTx_WAKE_FROM_LOW_POWER and USARTx_WUS in
    stm32h5 serial driver to wake from low power modes.
    Use the USART clock source specified by board configs.
    Enable FIFOs.
    Clear UE bit before initialization.
    
    Co-authored-by: Javier Casas <[email protected]>
    Co-authored-by: daniellizewski <[email protected]>
    Signed-off-by: Liam Howatt <[email protected]>
---
 arch/arm/src/common/stm32/Kconfig.have          |   3 +
 arch/arm/src/common/stm32/Kconfig.uart          | 280 ++++++++++++++++++++++
 arch/arm/src/stm32h5/Kconfig                    |   1 +
 arch/arm/src/stm32h5/hardware/stm32h5xxx_rcc.h  |  34 +--
 arch/arm/src/stm32h5/hardware/stm32h5xxx_uart.h |  33 ++-
 arch/arm/src/stm32h5/stm32_serial.c             | 299 ++++++++++++++++++++++--
 arch/arm/src/stm32h5/stm32h5xx_rcc.c            |  94 ++++++++
 7 files changed, 706 insertions(+), 38 deletions(-)

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);

Reply via email to