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 72c1377e970eb8d673f688b8ab000202986dda97
Author: Darryl Ring <[email protected]>
AuthorDate: Tue Oct 6 16:32:13 2026 -0700

    arch/arm/stm32h5: Add capture support
    
    Clone the capture support from the STM32H7.
    
    Assisted-by: Claude:claude-sonnet-5-5
    Signed-off-by: Darryl Ring <[email protected]>
---
 .../arm/stm32h5/boards/nucleo-h563zi/index.rst     |    9 +
 Documentation/platforms/arm/stm32h5/index.rst      |   28 +
 arch/arm/src/common/stm32/Kconfig.tim              |   80 +-
 arch/arm/src/stm32h5/CMakeLists.txt                |    7 +
 arch/arm/src/stm32h5/Make.defs                     |    7 +
 arch/arm/src/stm32h5/hardware/stm32h50xxx_pinmap.h |   48 +
 arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h |   68 +
 arch/arm/src/stm32h5/stm32_capture.c               | 1331 ++++++++++++++++++++
 arch/arm/src/stm32h5/stm32_capture.h               |  240 ++++
 arch/arm/src/stm32h5/stm32_capture_lowerhalf.c     |  529 ++++++++
 .../nucleo-h563zi/configs/capture/defconfig        |   56 +
 boards/arm/stm32h5/nucleo-h563zi/include/board.h   |    7 +
 .../arm/stm32h5/nucleo-h563zi/src/stm32_bringup.c  |   83 ++
 13 files changed, 2457 insertions(+), 36 deletions(-)

diff --git a/Documentation/platforms/arm/stm32h5/boards/nucleo-h563zi/index.rst 
b/Documentation/platforms/arm/stm32h5/boards/nucleo-h563zi/index.rst
index 18244d39b2d..460a1f6ac7e 100644
--- a/Documentation/platforms/arm/stm32h5/boards/nucleo-h563zi/index.rst
+++ b/Documentation/platforms/arm/stm32h5/boards/nucleo-h563zi/index.rst
@@ -159,6 +159,15 @@ accessed at pin D6 on the CN10 A0 connector. TIM1_CH1 is 
configured
 as a pwm output at /dev/pwm0, and can be tested with the example pwm
 application.
 
+capture:
+--------
+
+This configuration configures TIM4 as a capture timer to measure the frequency 
and
+the duty cycle of a PWM input signal on TIM4_CH1 (pin PB6). It is registered at
+/dev/cap0 and can be tested with the example capture application (``cap``), 
which prints
+the measured frequency and duty cycle. The capture counter runs at 100 kHz, so 
only
+input signals that have a period of up to 655 ms (down to about 1.5 Hz) can be 
measured.
+
 adc_watchdog:
 --------------
 
diff --git a/Documentation/platforms/arm/stm32h5/index.rst 
b/Documentation/platforms/arm/stm32h5/index.rst
index 5cd754c7890..c3a7021b5b4 100644
--- a/Documentation/platforms/arm/stm32h5/index.rst
+++ b/Documentation/platforms/arm/stm32h5/index.rst
@@ -116,6 +116,34 @@ Options:
 
 - STM32H5_USBDRD_DESCSIZE - Maximum size of a descriptor.  Default: 128
 
+Timer Capture
+-------------
+
+The STM32H5 timer capture driver measures the frequency and the duty cycle of
+a PWM input signal using the PWM input mode of the timer. It is registered as
+``/dev/cap0``, ``/dev/cap1``, ... (see ``include/nuttx/timers/capture.h``).
+
+Only the timers with two input channels can be used: TIM1, TIM2, TIM3, TIM4,
+TIM5, TIM8, TIM12 and TIM15.
+
+Pre-requisites:
+
+- ``CONFIG_CAPTURE`` - Enable the upper-half capture driver
+- ``CONFIG_STM32_TIMn`` and ``CONFIG_STM32_TIMn_CAP`` - Reserve timer ``n`` 
for capture
+
+Options:
+
+- ``CONFIG_STM32_TIMn_CHANNEL`` - The input channel, 1 or 2. The signal is 
measured
+  on the pin of that channel. The other channel is mapped internally to the 
same input.
+- ``CONFIG_STM32_TIMn_CLOCK`` - The counter frequency. It limits the resolution
+  of the measurement and the lowest frequency that can be measured (the 
counter must not
+  overflow within a period of the input signal).
+
+The board must define the pin of the selected channel in ``board.h``, e.g.
+``GPIO_TIM4_CH1IN`` (see ``GPIO_TIMn_CHmIN_x`` in the pin map) and register 
the drivers
+with ``stm32_cap_initialize()`` and ``cap_register_multiple()``, see the 
nucleo-h563zi
+board for an example.
+
 OTP
 ---
 
diff --git a/arch/arm/src/common/stm32/Kconfig.tim 
b/arch/arm/src/common/stm32/Kconfig.tim
index aae4d6ba70a..333d51695b9 100644
--- a/arch/arm/src/common/stm32/Kconfig.tim
+++ b/arch/arm/src/common/stm32/Kconfig.tim
@@ -137,7 +137,7 @@ endmenu # Timer Configuration
 
 config STM32_TIMX_CAP
        bool "Helpers for Capture Drivers"
-       depends on ARCH_CHIP_STM32H7
+       depends on ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5
        default n
 
 choice
@@ -1229,8 +1229,9 @@ config STM32_TIM1_CH6OUT
 
 config STM32_TIM1_CHANNEL
        int "TIM1 PWM Output Channel"
-       depends on (STM32_TIM1_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM1_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM1_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM1_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 || 
ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM1_CAP
        range 1 6 if ARCH_CHIP_STM32H7 && STM32_TIM1_CAP
        range 1 4 if !ARCH_CHIP_STM32H7 || !STM32_TIM1_CAP
        ---help---
@@ -1373,8 +1374,9 @@ config STM32_TIM2_CH4OUT
 
 config STM32_TIM2_CHANNEL
        int "TIM2 PWM Output Channel"
-       depends on (STM32_TIM2_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM2_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM2_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM2_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 || 
ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM2_CAP
        range 1 4
        ---help---
                If TIM2 is enabled for PWM usage, you also need specifies the 
timer output
@@ -1516,8 +1518,9 @@ config STM32_TIM3_CH4OUT
 
 config STM32_TIM3_CHANNEL
        int "TIM3 PWM Output Channel"
-       depends on (STM32_TIM3_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM3_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM3_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM3_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 || 
ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM3_CAP
        range 1 4
        ---help---
                If TIM3 is enabled for PWM usage, you also need specifies the 
timer output
@@ -1659,8 +1662,9 @@ config STM32_TIM4_CH4OUT
 
 config STM32_TIM4_CHANNEL
        int "TIM4 PWM Output Channel"
-       depends on (STM32_TIM4_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM4_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM4_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM4_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 || 
ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM4_CAP
        range 1 4
        ---help---
                If TIM4 is enabled for PWM usage, you also need specifies the 
timer output
@@ -1802,8 +1806,9 @@ config STM32_TIM5_CH4OUT
 
 config STM32_TIM5_CHANNEL
        int "TIM5 PWM Output Channel"
-       depends on (STM32_TIM5_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM5_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM5_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM5_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 || 
ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM5_CAP
        range 1 4
        ---help---
                If TIM5 is enabled for PWM usage, you also need specifies the 
timer output
@@ -2042,8 +2047,9 @@ config STM32_TIM8_CH6OUT
 
 config STM32_TIM8_CHANNEL
        int "TIM8 PWM Output Channel"
-       depends on (STM32_TIM8_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM8_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM8_PWM && !STM32_PWM_MULTICHAN) || (STM32_TIM8_CAP 
&& ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 || 
ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM8_CAP
        range 1 6 if ARCH_CHIP_STM32H7 && STM32_TIM8_CAP
        range 1 4 if !ARCH_CHIP_STM32H7 || !STM32_TIM8_CAP
        ---help---
@@ -2305,8 +2311,9 @@ config STM32_TIM12_CH2OUT
 
 config STM32_TIM12_CHANNEL
        int "TIM12 PWM Output Channel"
-       depends on (STM32_TIM12_PWM && !STM32_PWM_MULTICHAN) || 
(STM32_TIM12_CAP && ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7))
+       depends on (STM32_TIM12_PWM && !STM32_PWM_MULTICHAN) || 
(STM32_TIM12_CAP && ((STM32_HAVE_IP_TIMERS && STM32_TIM) || ARCH_CHIP_STM32H7 
|| ARCH_CHIP_STM32H5))
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM12_CAP
        range 1 4 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM12_CAP
        range 1 2 if !STM32_HAVE_IP_TIMERS || !STM32_TIM12_CAP
        ---help---
@@ -2531,8 +2538,9 @@ config STM32_TIM15_CH2OUT
 
 config STM32_TIM15_CHANNEL
        int "TIM15 PWM Output Channel"
-       depends on (STM32_TIM15_PWM && !STM32_PWM_MULTICHAN) || 
(ARCH_CHIP_STM32H7 && STM32_TIM15_CAP)
+       depends on (STM32_TIM15_PWM && !STM32_PWM_MULTICHAN) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM15_CAP)
        default 1
+       range 1 2 if ARCH_CHIP_STM32H5 && STM32_TIM15_CAP
        range 1 2
        ---help---
                If TIM15 is enabled for PWM usage, you also need specifies the 
timer output
@@ -2799,7 +2807,7 @@ config STM32_TIM1_CAP
        bool "TIM1 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM1 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM1 || STM32_COMMON_L4_L5_U5 && 
STM32_HAVE_TIM1
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM1
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM1
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM1
        ---help---
                Reserve timer 1 for use by Capture
 
@@ -2808,9 +2816,9 @@ config STM32_TIM1_CAP
 
 config STM32_TIM1_CLOCK
        int "TIM1 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM1_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM1_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM1_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM1_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM1_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM1_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM1_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
@@ -2818,7 +2826,7 @@ config STM32_TIM2_CAP
        bool "TIM2 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM2 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM2 || STM32_COMMON_L4_L5_U5 && 
STM32_HAVE_TIM2
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM2
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM2
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM2
        ---help---
                Reserve timer 2 for use by Capture
 
@@ -2827,9 +2835,9 @@ config STM32_TIM2_CAP
 
 config STM32_TIM2_CLOCK
        int "TIM2 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM2_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM2_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM2_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM2_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM2_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM2_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM2_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
@@ -2837,7 +2845,7 @@ config STM32_TIM3_CAP
        bool "TIM3 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM3 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM3 || STM32_COMMON_L4_L5_U5 && 
STM32_HAVE_TIM3
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM3
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM3
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM3
        ---help---
                Reserve timer 3 for use by Capture
 
@@ -2846,9 +2854,9 @@ config STM32_TIM3_CAP
 
 config STM32_TIM3_CLOCK
        int "TIM3 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM3_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM3_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM3_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM3_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM3_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM3_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM3_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
@@ -2856,7 +2864,7 @@ config STM32_TIM4_CAP
        bool "TIM4 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM4 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM4 || STM32_COMMON_L4_L5_U5 && 
STM32_HAVE_TIM4
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM4
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM4
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM4
        ---help---
                Reserve timer 4 for use by Capture
 
@@ -2865,9 +2873,9 @@ config STM32_TIM4_CAP
 
 config STM32_TIM4_CLOCK
        int "TIM4 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM4_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM4_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM4_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM4_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM4_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM4_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM4_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
@@ -2875,7 +2883,7 @@ config STM32_TIM5_CAP
        bool "TIM5 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM5 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM5 || STM32_COMMON_L4_L5_U5 && 
STM32_HAVE_TIM5
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM5
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM5
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM5
        ---help---
                Reserve timer 5 for use by Capture
 
@@ -2884,9 +2892,9 @@ config STM32_TIM5_CAP
 
 config STM32_TIM5_CLOCK
        int "TIM5 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM5_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM5_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM5_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM5_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM5_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM5_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM5_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
@@ -2894,7 +2902,7 @@ config STM32_TIM8_CAP
        bool "TIM8 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM8 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM8 || STM32_COMMON_L4_L5_U5 && 
STM32_HAVE_TIM8
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM8
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM8
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM8
        ---help---
                Reserve timer 8 for use by Capture
 
@@ -2903,9 +2911,9 @@ config STM32_TIM8_CAP
 
 config STM32_TIM8_CLOCK
        int "TIM8 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM8_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM8_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM8_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM8_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM8_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM8_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM8_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
@@ -2943,7 +2951,7 @@ config STM32_TIM12_CAP
        bool "TIM12 Capture"
        depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM12 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM12
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM12
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM12
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM12
        ---help---
                Reserve timer 12 for use by Capture
 
@@ -2952,15 +2960,15 @@ config STM32_TIM12_CAP
 
 config STM32_TIM12_CLOCK
        int "TIM12 work frequency for capture"
-       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM12_CAP) || 
(ARCH_CHIP_STM32H7 && STM32_TIM12_CAP)
+       depends on (STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM12_CAP) || 
((ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM12_CAP)
        default 1000000 if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM12_CAP
-       default 100000 if ARCH_CHIP_STM32H7 && STM32_TIM12_CAP
+       default 100000 if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM12_CAP
        ---help---
                This clock frequency limiting the count rate at the expense of 
resolution.
 
 config STM32_TIM13_CAP
        bool "TIM13 Capture"
-       depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM13 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM13
+       depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM13 || 
(STM32_COMMON_F7_H7) && STM32_TIM13
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM13
        select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM13
        ---help---
@@ -2979,7 +2987,7 @@ config STM32_TIM13_CLOCK
 
 config STM32_TIM14_CAP
        bool "TIM14 Capture"
-       depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM14 || 
(STM32_COMMON_F7_H7_H5) && STM32_TIM14
+       depends on STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM14 || 
(STM32_COMMON_F7_H7) && STM32_TIM14
        select STM32_CAP if STM32_HAVE_IP_TIMERS && STM32_TIM && STM32_TIM14
        select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM14
        ---help---
@@ -3893,27 +3901,27 @@ config STM32_TIM17_CH1NOUT
 config STM32_TIM15_CAP
        bool "TIM15 Capture"
        depends on STM32_COMMON_H7_H5 && STM32_TIM15
-       select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM15
+       select STM32_TIMX_CAP if (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && 
STM32_TIM15
        ---help---
                Reserve timer 15 for use by the capture driver.
 
 config STM32_TIM16_CAP
        bool "TIM16 Capture"
-       depends on STM32_COMMON_H7_H5 && STM32_TIM16
+       depends on ARCH_CHIP_STM32H7 && STM32_TIM16
        select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM16
        ---help---
                Reserve timer 16 for use by the capture driver.
 
 config STM32_TIM17_CAP
        bool "TIM17 Capture"
-       depends on STM32_COMMON_H7_H5 && STM32_TIM17
+       depends on ARCH_CHIP_STM32H7 && STM32_TIM17
        select STM32_TIMX_CAP if ARCH_CHIP_STM32H7 && STM32_TIM17
        ---help---
                Reserve timer 17 for use by the capture driver.
 
 config STM32_TIM15_CLOCK
        int "TIM15 capture frequency (Hz)"
-       depends on ARCH_CHIP_STM32H7 && STM32_TIM15_CAP
+       depends on (ARCH_CHIP_STM32H7 || ARCH_CHIP_STM32H5) && STM32_TIM15_CAP
        default 100000
        ---help---
                This clock frequency determines the timer's counting rate.
diff --git a/arch/arm/src/stm32h5/CMakeLists.txt 
b/arch/arm/src/stm32h5/CMakeLists.txt
index 6d7386c87a5..1284ecfa936 100644
--- a/arch/arm/src/stm32h5/CMakeLists.txt
+++ b/arch/arm/src/stm32h5/CMakeLists.txt
@@ -104,6 +104,13 @@ if(CONFIG_STM32_PWM)
   list(APPEND SRCS stm32_pwm.c)
 endif()
 
+if(CONFIG_STM32_TIMX_CAP)
+  list(APPEND SRCS stm32_capture.c)
+  if(CONFIG_CAPTURE)
+    list(APPEND SRCS stm32_capture_lowerhalf.c)
+  endif()
+endif()
+
 # Required chip type specific files
 
 if(CONFIG_STM32_STM32H5XXXX)
diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs
index 99525ed6615..1c620a10773 100644
--- a/arch/arm/src/stm32h5/Make.defs
+++ b/arch/arm/src/stm32h5/Make.defs
@@ -112,6 +112,13 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32_pwm.c
 endif
 
+ifeq ($(CONFIG_STM32_TIMX_CAP),y)
+CHIP_CSRCS += stm32_capture.c
+ifeq ($(CONFIG_CAPTURE),y)
+CHIP_CSRCS += stm32_capture_lowerhalf.c
+endif
+endif
+
 ifeq ($(CONFIG_PM),y)
 CHIP_CSRCS += stm32_pmstandby.c stm32_pmstop.c
 ifneq ($(CONFIG_ARCH_CUSTOM_PMINIT),y)
diff --git a/arch/arm/src/stm32h5/hardware/stm32h50xxx_pinmap.h 
b/arch/arm/src/stm32h5/hardware/stm32h50xxx_pinmap.h
index e4d36129a10..6aa32be6aea 100644
--- a/arch/arm/src/stm32h5/hardware/stm32h50xxx_pinmap.h
+++ b/arch/arm/src/stm32h5/hardware/stm32h50xxx_pinmap.h
@@ -164,18 +164,26 @@
 /* Timers */
 
 #define GPIO_TIM1_CH1OUT_1     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_TIM1_CH1IN_1      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8)
 #define GPIO_TIM1_CH1OUT_2     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN13)
+#define GPIO_TIM1_CH1IN_2      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN13)
 #define GPIO_TIM1_CH1OUT_3     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7)
+#define GPIO_TIM1_CH1IN_3      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7)
 #define GPIO_TIM1_CH1OUT_4     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)
+#define GPIO_TIM1_CH1IN_4      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6)
 
 #define GPIO_TIM1_CH1NOUT_1    (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN3)
 #define GPIO_TIM1_CH1NOUT_2    (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7)
 #define GPIO_TIM1_CH1NOUT_3    (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13)
 
 #define GPIO_TIM1_CH2OUT_1     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9)
+#define GPIO_TIM1_CH2IN_1      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9)
 #define GPIO_TIM1_CH2OUT_2     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN14)
+#define GPIO_TIM1_CH2IN_2      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN14)
 #define GPIO_TIM1_CH2OUT_3     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4)
+#define GPIO_TIM1_CH2IN_3      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4)
 #define GPIO_TIM1_CH2OUT_4     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6)
+#define GPIO_TIM1_CH2IN_4      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6)
 
 #define GPIO_TIM1_CH2NOUT_1    (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN4)
 #define GPIO_TIM1_CH2NOUT_2    (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0)
@@ -184,18 +192,26 @@
 #define GPIO_TIM1_CH2NOUT_5    (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14)
 
 #define GPIO_TIM1_CH3OUT_1     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_TIM1_CH3IN_1      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1)
 #define GPIO_TIM1_CH3OUT_2     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10)
+#define GPIO_TIM1_CH3IN_2      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10)
 #define GPIO_TIM1_CH3OUT_3     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5)
+#define GPIO_TIM1_CH3IN_3      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5)
 #define GPIO_TIM1_CH3OUT_4     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)
+#define GPIO_TIM1_CH3IN_4      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8)
 
 #define GPIO_TIM1_CH3NOUT_1    (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1)
 #define GPIO_TIM1_CH3NOUT_2    (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN6)
 #define GPIO_TIM1_CH3NOUT_3    (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN15)
 
 #define GPIO_TIM1_CH4OUT_1     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_TIM1_CH4IN_1      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)
 #define GPIO_TIM1_CH4OUT_2     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_TIM1_CH4IN_2      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11)
 #define GPIO_TIM1_CH4OUT_3     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)
+#define GPIO_TIM1_CH4IN_3      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9)
 #define GPIO_TIM1_CH4OUT_4     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12)
+#define GPIO_TIM1_CH4IN_4      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN12)
 
 #define GPIO_TIM1_CH4NOUT_1    (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN8)
 #define GPIO_TIM1_CH4NOUT_2    (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN14)
@@ -203,44 +219,76 @@
 #define GPIO_TIM1_CH4NOUT_4    (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN5)
 
 #define GPIO_TIM2_CH1OUT_1     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_TIM2_CH1IN_1      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)
 #define GPIO_TIM2_CH1OUT_2     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_TIM2_CH1IN_2      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5)
 #define GPIO_TIM2_CH1OUT_3     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15)
+#define GPIO_TIM2_CH1IN_3      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15)
 #define GPIO_TIM2_CH1OUT_4     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN2)
+#define GPIO_TIM2_CH1IN_4      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN2)
 
 #define GPIO_TIM2_CH2OUT_1     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_TIM2_CH2IN_1      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1)
 #define GPIO_TIM2_CH2OUT_2     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_TIM2_CH2IN_2      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3)
 #define GPIO_TIM2_CH2OUT_3     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN11)
+#define GPIO_TIM2_CH2IN_3      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN11)
 
 #define GPIO_TIM2_CH3OUT_1     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_TIM2_CH3IN_1      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)
 #define GPIO_TIM2_CH3OUT_2     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_TIM2_CH3IN_2      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7)
 #define GPIO_TIM2_CH3OUT_3     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10)
+#define GPIO_TIM2_CH3IN_3      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10)
 #define GPIO_TIM2_CH3OUT_4     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2)
+#define GPIO_TIM2_CH3IN_4      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN2)
 
 #define GPIO_TIM2_CH4OUT_1     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_TIM2_CH4IN_1      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3)
 #define GPIO_TIM2_CH4OUT_2     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12)
+#define GPIO_TIM2_CH4IN_2      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12)
 #define GPIO_TIM2_CH4OUT_3     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4)
+#define GPIO_TIM2_CH4IN_3      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN4)
 #define GPIO_TIM2_CH4OUT_4     
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12)
+#define GPIO_TIM2_CH4IN_4      
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN12)
 
 #define GPIO_TIM3_CH1OUT_1     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_TIM3_CH1IN_1      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)
 #define GPIO_TIM3_CH1OUT_2     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM3_CH1IN_2      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6)
 #define GPIO_TIM3_CH1OUT_3     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN14)
+#define GPIO_TIM3_CH1IN_3      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN14)
 #define GPIO_TIM3_CH1OUT_4     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4)
+#define GPIO_TIM3_CH1IN_4      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4)
 #define GPIO_TIM3_CH1OUT_5     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)
+#define GPIO_TIM3_CH1IN_5      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6)
 
 #define GPIO_TIM3_CH2OUT_1     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_TIM3_CH2IN_1      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7)
 #define GPIO_TIM3_CH2OUT_2     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_TIM3_CH2IN_2      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11)
 #define GPIO_TIM3_CH2OUT_3     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5)
+#define GPIO_TIM3_CH2IN_3      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5)
 #define GPIO_TIM3_CH2OUT_4     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7)
+#define GPIO_TIM3_CH2IN_4      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7)
 
 #define GPIO_TIM3_CH3OUT_1     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_TIM3_CH3IN_1      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8)
 #define GPIO_TIM3_CH3OUT_2     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_TIM3_CH3IN_2      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0)
 #define GPIO_TIM3_CH3OUT_3     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6)
+#define GPIO_TIM3_CH3IN_3      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6)
 #define GPIO_TIM3_CH3OUT_4     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)
+#define GPIO_TIM3_CH3IN_4      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8)
 
 #define GPIO_TIM3_CH4OUT_1     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN12)
+#define GPIO_TIM3_CH4IN_1      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN12)
 #define GPIO_TIM3_CH4OUT_2     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_TIM3_CH4IN_2      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1)
 #define GPIO_TIM3_CH4OUT_3     
(GPIO_ALT|GPIO_AF14|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15)
+#define GPIO_TIM3_CH4IN_3      
(GPIO_ALT|GPIO_AF14|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN15)
 #define GPIO_TIM3_CH4OUT_4     
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)
+#define GPIO_TIM3_CH4IN_4      
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9)
 
 /* USART/UART/LPUART */
 
diff --git a/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h 
b/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h
index d88cd64d27c..aca8a176521 100644
--- a/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h
+++ b/arch/arm/src/stm32h5/hardware/stm32h56xxx_pinmap.h
@@ -368,8 +368,11 @@
 /*  TIM1 (AF1)  */
 
 #define GPIO_TIM1_CH1OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8)   /* PA8  */
+#define GPIO_TIM1_CH1IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8)      /* PA8  */
 #define GPIO_TIM1_CH1OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9)   /* PE9  */
+#define GPIO_TIM1_CH1IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN9)      /* PE9  */
 #define GPIO_TIM1_CH1OUT_3        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11)  /* PH11 */
+#define GPIO_TIM1_CH1IN_3         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN11)     /* PH11 */
 
 #define GPIO_TIM1_CH1NOUT_1       (GPIO_ALT|GPIO_AF1|GPIO_PORTA|GPIO_PIN7)   
/* PA7  */
 #define GPIO_TIM1_CH1NOUT_2       (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN13)  
/* PB13 */
@@ -377,8 +380,11 @@
 #define GPIO_TIM1_CH1NOUT_4       (GPIO_ALT|GPIO_AF1|GPIO_PORTH|GPIO_PIN10)  
/* PH10 */
 
 #define GPIO_TIM1_CH2OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9)   /* PA9  */
+#define GPIO_TIM1_CH2IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9)      /* PA9  */
 #define GPIO_TIM1_CH2OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11)  /* PE11 */
+#define GPIO_TIM1_CH2IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN11)     /* PE11 */
 #define GPIO_TIM1_CH2OUT_3        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9)   /* PH9  */
+#define GPIO_TIM1_CH2IN_3         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN9)      /* PH9  */
 
 #define GPIO_TIM1_CH2NOUT_1       (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN0)   
/* PB0  */
 #define GPIO_TIM1_CH2NOUT_2       (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN14)  
/* PB14 */
@@ -386,8 +392,11 @@
 #define GPIO_TIM1_CH2NOUT_4       (GPIO_ALT|GPIO_AF1|GPIO_PORTH|GPIO_PIN8)   
/* PH8  */
 
 #define GPIO_TIM1_CH3OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10)  /* PA10 */
+#define GPIO_TIM1_CH3IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10)     /* PA10 */
 #define GPIO_TIM1_CH3OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13)  /* PE13 */
+#define GPIO_TIM1_CH3IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN13)     /* PE13 */
 #define GPIO_TIM1_CH3OUT_3        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN7)   /* PH7  */
+#define GPIO_TIM1_CH3IN_3         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN7)      /* PH7  */
 
 #define GPIO_TIM1_CH3NOUT_1       (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN1)   
/* PB1  */
 #define GPIO_TIM1_CH3NOUT_2       (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN15)  
/* PB15 */
@@ -395,7 +404,9 @@
 #define GPIO_TIM1_CH3NOUT_4       (GPIO_ALT|GPIO_AF1|GPIO_PORTH|GPIO_PIN6)   
/* PH6  */
 
 #define GPIO_TIM1_CH4OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11)  /* PA11 */
+#define GPIO_TIM1_CH4IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11)     /* PA11 */
 #define GPIO_TIM1_CH4OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14)  /* PE14 */
+#define GPIO_TIM1_CH4IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN14)     /* PE14 */
 
 #define GPIO_TIM1_CH4NOUT_1       (GPIO_ALT|GPIO_AF1|GPIO_PORTE|GPIO_PIN15)  
/* PE15 */
 #define GPIO_TIM1_CH4NOUT_2       (GPIO_ALT|GPIO_AF1|GPIO_PORTC|GPIO_PIN5)   
/* PC5  */
@@ -403,62 +414,98 @@
 /*  TIM2 (AF1)  */
 
 #define GPIO_TIM2_CH1OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)   /* PA0  */
+#define GPIO_TIM2_CH1IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)      /* PA0  */
 #define GPIO_TIM2_CH1OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5)   /* PA5  */
+#define GPIO_TIM2_CH1IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5)      /* PA5  */
 #define GPIO_TIM2_CH1OUT_3        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15)  /* PA15 */
+#define GPIO_TIM2_CH1IN_3         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15)     /* PA15 */
 
 #define GPIO_TIM2_CH2OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)   /* PA1  */
+#define GPIO_TIM2_CH2IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1)      /* PA1  */
 #define GPIO_TIM2_CH2OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3)   /* PB3  */
+#define GPIO_TIM2_CH2IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3)      /* PB3  */
 
 #define GPIO_TIM2_CH3OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)   /* PA2  */
+#define GPIO_TIM2_CH3IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)      /* PA2  */
 #define GPIO_TIM2_CH3OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10)  /* PB10 */
+#define GPIO_TIM2_CH3IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10)     /* PB10 */
 
 #define GPIO_TIM2_CH4OUT_1        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)   /* PA3  */
+#define GPIO_TIM2_CH4IN_1         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3)      /* PA3  */
 #define GPIO_TIM2_CH4OUT_2        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11)  /* PB11 */
+#define GPIO_TIM2_CH4IN_2         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11)     /* PB11 */
 #define GPIO_TIM2_CH4OUT_3        
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN4)   /* PC4  */
+#define GPIO_TIM2_CH4IN_3         
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN4)      /* PC4  */
 
 /*  TIM3 (AF2)  */
 
 #define GPIO_TIM3_CH1OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6)   /* PA6  */
+#define GPIO_TIM3_CH1IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6)      /* PA6  */
 #define GPIO_TIM3_CH1OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4)   /* PB4  */
+#define GPIO_TIM3_CH1IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4)      /* PB4  */
 #define GPIO_TIM3_CH1OUT_3        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)   /* PC6  */
+#define GPIO_TIM3_CH1IN_3         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6)      /* PC6  */
 
 #define GPIO_TIM3_CH2OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)   /* PA7  */
+#define GPIO_TIM3_CH2IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7)      /* PA7  */
 #define GPIO_TIM3_CH2OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5)   /* PB5  */
+#define GPIO_TIM3_CH2IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5)      /* PB5  */
 #define GPIO_TIM3_CH2OUT_3        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7)   /* PC7  */
+#define GPIO_TIM3_CH2IN_3         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7)      /* PC7  */
 
 #define GPIO_TIM3_CH3OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0)   /* PB0  */
+#define GPIO_TIM3_CH3IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0)      /* PB0  */
 #define GPIO_TIM3_CH3OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)   /* PC8  */
+#define GPIO_TIM3_CH3IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8)      /* PC8  */
 
 #define GPIO_TIM3_CH4OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1)   /* PB1  */
+#define GPIO_TIM3_CH4IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1)      /* PB1  */
 #define GPIO_TIM3_CH4OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)   /* PC9  */
+#define GPIO_TIM3_CH4IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9)      /* PC9  */
 
 /*  TIM4 (AF2)  */
 
 #define GPIO_TIM4_CH1OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6)   /* PB6  */
+#define GPIO_TIM4_CH1IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN6)      /* PB6  */
 #define GPIO_TIM4_CH2OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN7)   /* PB7  */
+#define GPIO_TIM4_CH2IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN7)      /* PB7  */
 #define GPIO_TIM4_CH3OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8)   /* PB8  */
+#define GPIO_TIM4_CH3IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8)      /* PB8  */
 #define GPIO_TIM4_CH4OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9)   /* PB9  */
+#define GPIO_TIM4_CH4IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9)      /* PB9  */
 #define GPIO_TIM4_CH4OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2)   /* PC2  */
+#define GPIO_TIM4_CH4IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN2)      /* PC2  */
 
 /*  TIM5 (AF2)  */
 
 #define GPIO_TIM5_CH1OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)   /* PA0  */
+#define GPIO_TIM5_CH1IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)      /* PA0  */
 #define GPIO_TIM5_CH1OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10)  /* PH10 */
+#define GPIO_TIM5_CH1IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10)     /* PH10 */
 
 #define GPIO_TIM5_CH2OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)   /* PA1  */
+#define GPIO_TIM5_CH2IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1)      /* PA1  */
 #define GPIO_TIM5_CH2OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11)  /* PH11 */
+#define GPIO_TIM5_CH2IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN11)     /* PH11 */
 
 #define GPIO_TIM5_CH3OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)   /* PA2  */
+#define GPIO_TIM5_CH3IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)      /* PA2  */
 #define GPIO_TIM5_CH3OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12)  /* PH12 */
+#define GPIO_TIM5_CH3IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN12)     /* PH12 */
 
 #define GPIO_TIM5_CH4OUT_1        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)   /* PA3  */
+#define GPIO_TIM5_CH4IN_1         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3)      /* PA3  */
 #define GPIO_TIM5_CH4OUT_2        
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN0)   /* PI0  */
+#define GPIO_TIM5_CH4IN_2         
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN0)      /* PI0  */
 
 /*  TIM8 (AF3)  */
 
 #define GPIO_TIM8_CH1OUT_1        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)   /* PC6  */
+#define GPIO_TIM8_CH1IN_1         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6)      /* PC6  */
 #define GPIO_TIM8_CH1OUT_2        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN5)   /* PI5  */
+#define GPIO_TIM8_CH1IN_2         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN5)      /* PI5  */
 #define GPIO_TIM8_CH1OUT_3        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6)   /* PH6  */
+#define GPIO_TIM8_CH1IN_3         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6)      /* PH6  */
 
 #define GPIO_TIM8_CH1NOUT_1       (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN5)   
/* PA5  */
 #define GPIO_TIM8_CH1NOUT_2       (GPIO_ALT|GPIO_AF3|GPIO_PORTA|GPIO_PIN7)   
/* PA7  */
@@ -466,8 +513,11 @@
 #define GPIO_TIM8_CH1NOUT_4       (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN13)  
/* PH13 */
 
 #define GPIO_TIM8_CH2OUT_1        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7)   /* PC7  */
+#define GPIO_TIM8_CH2IN_1         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7)      /* PC7  */
 #define GPIO_TIM8_CH2OUT_2        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN6)   /* PI6  */
+#define GPIO_TIM8_CH2IN_2         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN6)      /* PI6  */
 #define GPIO_TIM8_CH2OUT_3        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN8)   /* PH8  */
+#define GPIO_TIM8_CH2IN_3         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN8)      /* PH8  */
 
 #define GPIO_TIM8_CH2NOUT_1       (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN0)   
/* PB0  */
 #define GPIO_TIM8_CH2NOUT_2       (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN14)  
/* PB14 */
@@ -475,8 +525,11 @@
 #define GPIO_TIM8_CH2NOUT_4       (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN14)  
/* PH14 */
 
 #define GPIO_TIM8_CH3OUT_1        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)   /* PC8  */
+#define GPIO_TIM8_CH3IN_1         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8)      /* PC8  */
 #define GPIO_TIM8_CH3OUT_2        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10)  /* PH10 */
+#define GPIO_TIM8_CH3IN_2         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN10)     /* PH10 */
 #define GPIO_TIM8_CH3OUT_3        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN7)   /* PI7  */
+#define GPIO_TIM8_CH3IN_3         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN7)      /* PI7  */
 
 #define GPIO_TIM8_CH3NOUT_1       (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN1)   
/* PB1  */
 #define GPIO_TIM8_CH3NOUT_2       (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN15)  
/* PB15 */
@@ -484,41 +537,56 @@
 #define GPIO_TIM8_CH3NOUT_4       (GPIO_ALT|GPIO_AF3|GPIO_PORTH|GPIO_PIN15)  
/* PH15 */
 
 #define GPIO_TIM8_CH4OUT_1        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)   /* PC9  */
+#define GPIO_TIM8_CH4IN_1         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9)      /* PC9  */
 #define GPIO_TIM8_CH4OUT_2        
(GPIO_ALT|GPIO_AF3|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN2)   /* PI2  */
+#define GPIO_TIM8_CH4IN_2         
(GPIO_ALT|GPIO_AF3|GPIO_FLOAT|GPIO_PORTI|GPIO_PIN2)      /* PI2  */
 
 #define GPIO_TIM8_CH4NOUT_1       (GPIO_ALT|GPIO_AF3|GPIO_PORTB|GPIO_PIN2)   
/* PB2  */
 
 /*  TIM12 (AF2)  */
 
 #define GPIO_TIM12_CH1OUT_1       
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14)  /* PB14 */
+#define GPIO_TIM12_CH1IN_1        
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN14)     /* PB14 */
 #define GPIO_TIM12_CH1OUT_2       
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN6)   /* PH6  */
+#define GPIO_TIM12_CH1IN_2        
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN6)      /* PH6  */
 
 #define GPIO_TIM12_CH2OUT_1       
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15)  /* PB15 */
+#define GPIO_TIM12_CH2IN_1        
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN15)     /* PB15 */
 #define GPIO_TIM12_CH2OUT_2       
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9)   /* PH9  */
+#define GPIO_TIM12_CH2IN_2        
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTH|GPIO_PIN9)      /* PH9  */
 
 /*  TIM15 (AF2/AF4, per pin) */
 
 #define GPIO_TIM15_CH1OUT_1       
(GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)   /* PA2  */
+#define GPIO_TIM15_CH1IN_1        
(GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)      /* PA2  */
 #define GPIO_TIM15_CH1OUT_2       
(GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5)   /* PE5  */
+#define GPIO_TIM15_CH1IN_2        
(GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN5)      /* PE5  */
 #define GPIO_TIM15_CH1OUT_3       
(GPIO_ALT|GPIO_AF2|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN12)  /* PC12 */
+#define GPIO_TIM15_CH1IN_3        
(GPIO_ALT|GPIO_AF2|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN12)     /* PC12 */
 
 #define GPIO_TIM15_CH1NOUT_1      (GPIO_ALT|GPIO_AF4|GPIO_PORTA|GPIO_PIN1)   
/* PA1  */
 #define GPIO_TIM15_CH1NOUT_2      (GPIO_ALT|GPIO_AF4|GPIO_PORTE|GPIO_PIN4)   
/* PE4  */
 
 #define GPIO_TIM15_CH2OUT_1       
(GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)   /* PA3  */
+#define GPIO_TIM15_CH2IN_1        
(GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3)      /* PA3  */
 #define GPIO_TIM15_CH2OUT_2       
(GPIO_ALT|GPIO_AF4|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6)   /* PE6  */
+#define GPIO_TIM15_CH2IN_2        
(GPIO_ALT|GPIO_AF4|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6)      /* PE6  */
 
 /*  TIM16 (AF1)  */
 
 #define GPIO_TIM16_CH1OUT_1       
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8)   /* PB8  */
+#define GPIO_TIM16_CH1IN_1        
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8)      /* PB8  */
 #define GPIO_TIM16_CH1OUT_2       
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN6)   /* PF6  */
+#define GPIO_TIM16_CH1IN_2        
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN6)      /* PF6  */
 #define GPIO_TIM16_CH1NOUT_1      (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN6)     
            /* PB6  */
 #define GPIO_TIM16_CH1NOUT_2      (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN8)     
            /* PF8  */
 
 /*  TIM17 (AF1)  */
 
 #define GPIO_TIM17_CH1OUT_1       
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9)   /* PB9  */
+#define GPIO_TIM17_CH1IN_1        
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN9)      /* PB9  */
 #define GPIO_TIM17_CH1OUT_2       
(GPIO_ALT|GPIO_AF1|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN7)   /* PF7  */
+#define GPIO_TIM17_CH1IN_2        
(GPIO_ALT|GPIO_AF1|GPIO_FLOAT|GPIO_PORTF|GPIO_PIN7)      /* PF7  */
 #define GPIO_TIM17_CH1NOUT_1      (GPIO_ALT|GPIO_AF1|GPIO_PORTB|GPIO_PIN7)     
            /* PB7  */
 #define GPIO_TIM17_CH1NOUT_2      (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN9)     
            /* PF9  */
 
diff --git a/arch/arm/src/stm32h5/stm32_capture.c 
b/arch/arm/src/stm32h5/stm32_capture.c
new file mode 100644
index 00000000000..2c86a07ccae
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_capture.c
@@ -0,0 +1,1331 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_capture.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 <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+#include <nuttx/debug.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "arm_internal.h"
+#include "stm32.h"
+#include "stm32_gpio.h"
+#include "stm32_capture.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Timer Channel Configuration **********************************************/
+
+/* This module only compiles if there are enabled timers that are not
+ * intended for some other purpose.
+ */
+
+#if defined(CONFIG_STM32_TIMX_CAP)
+
+/* Check if any channel is enabled.
+ * This is done to simplify the logic below.
+ */
+
+#if defined(GPIO_TIM1_CH1IN) || defined(GPIO_TIM2_CH1IN) || 
defined(GPIO_TIM3_CH1IN) || \
+    defined(GPIO_TIM4_CH1IN) || defined(GPIO_TIM5_CH1IN) || 
defined(GPIO_TIM8_CH1IN) || \
+    defined(GPIO_TIM12_CH1IN) || defined(GPIO_TIM15_CH1IN)
+#  define HAVE_CH1IN 1
+#endif
+
+#if defined(GPIO_TIM1_CH2IN) || defined(GPIO_TIM2_CH2IN) || 
defined(GPIO_TIM3_CH2IN) || \
+    defined(GPIO_TIM4_CH2IN) || defined(GPIO_TIM5_CH2IN) || 
defined(GPIO_TIM8_CH2IN) || \
+    defined(GPIO_TIM12_CH2IN) || defined(GPIO_TIM15_CH2IN)
+#  define HAVE_CH2IN 1
+#endif
+
+#if defined(GPIO_TIM1_CH3IN) || defined(GPIO_TIM2_CH3IN) || 
defined(GPIO_TIM3_CH3IN) || \
+    defined(GPIO_TIM4_CH3IN) || defined(GPIO_TIM5_CH3IN) || 
defined(GPIO_TIM8_CH3IN)
+#  define HAVE_CH3IN 1
+#endif
+
+#if defined(GPIO_TIM1_CH4IN) || defined(GPIO_TIM2_CH4IN) || 
defined(GPIO_TIM3_CH4IN) || \
+    defined(GPIO_TIM4_CH4IN) || defined(GPIO_TIM5_CH4IN) || 
defined(GPIO_TIM8_CH4IN)
+#  define HAVE_CH4IN 1
+#endif
+
+#if defined(GPIO_TIM1_CH5IN) || defined(GPIO_TIM8_CH5IN)
+#  define HAVE_CH5IN 1
+#endif
+
+#if defined(GPIO_TIM1_CH6IN) || defined(GPIO_TIM8_CH6IN)
+#  define HAVE_CH6IN 1
+#endif
+
+/* Check if we have any advanced timers */
+
+#if defined(CONFIG_STM32_TIM1_CAP) || defined(CONFIG_STM32_TIM8_CAP)
+#  define USE_ADVANCED_TIM 1
+#endif
+
+/* Check if we have any general purpose timers */
+
+#if defined(CONFIG_STM32_TIM2_CAP) || defined(CONFIG_STM32_TIM3_CAP) || \
+    defined(CONFIG_STM32_TIM4_CAP) || defined(CONFIG_STM32_TIM5_CAP) || \
+    defined(CONFIG_STM32_TIM12_CAP) || defined(CONFIG_STM32_TIM15_CAP)
+#  define USE_GENERAL_TIM 1
+#endif
+
+/* Check for external clock signal */
+
+#if defined(GPIO_TIM1_ETR_IN) || defined(GPIO_TIM2_ETR_IN) || 
defined(GPIO_TIM3_ETR_IN) || \
+    defined(GPIO_TIM4_ETR_IN) || defined(GPIO_TIM5_ETR_IN) || 
defined(GPIO_TIM8_ETR_IN)
+#  define USE_EXT_CLOCK 1
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* TIM Device Structure */
+
+struct stm32_cap_priv_s
+{
+  const struct stm32_cap_ops_s *ops;
+  const uint32_t base;      /* TIMn base address */
+#ifdef USE_EXT_CLOCK
+  const uint32_t gpio_clk;  /* TIMn base address */
+#endif
+  const int irq;            /* irq vector */
+#ifdef USE_ADVANCED_TIM
+  const int irq_of;         /* irq timer overflow is deferent in advanced 
timer */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Get a 16-bit register value by offset */
+
+static inline
+uint16_t stm32_getreg16(const struct stm32_cap_priv_s *priv,
+                        uint8_t offset)
+{
+  return getreg16(priv->base + offset);
+}
+
+/* Put a 16-bit register value by offset */
+
+static inline void stm32_putreg16(const struct stm32_cap_priv_s *priv,
+                                  uint8_t offset, uint16_t value)
+{
+  putreg16(value, priv->base + offset);
+}
+
+/* Modify a 16-bit register value by offset */
+
+static inline void stm32_modifyreg16(const struct stm32_cap_priv_s *priv,
+                                     uint8_t offset, uint16_t clearbits,
+                                     uint16_t setbits)
+{
+  modifyreg16(priv->base + offset, clearbits, setbits);
+}
+
+/* Get a 32-bit register value by offset.  This applies only for the STM32 F4
+ * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2 and TIM5.
+ */
+
+static inline
+uint32_t stm32_getreg32(const struct stm32_cap_priv_s *priv,
+                        uint8_t offset)
+{
+  return getreg32(priv->base + offset);
+}
+
+/* Put a 32-bit register value by offset.  This applies only for the STM32 F4
+ * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2 and TIM5.
+ */
+
+static inline void stm32_putreg32(const struct stm32_cap_priv_s *priv,
+                                  uint8_t offset, uint32_t value)
+{
+  putreg32(value, priv->base + offset);
+}
+
+/****************************************************************************
+ * gpio Functions
+ ****************************************************************************/
+
+static inline
+uint32_t stm32_cap_gpio(const struct stm32_cap_priv_s *priv,
+                        int channel)
+{
+  if (channel < 0) /* Special case: return first available channel */
+    {
+      uint32_t gpio;
+
+      /* Try counter channel first */
+
+      gpio = stm32_cap_gpio(priv, STM32_CAP_CHANNEL_COUNTER);
+      if (gpio)
+        {
+          return gpio;
+        }
+
+      /* Then try channels 1..4 */
+
+      for (int ch = 1; ch <= 4; ch++)
+        {
+          gpio = stm32_cap_gpio(priv, ch);
+          if (gpio)
+            {
+              return gpio;
+            }
+        }
+
+      return 0; /* None found */
+    }
+
+  switch (priv->base)
+    {
+#ifdef CONFIG_STM32_TIM1_CAP
+      case STM32_TIM1_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM1_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM1_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM1_CH1IN
+            case 1:
+              return GPIO_TIM1_CH1IN;
+#endif
+#ifdef GPIO_TIM1_CH2IN
+            case 2:
+              return GPIO_TIM1_CH2IN;
+#endif
+#ifdef GPIO_TIM1_CH3IN
+            case 3:
+              return GPIO_TIM1_CH3IN;
+#endif
+#ifdef GPIO_TIM1_CH4IN
+            case 4:
+              return GPIO_TIM1_CH4IN;
+#endif
+          }
+        break;
+#endif
+
+#ifdef CONFIG_STM32_TIM2_CAP
+      case STM32_TIM2_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM2_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM2_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM2_CH1IN
+            case 1:
+              return GPIO_TIM2_CH1IN;
+#endif
+#ifdef GPIO_TIM2_CH2IN
+            case 2:
+              return GPIO_TIM2_CH2IN;
+#endif
+#ifdef GPIO_TIM2_CH3IN
+            case 3:
+              return GPIO_TIM2_CH3IN;
+#endif
+#ifdef GPIO_TIM2_CH4IN
+            case 4:
+              return GPIO_TIM2_CH4IN;
+#endif
+          }
+        break;
+#endif
+
+#ifdef CONFIG_STM32_TIM3_CAP
+      case STM32_TIM3_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM3_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM3_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM3_CH1IN
+            case 1:
+              return GPIO_TIM3_CH1IN;
+#endif
+#ifdef GPIO_TIM3_CH2IN
+            case 2:
+              return GPIO_TIM3_CH2IN;
+#endif
+#ifdef GPIO_TIM3_CH3IN
+            case 3:
+              return GPIO_TIM3_CH3IN;
+#endif
+#ifdef GPIO_TIM3_CH4IN
+            case 4:
+              return GPIO_TIM3_CH4IN;
+#endif
+          }
+        break;
+#endif
+
+#ifdef CONFIG_STM32_TIM4_CAP
+      case STM32_TIM4_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM4_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM4_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM4_CH1IN
+            case 1:
+              return GPIO_TIM4_CH1IN;
+#endif
+#ifdef GPIO_TIM4_CH2IN
+            case 2:
+              return GPIO_TIM4_CH2IN;
+#endif
+#ifdef GPIO_TIM4_CH3IN
+            case 3:
+              return GPIO_TIM4_CH3IN;
+#endif
+#ifdef GPIO_TIM4_CH4IN
+            case 4:
+              return GPIO_TIM4_CH4IN;
+#endif
+          }
+        break;
+#endif
+
+#ifdef CONFIG_STM32_TIM5_CAP
+      case STM32_TIM5_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM5_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM5_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM5_CH1IN
+            case 1:
+              return GPIO_TIM5_CH1IN;
+#endif
+#ifdef GPIO_TIM5_CH2IN
+            case 2:
+              return GPIO_TIM5_CH2IN;
+#endif
+#ifdef GPIO_TIM5_CH3IN
+            case 3:
+              return GPIO_TIM5_CH3IN;
+#endif
+#ifdef GPIO_TIM5_CH4IN
+            case 4:
+              return GPIO_TIM5_CH4IN;
+#endif
+          }
+        break;
+#endif
+
+      /* TIM6 and TIM7 cannot be used in capture */
+
+#ifdef CONFIG_STM32_TIM8_CAP
+      case STM32_TIM8_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM8_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM8_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM8_CH1IN
+            case 1:
+              return GPIO_TIM8_CH1IN;
+#endif
+#ifdef GPIO_TIM8_CH2IN
+            case 2:
+              return GPIO_TIM8_CH2IN;
+#endif
+#ifdef GPIO_TIM8_CH3IN
+            case 3:
+              return GPIO_TIM8_CH3IN;
+#endif
+#ifdef GPIO_TIM8_CH4IN
+            case 4:
+              return GPIO_TIM8_CH4IN;
+#endif
+          }
+        break;
+#endif
+
+#ifdef CONFIG_STM32_TIM12_CAP
+      case STM32_TIM12_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM12_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM12_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM12_CH1IN
+            case 1:
+              return GPIO_TIM12_CH1IN;
+#endif
+#ifdef GPIO_TIM12_CH2IN
+            case 2:
+              return GPIO_TIM12_CH2IN;
+#endif
+          }
+        break;
+#endif
+
+#ifdef CONFIG_STM32_TIM15_CAP
+      case STM32_TIM15_BASE:
+        switch (channel)
+          {
+#ifdef GPIO_TIM15_EXT_CLK_IN
+            case STM32_CAP_CHANNEL_COUNTER:
+              return GPIO_TIM15_EXT_CLK_IN;
+#endif
+#ifdef GPIO_TIM15_CH1IN
+            case 1:
+              return GPIO_TIM15_CH1IN;
+#endif
+#ifdef GPIO_TIM15_CH2IN
+            case 2:
+              return GPIO_TIM15_CH2IN;
+#endif
+          }
+        break;
+#endif
+    }
+
+  return 0;
+}
+
+static inline int stm32_cap_set_rcc(const struct stm32_cap_priv_s *priv,
+                                    bool on)
+{
+  uint32_t offset = 0;
+  uint32_t mask   = 0;
+
+  switch (priv->base)
+    {
+      /* APB2 Timers */
+
+#ifdef CONFIG_STM32_TIM1_CAP
+      case STM32_TIM1_BASE:
+        offset = STM32_RCC_APB2ENR;
+        mask   = RCC_APB2ENR_TIM1EN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM8_CAP
+      case STM32_TIM8_BASE:
+        offset = STM32_RCC_APB2ENR;
+        mask   = RCC_APB2ENR_TIM8EN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM15_CAP
+      case STM32_TIM15_BASE:
+        offset = STM32_RCC_APB2ENR;
+        mask   = RCC_APB2ENR_TIM15EN;
+        break;
+#endif
+
+      /* APB1L Timers */
+
+#ifdef CONFIG_STM32_TIM2_CAP
+      case STM32_TIM2_BASE:
+        offset = STM32_RCC_APB1LENR;
+        mask   = RCC_APB1LENR_TIM2EN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM3_CAP
+      case STM32_TIM3_BASE:
+        offset = STM32_RCC_APB1LENR;
+        mask   = RCC_APB1LENR_TIM3EN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM4_CAP
+      case STM32_TIM4_BASE:
+        offset = STM32_RCC_APB1LENR;
+        mask   = RCC_APB1LENR_TIM4EN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM5_CAP
+      case STM32_TIM5_BASE:
+        offset = STM32_RCC_APB1LENR;
+        mask   = RCC_APB1LENR_TIM5EN;
+        break;
+#endif
+      /* TIM6 and TIM7 cannot be used in capture */
+#ifdef CONFIG_STM32_TIM12_CAP
+      case STM32_TIM12_BASE:
+        offset = STM32_RCC_APB1LENR;
+        mask   = RCC_APB1LENR_TIM12EN;
+        break;
+#endif
+
+      /* APB4 Timers */
+
+      default:
+        return -EINVAL;
+    }
+
+  if (on)
+    {
+      modifyreg32(offset, 0, mask);
+    }
+  else
+    {
+      modifyreg32(offset, mask, 0);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Basic Functions
+ ****************************************************************************/
+
+static int stm32_cap_setclock(struct stm32_cap_dev_s *dev,
+                              uint32_t freq, uint32_t max)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint32_t freqin;
+  int prescaler;
+
+  /* Disable Timer? */
+
+  if (freq == 0)
+    {
+      /* Disable Timer */
+
+      stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0);
+      return 0;
+    }
+
+  /* Get the input clock frequency for this timer.  These vary with
+   * different timer clock sources, MCU-specific timer configuration, and
+   * board-specific clock configuration.  The correct input clock frequency
+   * must be defined in the board.h header file.
+   */
+
+  switch (priv->base)
+    {
+#ifdef CONFIG_STM32_TIM1
+      case STM32_TIM1_BASE:
+        freqin = STM32_TIM1_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM2
+      case STM32_TIM2_BASE:
+        freqin = STM32_TIM2_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM3
+      case STM32_TIM3_BASE:
+        freqin = STM32_TIM3_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM4
+      case STM32_TIM4_BASE:
+        freqin = STM32_TIM4_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM5
+      case STM32_TIM5_BASE:
+        freqin = STM32_TIM5_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM8
+      case STM32_TIM8_BASE:
+        freqin = STM32_TIM8_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM12
+      case STM32_TIM12_BASE:
+        freqin = STM32_TIM12_CLKIN;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM15
+      case STM32_TIM15_BASE:
+        freqin = STM32_TIM15_CLKIN;
+        break;
+#endif
+
+      default:
+        return -EINVAL;
+    }
+
+  /* Select a pre-scaler value for this timer using the input clock
+   * frequency.
+   */
+
+  prescaler = freqin / freq;
+
+  /* We need to decrement value for '1', but only, if we are allowed to
+   * not to cause underflow. Check for overflow.
+   */
+
+  if (prescaler > 0)
+    {
+      prescaler--;
+    }
+
+  if (prescaler > 0xffff)
+    {
+      prescaler = 0xffff;
+    }
+
+  /* Set Maximum */
+
+  stm32_putreg32(priv, STM32_BTIM_ARR_OFFSET, max);
+
+  /* Set prescaler */
+
+  stm32_putreg16(priv, STM32_BTIM_PSC_OFFSET, prescaler);
+
+  /* Reset counter timer */
+
+  stm32_modifyreg16(priv, STM32_BTIM_EGR_OFFSET, 0, BTIM_EGR_UG);
+
+  /* Enable timer */
+
+  stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, 0, BTIM_CR1_CEN);
+
+#ifdef USE_ADVANCED_TIM
+  /* Advanced registers require Main Output Enable */
+
+  if (priv->base == STM32_TIM1_BASE || priv->base == STM32_TIM8_BASE)
+    {
+      stm32_modifyreg16(priv, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE);
+    }
+#endif
+
+  return prescaler;
+}
+
+/****************************************************************************
+ * Name: stm32_cap_setsmc
+ *
+ * Description:
+ *   set slave mode control register
+ *
+ * Input Parameters:
+ *   dev - A pointer of the stm32 capture device structure.
+ *   cfg - Slave mode control register configure of timer.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_cap_setsmc(struct stm32_cap_dev_s *dev,
+                            stm32_cap_smc_cfg_t cfg)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint16_t regval = 0;
+  uint16_t mask = 0;
+
+  switch (cfg & STM32_CAP_SMS_MASK)
+    {
+      case STM32_CAP_SMS_INT:
+        regval |= GTIM_SMCR_DISAB;
+        break;
+
+      case STM32_CAP_SMS_ENC1:
+        regval |= GTIM_SMCR_ENCMD1;
+        break;
+
+      case STM32_CAP_SMS_ENC2:
+        regval |= GTIM_SMCR_ENCMD2;
+        break;
+
+      case STM32_CAP_SMS_ENC3:
+        regval |= GTIM_SMCR_ENCMD3;
+        break;
+
+      case STM32_CAP_SMS_RST:
+        regval |= GTIM_SMCR_RESET;
+        break;
+
+      case STM32_CAP_SMS_GAT:
+        regval |= GTIM_SMCR_GATED;
+        break;
+
+      case STM32_CAP_SMS_TRG:
+        regval |= GTIM_SMCR_TRIGGER;
+        break;
+
+      case STM32_CAP_SMS_EXT:
+        regval |= GTIM_SMCR_EXTCLK1;
+        break;
+
+      default:
+        break;
+    }
+
+  switch (cfg & STM32_CAP_TS_MASK)
+    {
+      case STM32_CAP_TS_ITR0:
+        regval |= GTIM_SMCR_ITR0;
+        break;
+
+      case STM32_CAP_TS_ITR1:
+        regval |= GTIM_SMCR_ITR1;
+        break;
+
+      case STM32_CAP_TS_ITR2:
+        regval |= GTIM_SMCR_ITR2;
+        break;
+
+      case STM32_CAP_TS_ITR3:
+        regval |= GTIM_SMCR_ITR3;
+        break;
+
+      case STM32_CAP_TS_TI1FED:
+        regval |= GTIM_SMCR_TI1FED;
+        break;
+
+      case STM32_CAP_TS_TI1FP1:
+        regval |= GTIM_SMCR_TI1FP1;
+        break;
+
+      case STM32_CAP_TS_TI2FP2:
+        regval |= GTIM_SMCR_TI2FP2;
+        break;
+
+      case STM32_CAP_TS_ETRF:
+        regval |= GTIM_SMCR_ETRF;
+        break;
+
+      default:
+        break;
+    }
+
+  if (cfg & STM32_CAP_MSM_MASK)
+    {
+      regval |= STM32_CAP_MSM_MASK;
+    }
+
+  mask = (STM32_CAP_SMS_MASK | STM32_CAP_TS_MASK | STM32_CAP_MSM_MASK);
+  stm32_modifyreg16(priv, STM32_GTIM_SMCR_OFFSET, mask, regval);
+
+  return OK;
+}
+
+static int stm32_cap_setisr(struct stm32_cap_dev_s *dev, xcpt_t handler,
+                            void *arg)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  int irq;
+#ifdef USE_ADVANCED_TIM
+  int irq_of;
+#endif
+
+  DEBUGASSERT(dev != NULL);
+
+  irq = priv->irq;
+#ifdef USE_ADVANCED_TIM
+  irq_of = priv->irq_of;
+#endif
+
+  /* Disable interrupt when callback is removed */
+
+  if (!handler)
+    {
+      up_disable_irq(irq);
+      irq_detach(irq);
+
+#ifdef USE_ADVANCED_TIM
+      if (priv->irq_of)
+        {
+          up_disable_irq(irq_of);
+          irq_detach(irq_of);
+        }
+#endif
+
+      return OK;
+    }
+
+  /* Otherwise set callback and enable interrupt */
+
+  irq_attach(irq, handler, arg);
+  up_enable_irq(irq);
+
+#ifdef USE_ADVANCED_TIM
+  if (priv->irq_of)
+    {
+      irq_attach(priv->irq_of, handler, arg);
+      up_enable_irq(priv->irq_of);
+    }
+#endif
+
+  return OK;
+}
+
+static void stm32_cap_enableint(struct stm32_cap_dev_s *dev,
+                                stm32_cap_flags_t src, bool on)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint16_t mask = 0;
+
+  DEBUGASSERT(dev != NULL);
+
+  if (src & STM32_CAP_FLAG_IRQ_COUNTER)
+    {
+      mask |= ATIM_DIER_UIE;
+    }
+
+  if (src & STM32_CAP_FLAG_IRQ_CH_1)
+    {
+      mask |= ATIM_DIER_CC1IE;
+    }
+
+  if (src & STM32_CAP_FLAG_IRQ_CH_2)
+    {
+      mask |= ATIM_DIER_CC2IE;
+    }
+
+  if (src & STM32_CAP_FLAG_IRQ_CH_3)
+    {
+      mask |= ATIM_DIER_CC3IE;
+    }
+
+  if (src & STM32_CAP_FLAG_IRQ_CH_4)
+    {
+      mask |= ATIM_DIER_CC4IE;
+    }
+
+  /* Not IRQ on channel overflow */
+
+  if (on)
+    {
+      stm32_modifyreg16(priv, STM32_BTIM_DIER_OFFSET, 0, mask);
+    }
+  else
+    {
+      stm32_modifyreg16(priv, STM32_BTIM_DIER_OFFSET, mask, 0);
+    }
+}
+
+static void stm32_cap_ackflags(struct stm32_cap_dev_s *dev, int flags)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint16_t mask = 0;
+
+  if (flags & STM32_CAP_FLAG_IRQ_COUNTER)
+    {
+      mask |= ATIM_SR_UIF;
+    }
+
+  if (flags & STM32_CAP_FLAG_IRQ_CH_1)
+    {
+      mask |= ATIM_SR_CC1IF;
+    }
+
+  if (flags & STM32_CAP_FLAG_IRQ_CH_2)
+    {
+      mask |= ATIM_SR_CC2IF;
+    }
+
+  if (flags & STM32_CAP_FLAG_IRQ_CH_3)
+    {
+      mask |= ATIM_SR_CC3IF;
+    }
+
+  if (flags & STM32_CAP_FLAG_IRQ_CH_4)
+    {
+      mask |= ATIM_SR_CC4IF;
+    }
+
+  if (flags & STM32_CAP_FLAG_OF_CH_1)
+    {
+      mask |= ATIM_SR_CC1OF;
+    }
+
+  if (flags & STM32_CAP_FLAG_OF_CH_2)
+    {
+      mask |= ATIM_SR_CC2OF;
+    }
+
+  if (flags & STM32_CAP_FLAG_OF_CH_3)
+    {
+      mask |= ATIM_SR_CC3OF;
+    }
+
+  if (flags & STM32_CAP_FLAG_OF_CH_4)
+    {
+      mask |= ATIM_SR_CC4OF;
+    }
+
+  stm32_putreg16(priv, STM32_BTIM_SR_OFFSET, ~mask);
+}
+
+static stm32_cap_flags_t stm32_cap_getflags(struct stm32_cap_dev_s *dev)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint16_t regval = 0;
+  stm32_cap_flags_t flags = 0;
+
+  regval = stm32_getreg16(priv, STM32_BTIM_SR_OFFSET);
+
+  if (regval & ATIM_SR_UIF)
+    {
+      flags |= STM32_CAP_FLAG_IRQ_COUNTER;
+    }
+
+  if (regval & ATIM_SR_CC1IF)
+    {
+      flags |= STM32_CAP_FLAG_IRQ_CH_1;
+    }
+
+  if (regval & ATIM_SR_CC2IF)
+    {
+      flags |= STM32_CAP_FLAG_IRQ_CH_2;
+    }
+
+  if (regval & ATIM_SR_CC3IF)
+    {
+      flags |= STM32_CAP_FLAG_IRQ_CH_3;
+    }
+
+  if (regval & ATIM_SR_CC4IF)
+    {
+      flags |= STM32_CAP_FLAG_IRQ_CH_4;
+    }
+
+  if (regval & ATIM_SR_CC1OF)
+    {
+      flags |= STM32_CAP_FLAG_OF_CH_1;
+    }
+
+  if (regval & ATIM_SR_CC2OF)
+    {
+      flags |= STM32_CAP_FLAG_OF_CH_2;
+    }
+
+  if (regval & ATIM_SR_CC3OF)
+    {
+      flags |= STM32_CAP_FLAG_OF_CH_3;
+    }
+
+  if (regval & ATIM_SR_CC4OF)
+    {
+      flags |= STM32_CAP_FLAG_OF_CH_4;
+    }
+
+  return flags;
+}
+
+/****************************************************************************
+ * General Functions
+ ****************************************************************************/
+
+static int stm32_cap_setchannel(struct stm32_cap_dev_s *dev,
+                                uint8_t channel,
+                                stm32_cap_ch_cfg_t cfg)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint32_t gpio = 0;
+  uint16_t mask;
+  uint16_t regval;
+  uint16_t ccer_en_bit;
+
+  DEBUGASSERT(dev != NULL);
+
+  if ((cfg & STM32_CAP_MAPPED_MASK) == 0)
+    {
+      return ERROR; /* MAPPED not selected */
+    }
+
+  /* Only a channel mapped to its own input needs a pin.  A channel mapped
+   * to the input of its paired channel (as the second channel in PWM input
+   * mode) shares the pin of that channel.
+   */
+
+  if ((cfg & STM32_CAP_MAPPED_MASK) == STM32_CAP_MAPPED_TI1)
+    {
+      gpio = stm32_cap_gpio(priv, channel);
+
+      if (gpio == 0 &&
+          (cfg & STM32_CAP_EDGE_MASK) != STM32_CAP_EDGE_DISABLED)
+        {
+          return ERROR;
+        }
+    }
+
+  /* Change to zero base index */
+
+  channel--;
+
+  /* Set ccer :
+   *
+   * GTIM_CCER_CCxE Is written latter to allow writing CCxS bits.
+   *
+   */
+
+  switch (cfg & STM32_CAP_EDGE_MASK)
+    {
+      case STM32_CAP_EDGE_DISABLED:
+        regval = 0;
+        ccer_en_bit = 0;
+        break;
+
+      case STM32_CAP_EDGE_RISING:
+        ccer_en_bit = GTIM_CCER_CC1E;
+        regval      = 0;
+        break;
+
+      case STM32_CAP_EDGE_FALLING:
+        ccer_en_bit = GTIM_CCER_CC1E;
+        regval      = GTIM_CCER_CC1P;
+        break;
+
+      case STM32_CAP_EDGE_BOTH:
+        ccer_en_bit = GTIM_CCER_CC1E;
+        regval      = GTIM_CCER_CC1P | GTIM_CCER_CC1NP;
+        break;
+
+      default:
+        return ERROR;
+    }
+
+  /* Shift all CCER bits to corresponding channel */
+
+  mask = (GTIM_CCER_CC1E | GTIM_CCER_CC1P | GTIM_CCER_CC1NP);
+  mask          <<= GTIM_CCER_CCXBASE(channel);
+  regval        <<= GTIM_CCER_CCXBASE(channel);
+  ccer_en_bit   <<= GTIM_CCER_CCXBASE(channel);
+
+  stm32_modifyreg16(priv, STM32_GTIM_CCER_OFFSET, mask, regval);
+
+  /* Set ccmr */
+
+  regval = cfg;
+  mask = (GTIM_CCMR1_IC1F_MASK |
+          GTIM_CCMR1_IC1PSC_MASK |
+          GTIM_CCMR1_CC1S_MASK);
+  regval &= mask;
+
+  if (channel & 1)
+    {
+      regval <<= 8;
+      mask   <<= 8;
+    }
+
+  if (channel < 2)
+    {
+      stm32_modifyreg16(priv, STM32_GTIM_CCMR1_OFFSET, mask, regval);
+    }
+  else
+    {
+      stm32_modifyreg16(priv, STM32_GTIM_CCMR2_OFFSET, mask, regval);
+    }
+
+  /* Set GPIO */
+
+  if (gpio != 0)
+    {
+      if ((cfg & STM32_CAP_EDGE_MASK) == STM32_CAP_EDGE_DISABLED)
+        {
+          stm32_unconfiggpio(gpio);
+        }
+      else
+        {
+          stm32_configgpio(gpio);
+        }
+    }
+
+  /* Enable this channel timer */
+
+  stm32_modifyreg16(priv, STM32_GTIM_CCER_OFFSET, 0, ccer_en_bit);
+  return OK;
+}
+
+static uint32_t stm32_cap_getcapture(struct stm32_cap_dev_s *dev,
+                                     uint8_t channel)
+{
+  const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev;
+  uint32_t offset;
+
+  DEBUGASSERT(dev != NULL);
+
+  switch (channel)
+    {
+      case STM32_CAP_CHANNEL_COUNTER:
+        offset = STM32_GTIM_CNT_OFFSET;
+        break;
+#ifdef HAVE_CH1IN
+      case 1:
+        offset = STM32_GTIM_CCR1_OFFSET;
+        break;
+#endif
+#ifdef HAVE_CH2IN
+      case 2:
+        offset = STM32_GTIM_CCR2_OFFSET;
+        break;
+#endif
+#ifdef HAVE_CH3IN
+      case 3:
+        offset = STM32_GTIM_CCR3_OFFSET;
+        break;
+#endif
+#ifdef HAVE_CH4IN
+      case 4:
+        offset = STM32_GTIM_CCR4_OFFSET;
+        break;
+#endif
+      default:
+        return ERROR;
+    }
+
+  if (priv->base == STM32_TIM2_BASE || priv->base == STM32_TIM5_BASE)
+    {
+      return stm32_getreg32(priv, offset);
+    }
+
+  return stm32_getreg16(priv, offset);
+}
+
+/****************************************************************************
+ * Advanced Functions
+ ****************************************************************************/
+
+/* TODO: Advanced functions for the STM32_ATIM */
+
+/****************************************************************************
+ * Device Structures, Instantiation
+ ****************************************************************************/
+
+struct stm32_cap_ops_s stm32_cap_ops =
+{
+  .setsmc       = &stm32_cap_setsmc,
+  .setclock     = &stm32_cap_setclock,
+  .setchannel   = &stm32_cap_setchannel,
+  .getcapture   = &stm32_cap_getcapture,
+  .setisr       = &stm32_cap_setisr,
+  .enableint    = &stm32_cap_enableint,
+  .ackflags     = &stm32_cap_ackflags,
+  .getflags     = &stm32_cap_getflags
+};
+
+#ifdef CONFIG_STM32_TIM1_CAP
+const struct stm32_cap_priv_s stm32_tim1_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM1_BASE,
+  .irq          = STM32_IRQ_TIM1CC,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = STM32_IRQ_TIM1UP,
+#endif
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM2_CAP
+const struct stm32_cap_priv_s stm32_tim2_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM2_BASE,
+  .irq          = STM32_IRQ_TIM2,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = 0,
+#endif
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM3_CAP
+const struct stm32_cap_priv_s stm32_tim3_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM3_BASE,
+  .irq          = STM32_IRQ_TIM3,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = 0,
+#endif
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM4_CAP
+const struct stm32_cap_priv_s stm32_tim4_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM4_BASE,
+  .irq          = STM32_IRQ_TIM4,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = 0,
+#endif
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM5_CAP
+const struct stm32_cap_priv_s stm32_tim5_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM5_BASE,
+  .irq          = STM32_IRQ_TIM5,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = 0,
+#endif
+};
+#endif
+
+/* TIM6 and TIM7 cannot be used in capture */
+
+#ifdef CONFIG_STM32_TIM8_CAP
+const struct stm32_cap_priv_s stm32_tim8_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM8_BASE,
+  .irq          = STM32_IRQ_TIM8CC,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = STM32_IRQ_TIM8UP,
+#endif
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM12_CAP
+const struct stm32_cap_priv_s stm32_tim12_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM12_BASE,
+  .irq          = STM32_IRQ_TIM12,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = 0,
+#endif
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM15_CAP
+static const struct stm32_cap_priv_s stm32_tim15_priv =
+{
+  .ops          = &stm32_cap_ops,
+  .base         = STM32_TIM15_BASE,
+  .irq          = STM32_IRQ_TIM15,
+#ifdef USE_ADVANCED_TIM
+  .irq_of       = 0,
+#endif
+};
+#endif
+
+static inline const struct stm32_cap_priv_s * stm32_cap_get_priv(int timer)
+{
+  switch (timer)
+    {
+#ifdef CONFIG_STM32_TIM1_CAP
+      case 1:
+        return &stm32_tim1_priv;
+#endif
+#ifdef CONFIG_STM32_TIM2_CAP
+      case 2:
+        return &stm32_tim2_priv;
+#endif
+#ifdef CONFIG_STM32_TIM3_CAP
+      case 3:
+        return &stm32_tim3_priv;
+#endif
+#ifdef CONFIG_STM32_TIM4_CAP
+      case 4:
+        return &stm32_tim4_priv;
+#endif
+#ifdef CONFIG_STM32_TIM5_CAP
+      case 5:
+        return &stm32_tim5_priv;
+#endif
+
+      /* TIM6 and TIM7 cannot be used in capture */
+
+#ifdef CONFIG_STM32_TIM8_CAP
+      case 8:
+        return &stm32_tim8_priv;
+#endif
+#ifdef CONFIG_STM32_TIM12_CAP
+      case 12:
+        return &stm32_tim12_priv;
+#endif
+#ifdef CONFIG_STM32_TIM15_CAP
+      case 15:
+        return &stm32_tim15_priv;
+#endif
+    }
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Public Function - Initialization
+ ****************************************************************************/
+
+struct stm32_cap_dev_s *stm32_cap_init(int timer)
+{
+  const struct stm32_cap_priv_s *priv = stm32_cap_get_priv(timer);
+  uint32_t gpio;
+
+  if (priv)
+    {
+      stm32_cap_set_rcc(priv, true);
+
+      gpio = stm32_cap_gpio(priv, -1);
+      if (gpio)
+        {
+          stm32_configgpio(gpio);
+        }
+
+      /* Disable timer while is not configured */
+
+      stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0);
+    }
+
+  return (struct stm32_cap_dev_s *)priv;
+}
+
+int stm32_cap_deinit(struct stm32_cap_dev_s * dev)
+{
+  const struct stm32_cap_priv_s *priv = (struct stm32_cap_priv_s *)dev;
+  uint32_t gpio;
+
+  DEBUGASSERT(dev != NULL);
+
+  /* Disable timer while is not configured */
+
+  stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0);
+
+  gpio = stm32_cap_gpio(priv, -1);
+  if (gpio)
+    {
+      stm32_unconfiggpio(gpio);
+    }
+
+  stm32_cap_set_rcc(priv, false);
+  return OK;
+}
+
+#endif /* CONFIG_STM32_TIMX_CAP */
diff --git a/arch/arm/src/stm32h5/stm32_capture.h 
b/arch/arm/src/stm32h5/stm32_capture.h
new file mode 100644
index 00000000000..750a8091c8c
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_capture.h
@@ -0,0 +1,240 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_capture.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_CAPTURE_H
+#define __ARCH_ARM_SRC_STM32H5_STM32_CAPTURE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "chip.h"
+#include <arch/board/board.h>
+#include "hardware/stm32_tim.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Helpers ******************************************************************/
+
+#define STM32_CAP_SETSMC(d,cfg)                 ((d)->ops->setsmc(d,cfg))
+#define STM32_CAP_SETCLOCK(d,clk,max)           ((d)->ops->setclock(d,clk,max))
+#define STM32_CAP_SETCHANNEL(d,ch,cfg)          
((d)->ops->setchannel(d,ch,cfg))
+#define STM32_CAP_GETCAPTURE(d,ch)              ((d)->ops->getcapture(d,ch))
+#define STM32_CAP_SETISR(d,hnd,arg)             ((d)->ops->setisr(d,hnd,arg))
+#define STM32_CAP_ENABLEINT(d,s,on)             ((d)->ops->enableint(d,s,on))
+#define STM32_CAP_ACKFLAGS(d,f)                 ((d)->ops->ackflags(d,f))
+#define STM32_CAP_GETFLAGS(d)                   ((d)->ops->getflags(d))
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/* Capture Device Structure */
+
+struct stm32_cap_dev_s
+{
+  struct stm32_cap_ops_s *ops;
+};
+
+/* Capture input EDGE sources */
+
+typedef enum
+{
+  /* Mapped */
+
+  STM32_CAP_MAPPED_MASK         = (GTIM_CCMR1_CC1S_MASK),
+  STM32_CAP_MAPPED_TI1          = (GTIM_CCMR_CCS_CCIN1),
+  STM32_CAP_MAPPED_TI2          = (GTIM_CCMR_CCS_CCIN2),
+
+/* TODO STM32_CAP_MAPPED_TRC     = (GTIM_CCMR_CCS_CCINTRC), */
+
+  /* Event prescaler */
+
+  STM32_CAP_INPSC_MASK          = (GTIM_CCMR1_IC1PSC_MASK),
+  STM32_CAP_INPSC_NO            = (0 << GTIM_CCMR1_IC1PSC_SHIFT),
+  STM32_CAP_INPSC_2EVENTS       = (1 << GTIM_CCMR1_IC1PSC_SHIFT),
+  STM32_CAP_INPSC_4EVENTS       = (2 << GTIM_CCMR1_IC1PSC_SHIFT),
+  STM32_CAP_INPSC_8EVENTS       = (3 << GTIM_CCMR1_IC1PSC_SHIFT),
+
+  /* Event prescaler */
+
+  STM32_CAP_FILTER_MASK         = (GTIM_CCMR1_IC1F_MASK),
+  STM32_CAP_FILTER_NO           = (0 << GTIM_CCMR1_IC1F_SHIFT),
+
+  /* Internal clock with N time to confirm event */
+
+  STM32_CAP_FILTER_INT_N2       = (1 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_INT_N4       = (2 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_INT_N8       = (3 << GTIM_CCMR1_IC1F_SHIFT),
+
+  /* DTS clock div by D with N time to confirm event */
+
+  STM32_CAP_FILTER_DTS_D2_N6    = (4 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D2_N8    = (5 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D4_N6    = (6 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D4_N8    = (7 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D8_N6    = (8 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D8_N8    = (9 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D16_N5   = (10 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D16_N6   = (11 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D16_N8   = (12 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D32_N5   = (13 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D32_N6   = (14 << GTIM_CCMR1_IC1F_SHIFT),
+  STM32_CAP_FILTER_DTS_D32_N8   = (15 << GTIM_CCMR1_IC1F_SHIFT),
+
+  /* EDGE */
+
+  STM32_CAP_EDGE_MASK           = (3 << 8),
+  STM32_CAP_EDGE_DISABLED       = (0 << 8),
+  STM32_CAP_EDGE_RISING         = (1 << 8),
+  STM32_CAP_EDGE_FALLING        = (2 << 8),
+  STM32_CAP_EDGE_BOTH           = (3 << 8),
+} stm32_cap_ch_cfg_t;
+
+/* Slave mode control configure */
+
+typedef enum
+{
+  /* Slave mode selection */
+
+  STM32_CAP_SMS_MASK            = (7 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_INT             = (0 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_ENC1            = (1 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_ENC2            = (2 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_ENC3            = (3 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_RST             = (4 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_GAT             = (5 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_TRG             = (6 << GTIM_SMCR_SMS_SHIFT),
+  STM32_CAP_SMS_EXT             = (7 << GTIM_SMCR_SMS_SHIFT),
+
+  /* Trigger selection */
+
+  STM32_CAP_TS_MASK             = (7 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_ITR0             = (0 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_ITR1             = (1 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_ITR2             = (2 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_ITR3             = (3 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_TI1FED           = (4 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_TI1FP1           = (5 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_TI2FP2           = (6 << GTIM_SMCR_TS_SHIFT),
+  STM32_CAP_TS_ETRF             = (7 << GTIM_SMCR_TS_SHIFT),
+
+  /* Master/Slave mode setting */
+
+  STM32_CAP_MSM_MASK            = (1 << 7)
+} stm32_cap_smc_cfg_t;
+
+/* Capture flags */
+
+typedef enum
+{
+  /* One of the following */
+
+  STM32_CAP_FLAG_IRQ_COUNTER    = (GTIM_SR_UIF),
+
+  STM32_CAP_FLAG_IRQ_CH_1       = (GTIM_SR_CC1IF),
+  STM32_CAP_FLAG_IRQ_CH_2       = (GTIM_SR_CC2IF),
+  STM32_CAP_FLAG_IRQ_CH_3       = (GTIM_SR_CC3IF),
+  STM32_CAP_FLAG_IRQ_CH_4       = (GTIM_SR_CC4IF),
+
+  STM32_CAP_FLAG_OF_CH_1        = (GTIM_SR_CC1OF),
+  STM32_CAP_FLAG_OF_CH_2        = (GTIM_SR_CC2OF),
+  STM32_CAP_FLAG_OF_CH_3        = (GTIM_SR_CC3OF),
+  STM32_CAP_FLAG_OF_CH_4        = (GTIM_SR_CC4OF)
+} stm32_cap_flags_t;
+
+#define STM32_CAP_FLAG_IRQ_CH(ch)   (GTIM_SR_CC1IF<<((ch)-1))
+#define STM32_CAP_FLAG_OF_CH(ch)    (GTIM_SR_CC1OF<<((ch)-1))
+#define STM32_CAP_CHANNEL_COUNTER   0
+
+/* Capture Operations */
+
+struct stm32_cap_ops_s
+{
+  int  (*setsmc)(struct stm32_cap_dev_s *dev, stm32_cap_smc_cfg_t cfg);
+  int  (*setclock)(struct stm32_cap_dev_s *dev, uint32_t freq,
+                   uint32_t max);
+  int  (*setchannel)(struct stm32_cap_dev_s *dev, uint8_t channel,
+                     stm32_cap_ch_cfg_t cfg);
+  uint32_t (*getcapture)(struct stm32_cap_dev_s *dev, uint8_t channel);
+  int  (*setisr)(struct stm32_cap_dev_s *dev, xcpt_t handler, void *arg);
+  void (*enableint)(struct stm32_cap_dev_s *dev, stm32_cap_flags_t src,
+                    bool on);
+  void (*ackflags)(struct stm32_cap_dev_s *dev, int flags);
+  stm32_cap_flags_t (*getflags)(struct stm32_cap_dev_s *dev);
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/* Power-up timer and get its structure */
+
+struct stm32_cap_dev_s *stm32_cap_init(int timer);
+
+/* Power-down timer, mark it as unused */
+
+int stm32_cap_deinit(struct stm32_cap_dev_s *dev);
+
+/****************************************************************************
+ * Name: stm32_cap_initialize
+ *
+ * Description:
+ *   Initialize one timer for use with the upper_level capture driver.
+ *
+ * Input Parameters:
+ *   timer - A number identifying the timer use.  The number of valid timer
+ *     IDs varies with the STM32 MCU and MCU family but is somewhere in
+ *     the range of {1,..,5, 8, 12, 15}.
+ *
+ * Returned Value:
+ *   On success, a pointer to the STM32 lower half capture driver returned.
+ *   NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CAPTURE
+struct cap_lowerhalf_s *stm32_cap_initialize(int timer);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_STM32H5_STM32_CAPTURE_H */
diff --git a/arch/arm/src/stm32h5/stm32_capture_lowerhalf.c 
b/arch/arm/src/stm32h5/stm32_capture_lowerhalf.c
new file mode 100644
index 00000000000..5b7e4a48619
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_capture_lowerhalf.c
@@ -0,0 +1,529 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_capture_lowerhalf.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 <nuttx/config.h>
+
+#include <sys/types.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/timers/capture.h>
+
+#include <arch/board/board.h>
+
+#include "stm32_capture.h"
+
+#if defined(CONFIG_CAPTURE)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* 32-Bit Timers ************************************************************/
+
+#define STM32_TIM2_RES  32
+#define STM32_TIM5_RES  32
+
+/* 16-Bit Timers ************************************************************/
+
+/* Advanced-Control Timers */
+#define STM32_TIM1_RES  16
+#define STM32_TIM8_RES  16
+
+/* General-Purpose Timers */
+#define STM32_TIM3_RES  16
+#define STM32_TIM4_RES  16
+#define STM32_TIM12_RES 16
+#define STM32_TIM15_RES 16
+
+/* Basic Timers */
+#define STM32_TIM6_RES  16
+#define STM32_TIM7_RES  16
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure provides the private representation of the "lower-half"
+ * driver state structure.  This structure must be cast-compatible with the
+ * cap_lowerhalf_s structure.
+ */
+
+struct stm32_lowerhalf_s
+{
+  const struct cap_ops_s *ops;       /* Lower half operations */
+  struct stm32_cap_dev_s *cap;       /* stm32 capture driver */
+  bool                   started;    /* True: Timer has been started */
+  const uint8_t          resolution; /* Number of bits in the timer */
+  uint8_t                channel;    /* pwm input channel */
+  uint32_t               clock;      /* Timer clock frequency */
+  uint8_t                duty;       /* Result pwm frequency */
+  uint32_t               freq;       /* Result pwm frequency */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_cap_handler(int irq, void * context, void * arg);
+
+/* "Lower half" driver methods **********************************************/
+
+static int stm32_start(struct cap_lowerhalf_s *lower);
+static int stm32_stop(struct cap_lowerhalf_s *lower);
+static int stm32_getduty(struct cap_lowerhalf_s *lower, uint8_t *duty);
+static int stm32_getfreq(struct cap_lowerhalf_s *lower, uint32_t *freq);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* "Lower half" driver methods */
+
+static const struct cap_ops_s g_cap_ops =
+{
+  .start       = stm32_start,
+  .stop        = stm32_stop,
+  .getduty     = stm32_getduty,
+  .getfreq     = stm32_getfreq,
+};
+
+#ifdef CONFIG_STM32_TIM1_CAP
+static struct stm32_lowerhalf_s g_cap1_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM1_RES,
+  .channel     = CONFIG_STM32_TIM1_CHANNEL,
+  .clock       = CONFIG_STM32_TIM1_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM2_CAP
+static struct stm32_lowerhalf_s g_cap2_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM2_RES,
+  .channel     = CONFIG_STM32_TIM2_CHANNEL,
+  .clock       = CONFIG_STM32_TIM2_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM3_CAP
+static struct stm32_lowerhalf_s g_cap3_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM3_RES,
+  .channel     = CONFIG_STM32_TIM3_CHANNEL,
+  .clock       = CONFIG_STM32_TIM3_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM4_CAP
+static struct stm32_lowerhalf_s g_cap4_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM4_RES,
+  .channel     = CONFIG_STM32_TIM4_CHANNEL,
+  .clock       = CONFIG_STM32_TIM4_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM5_CAP
+static struct stm32_lowerhalf_s g_cap5_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM5_RES,
+  .channel     = CONFIG_STM32_TIM5_CHANNEL,
+  .clock       = CONFIG_STM32_TIM5_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM8_CAP
+static struct stm32_lowerhalf_s g_cap8_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM8_RES,
+  .channel     = CONFIG_STM32_TIM8_CHANNEL,
+  .clock       = CONFIG_STM32_TIM8_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM12_CAP
+static struct stm32_lowerhalf_s g_cap12_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM12_RES,
+  .channel     = CONFIG_STM32_TIM12_CHANNEL,
+  .clock       = CONFIG_STM32_TIM12_CLOCK,
+};
+#endif
+
+#ifdef CONFIG_STM32_TIM15_CAP
+static struct stm32_lowerhalf_s g_cap15_lowerhalf =
+{
+  .ops         = &g_cap_ops,
+  .resolution  = STM32_TIM15_RES,
+  .channel     = CONFIG_STM32_TIM15_CHANNEL,
+  .clock       = CONFIG_STM32_TIM15_CLOCK,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_cap_handler
+ *
+ * Description:
+ *   timer interrupt handler
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+static int stm32_cap_handler(int irq, void * context, void * arg)
+{
+  struct stm32_lowerhalf_s *lower = (struct stm32_lowerhalf_s *) arg;
+  uint8_t ch = 0x3 & lower->channel;
+  int period = 0;
+  int flags = 0;
+
+  flags = (int)STM32_CAP_GETFLAGS(lower->cap) ;
+
+  STM32_CAP_ACKFLAGS(lower->cap, flags);
+
+  period = STM32_CAP_GETCAPTURE(lower->cap, ch);
+
+  if (period != 0)
+    {
+      lower->duty = (100 * STM32_CAP_GETCAPTURE(lower->cap, 0x3 & (~ch))) /
+                    period;
+      lower->freq = lower->clock / period;
+    }
+  else
+    {
+      lower->duty = 0;
+      lower->freq = 0;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_start
+ *
+ * Description:
+ *   Start the timer, resetting the time to the current timeout,
+ *
+ * Input Parameters:
+ *   lower - A pointer the publicly visible representation of the
+ *           "lower-half" driver state structure.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_start(struct cap_lowerhalf_s *lower)
+{
+  struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower;
+  int flags = 0;
+  uint32_t maxtimeout = (1 << priv->resolution) - 1;
+
+  if (priv->started)
+    {
+      /* Return EBUSY to indicate that the timer was already running */
+
+      return -EBUSY;
+    }
+
+  switch (priv->channel)
+    {
+      case 1:
+        STM32_CAP_SETSMC(priv->cap, STM32_CAP_SMS_RST |
+                         STM32_CAP_TS_TI1FP1 |
+                         STM32_CAP_MSM_MASK);
+
+        STM32_CAP_SETCLOCK(priv->cap, priv->clock, maxtimeout);
+
+        STM32_CAP_SETCHANNEL(priv->cap, 1,
+                             STM32_CAP_EDGE_RISING |
+                             STM32_CAP_MAPPED_TI1);
+        STM32_CAP_SETCHANNEL(priv->cap, 2,
+                             STM32_CAP_EDGE_FALLING |
+                             STM32_CAP_MAPPED_TI2);
+
+        flags = (int)STM32_CAP_GETFLAGS(priv->cap);
+        STM32_CAP_ACKFLAGS(priv->cap, flags);
+
+        STM32_CAP_SETISR(priv->cap, stm32_cap_handler, priv);
+        STM32_CAP_ENABLEINT(priv->cap, STM32_CAP_FLAG_IRQ_CH_1, true);
+
+        priv->started = true;
+        break;
+
+      case 2:
+        STM32_CAP_SETSMC(priv->cap, STM32_CAP_SMS_RST |
+                         STM32_CAP_TS_TI2FP2 |
+                         STM32_CAP_MSM_MASK);
+
+        STM32_CAP_SETCLOCK(priv->cap, priv->clock, maxtimeout);
+
+        STM32_CAP_SETCHANNEL(priv->cap, 2,
+                             STM32_CAP_EDGE_RISING |
+                             STM32_CAP_MAPPED_TI1);
+        STM32_CAP_SETCHANNEL(priv->cap, 1,
+                             STM32_CAP_EDGE_FALLING |
+                             STM32_CAP_MAPPED_TI2);
+
+        flags = (int)STM32_CAP_GETFLAGS(priv->cap);
+        STM32_CAP_ACKFLAGS(priv->cap, flags);
+
+        STM32_CAP_SETISR(priv->cap, stm32_cap_handler, priv);
+        STM32_CAP_ENABLEINT(priv->cap, STM32_CAP_FLAG_IRQ_CH_2, true);
+
+        priv->started = true;
+        break;
+
+      default:
+        return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_stop
+ *
+ * Description:
+ *   Stop the capture
+ *
+ * Input Parameters:
+ *   lower - A pointer the publicly visible representation of the
+ *           "lower-half" driver state structure.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_stop(struct cap_lowerhalf_s *lower)
+{
+  struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower;
+
+  if (priv->started)
+    {
+      switch (priv->channel)
+        {
+          case 1:
+            STM32_CAP_ENABLEINT(priv->cap, STM32_CAP_FLAG_IRQ_CH_1, false);
+            STM32_CAP_SETCHANNEL(priv->cap, 1,
+                                 STM32_CAP_EDGE_DISABLED |
+                                 STM32_CAP_MAPPED_TI1);
+            STM32_CAP_SETCHANNEL(priv->cap, 2,
+                                 STM32_CAP_EDGE_DISABLED |
+                                 STM32_CAP_MAPPED_TI2);
+            break;
+
+          case 2:
+            STM32_CAP_ENABLEINT(priv->cap, STM32_CAP_FLAG_IRQ_CH_2, false);
+            STM32_CAP_SETCHANNEL(priv->cap, 2,
+                                 STM32_CAP_EDGE_DISABLED |
+                                 STM32_CAP_MAPPED_TI1);
+            STM32_CAP_SETCHANNEL(priv->cap, 1,
+                                 STM32_CAP_EDGE_DISABLED |
+                                 STM32_CAP_MAPPED_TI2);
+            break;
+
+          default:
+            return ERROR;
+        }
+
+      STM32_CAP_SETISR(priv->cap, NULL, NULL);
+      STM32_CAP_SETCLOCK(priv->cap, 0, 0);
+      priv->started = false;
+      return OK;
+    }
+
+  /* Return ENODEV to indicate that the timer was not running */
+
+  return -ENODEV;
+}
+
+/****************************************************************************
+ * Name: stm32_getduty
+ *
+ * Description:
+ *   get result duty
+ *
+ * Input Parameters:
+ *   lower - A pointer the publicly visible representation of the
+ *             "lower-half" driver state structure.
+ *   duty  - DutyCycle * 100.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_getduty(struct cap_lowerhalf_s *lower, uint8_t *duty)
+{
+  struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower;
+
+  irqstate_t flags = enter_critical_section();
+
+  *duty = priv->duty;
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_getfreq
+ *
+ * Description:
+ *   get result freq
+ *
+ * Input Parameters:
+ *   lower - A pointer the publicly visible representation of the
+ *             "lower-half" driver state structure.
+ *   freq  - Frequency in Hz.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_getfreq(struct cap_lowerhalf_s *lower, uint32_t *freq)
+{
+  struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower;
+
+  irqstate_t flags = enter_critical_section();
+
+  *freq = priv->freq;
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_cap_initialize
+ *
+ * Description:
+ *   Initialize one timer for use with the upper_level capture driver.
+ *
+ * Input Parameters:
+ *   timer - A number identifying the timer use.  The number of valid timer
+ *     IDs varies with the STM32 MCU and MCU family but is somewhere in
+ *     the range of {1,..,5, 8, 12, 15}.
+ *
+ * Returned Value:
+ *   On success, a pointer to the STM32 lower half capture driver returned.
+ *   NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+struct cap_lowerhalf_s *stm32_cap_initialize(int timer)
+{
+  struct stm32_lowerhalf_s *lower = NULL;
+
+  switch (timer)
+    {
+#ifdef CONFIG_STM32_TIM1_CAP
+      case 1:
+        lower = &g_cap1_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM2_CAP
+      case 2:
+        lower = &g_cap2_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM3_CAP
+      case 3:
+        lower = &g_cap3_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM4_CAP
+      case 4:
+        lower = &g_cap4_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM5_CAP
+      case 5:
+        lower = &g_cap5_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM8_CAP
+      case 8:
+        lower = &g_cap8_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM12_CAP
+      case 12:
+        lower = &g_cap12_lowerhalf;
+        break;
+#endif
+#ifdef CONFIG_STM32_TIM15_CAP
+      case 15:
+        lower = &g_cap15_lowerhalf;
+        break;
+#endif
+
+      default:
+        {
+          lower = NULL;
+          goto errout;
+        }
+    }
+
+  /* Initialize the elements of lower half state structure */
+
+  lower->started  = false;
+  lower->cap      = stm32_cap_init(timer);
+
+  if (lower->cap == NULL)
+    {
+      lower = NULL;
+    }
+
+errout:
+  return (struct cap_lowerhalf_s *)lower;
+}
+
+#endif /* CONFIG_CAPTURE */
diff --git a/boards/arm/stm32h5/nucleo-h563zi/configs/capture/defconfig 
b/boards/arm/stm32h5/nucleo-h563zi/configs/capture/defconfig
new file mode 100644
index 00000000000..e9ff6a7f11e
--- /dev/null
+++ b/boards/arm/stm32h5/nucleo-h563zi/configs/capture/defconfig
@@ -0,0 +1,56 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="nucleo-h563zi"
+CONFIG_ARCH_BOARD_NUCLEO_H563ZI=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="stm32h5"
+CONFIG_ARCH_CHIP_STM32=y
+CONFIG_ARCH_CHIP_STM32H563ZI=y
+CONFIG_ARCH_CHIP_STM32H5=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV8M_STACKCHECK=y
+CONFIG_BOARD_LOOPSPERMSEC=9251
+CONFIG_BUILTIN=y
+CONFIG_CAPTURE=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_EXAMPLES_CAPTURE=y
+CONFIG_EXAMPLES_CAPTURE_DEVPATH="/dev/cap0"
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_LINE_MAX=64
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=655360
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_READLINE_TABCOMPLETION=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_STACK_COLORATION=y
+CONFIG_STM32_TIM4=y
+CONFIG_STM32_TIM4_CAP=y
+CONFIG_STM32_TIM4_CLOCK=25000000
+CONFIG_STM32_USART3=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_TIMER=y
+CONFIG_USART3_SERIAL_CONSOLE=y
diff --git a/boards/arm/stm32h5/nucleo-h563zi/include/board.h 
b/boards/arm/stm32h5/nucleo-h563zi/include/board.h
index 80e1eddf29a..304ff31f2d1 100644
--- a/boards/arm/stm32h5/nucleo-h563zi/include/board.h
+++ b/boards/arm/stm32h5/nucleo-h563zi/include/board.h
@@ -364,6 +364,13 @@
 
 #define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_2 /* PE9 */
 
+/* TIM4 capture (PWM input).  The capture driver measures the signal on the
+ * pin of the selected channel (CONFIG_STM32_TIM4_CHANNEL, 1 by default).
+ */
+
+#define GPIO_TIM4_CH1IN  GPIO_TIM4_CH1IN_1  /* PB6 */
+#define GPIO_TIM4_CH2IN  GPIO_TIM4_CH2IN_1  /* PB7 */
+
 /* USART3 GPIOs *************************************************************/
 
 /* USART3 (Nucleo Virtual Console): Default board solder bridge configuration
diff --git a/boards/arm/stm32h5/nucleo-h563zi/src/stm32_bringup.c 
b/boards/arm/stm32h5/nucleo-h563zi/src/stm32_bringup.c
index 335dfd2cd22..0b67b2d6ff1 100644
--- a/boards/arm/stm32h5/nucleo-h563zi/src/stm32_bringup.c
+++ b/boards/arm/stm32h5/nucleo-h563zi/src/stm32_bringup.c
@@ -39,10 +39,83 @@
 
 #include "board_common.h"
 
+#if defined(CONFIG_CAPTURE) && defined(CONFIG_STM32_TIMX_CAP)
+#  include <errno.h>
+#  include <nuttx/timers/capture.h>
+#  include "stm32_capture.h"
+#  define HAVE_CAPTURE 1
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_capture_setup
+ *
+ * Description:
+ *   Initialize and register the capture drivers of the timers that are
+ *   configured for capture.  They are registered as /dev/cap0, /dev/cap1,
+ *   etc. in the order of the timer numbers.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_CAPTURE
+static int stm32_capture_setup(void)
+{
+  struct cap_lowerhalf_s *lower[] =
+    {
+#ifdef CONFIG_STM32_TIM1_CAP
+      stm32_cap_initialize(1),
+#endif
+#ifdef CONFIG_STM32_TIM2_CAP
+      stm32_cap_initialize(2),
+#endif
+#ifdef CONFIG_STM32_TIM3_CAP
+      stm32_cap_initialize(3),
+#endif
+#ifdef CONFIG_STM32_TIM4_CAP
+      stm32_cap_initialize(4),
+#endif
+#ifdef CONFIG_STM32_TIM5_CAP
+      stm32_cap_initialize(5),
+#endif
+#ifdef CONFIG_STM32_TIM8_CAP
+      stm32_cap_initialize(8),
+#endif
+#ifdef CONFIG_STM32_TIM12_CAP
+      stm32_cap_initialize(12),
+#endif
+#ifdef CONFIG_STM32_TIM15_CAP
+      stm32_cap_initialize(15),
+#endif
+    };
+
+  size_t count = sizeof(lower) / sizeof(lower[0]);
+  size_t i;
+
+  for (i = 0; i < count; i++)
+    {
+      if (lower[i] == NULL)
+        {
+          syslog(LOG_ERR, "ERROR: Failed to initialize a capture timer\n");
+          return -ENODEV;
+        }
+    }
+
+  /* This will register "/dev/cap0" ... "/dev/cap<count-1>" */
+
+  return cap_register_multiple("/dev/cap", lower, count);
+}
+#endif /* HAVE_CAPTURE */
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -147,6 +220,16 @@ int stm32_bringup(void)
     }
 #endif
 
+#ifdef HAVE_CAPTURE
+  /* Initialize the capture drivers and register them as /dev/capN */
+
+  ret = stm32_capture_setup();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: stm32_capture_setup() failed: %d\n", ret);
+    }
+#endif
+
 #ifdef CONFIG_USBHOST
   ret = stm32_usbhost_initialize();
   if (ret < 0)

Reply via email to