From 9783c88425b6741a7ee572cde6772410cb17cc9b Mon Sep 17 00:00:00 2001 From: Kyle Wilson Date: Fri, 3 Jan 2025 10:35:43 -0600 Subject: [PATCH] Initial STM32H5 Timers Commit Used the STM32H7 as a reference. Removed APB enabling from stm32h5xx_rcc.c. This is done in timer initialization, like STM32H7. Also removed LPTIM. Will add later. tim_lowerhalf: Timers 9, 10, and 11 removed. Timers 15,16, and 17 added. Removed low-power timers from Kconfig. Not implemented yet. Style Updates Added stm32_tim_enable and stm32_tim_disable to Timer operations. --- arch/arm/src/stm32h5/Kconfig | 3111 +++++++++++++++++++- arch/arm/src/stm32h5/Make.defs | 6 +- arch/arm/src/stm32h5/stm32_tim.c | 1553 ++++++++++ arch/arm/src/stm32h5/stm32_tim.h | 223 ++ arch/arm/src/stm32h5/stm32_tim_lowerhalf.c | 586 ++++ arch/arm/src/stm32h5/stm32h5xx_rcc.c | 84 - 6 files changed, 5477 insertions(+), 86 deletions(-) create mode 100644 arch/arm/src/stm32h5/stm32_tim.c create mode 100644 arch/arm/src/stm32h5/stm32_tim.h create mode 100644 arch/arm/src/stm32h5/stm32_tim_lowerhalf.c diff --git a/arch/arm/src/stm32h5/Kconfig b/arch/arm/src/stm32h5/Kconfig index 3a1e04d36a..4fd8583a4c 100644 --- a/arch/arm/src/stm32h5/Kconfig +++ b/arch/arm/src/stm32h5/Kconfig @@ -299,6 +299,10 @@ config STM32H5_SPI_DMA bool default n +config STM32H5_TIM + bool + default n + # These are the peripheral selections proper config STM32H5_ADC1 @@ -477,8 +481,81 @@ config STM32H5_SPI6 select SPI select STM32H5_SPI -endmenu +menu "STM32H5 Timer Selection" +config STM32H5_TIM1 + bool "TIM1" + default n + select STM32H5_TIM + +config STM32H5_TIM2 + bool "TIM2" + default n + select STM32H5_TIM + +config STM32H5_TIM3 + bool "TIM3" + default n + select STM32H5_TIM + +config STM32H5_TIM4 + bool "TIM4" + default n + select STM32H5_TIM + +config STM32H5_TIM5 + bool "TIM5" + default n + select STM32H5_TIM + +config STM32H5_TIM6 + bool "TIM6" + default n + select STM32H5_TIM + +config STM32H5_TIM7 + bool "TIM7" + default n + select STM32H5_TIM + +config STM32H5_TIM8 + bool "TIM8" + default n + select STM32H5_TIM + +config STM32H5_TIM12 + bool "TIM12" + default n + select STM32H5_TIM + +config STM32H5_TIM13 + bool "TIM13" + default n + select STM32H5_TIM + +config STM32H5_TIM14 + bool "TIM14" + default n + select STM32H5_TIM + +config STM32H5_TIM15 + bool "TIM15" + default n + select STM32H5_TIM + +config STM32H5_TIM16 + bool "TIM16" + default n + select STM32H5_TIM + +config STM32H5_TIM17 + bool "TIM17" + default n + select STM32H5_TIM + +endmenu # STM32H5 Timer Selection + +endmenu config STM32H5_FLASH_PREFETCH bool "Enable FLASH Pre-fetch" @@ -661,6 +738,3038 @@ config STM32H5_SPI6_COMMTYPE endmenu # "SPI Configuration" +menu "Timer Configuration" + +if SCHED_TICKLESS + +config STM32H5_TICKLESS_TIMER + int "Tickless hardware timer" + default 2 + range 1 17 + ---help--- + If the Tickless OS feature is enabled, then one clock must be + assigned to provided the timer needed by the OS. + +config STM32H5_TICKLESS_CHANNEL + int "Tickless timer channel" + default 1 + range 1 4 + ---help--- + If the Tickless OS feature is enabled, the one clock must be + assigned to provided the free-running timer needed by the OS + and one channel on that clock is needed to handle intervals. + +endif # SCHED_TICKLESS + +config STM32H5_ONESHOT + bool "TIM one-shot wrapper" + default n + ---help--- + Enable a wrapper around the low level timer/counter functions to + support one-shot timer. + +config STM32H5_ONESHOT_MAXTIMERS + int "Maximum number of oneshot timers" + default 1 + range 1 8 + depends on STM32H5_ONESHOT + ---help--- + Determines the maximum number of oneshot timers that can be + supported. This setting pre-allocates some minimal support for each + of the timers and places an upper limit on the number of oneshot + timers that you can use. + +config STM32H5_PWM_LL_OPS + bool "PWM low-level operations" + default n + ---help--- + Enable low-level PWM ops. + +config STM32H5_TIM1_PWM + bool "TIM1 PWM" + default n + depends on STM32H5_TIM1 + select STM32H5_PWM + ---help--- + Reserve timer 1 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM1 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM1_PWM + +config STM32H5_TIM1_MODE + int "TIM1 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +config STM32H5_TIM1_LOCK + int "TIM1 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 1 lock level configuration + +config STM32H5_TIM1_TDTS + int "TIM1 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 1 dead-time and sampling clock (t_DTS) division + +config STM32H5_TIM1_DEADTIME + int "TIM1 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 1 initial dead-time + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM1_CHANNEL1 + bool "TIM1 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM1_CHANNEL1 + +config STM32H5_TIM1_CH1MODE + int "TIM1 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM1_CH1OUT + bool "TIM1 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32H5_TIM1_CH1NOUT + bool "TIM1 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32H5_TIM1_CHANNEL1 + +config STM32H5_TIM1_CHANNEL2 + bool "TIM1 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM1_CHANNEL2 + +config STM32H5_TIM1_CH2MODE + int "TIM1 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM1_CH2OUT + bool "TIM1 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32H5_TIM1_CH2NOUT + bool "TIM1 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32H5_TIM1_CHANNEL2 + +config STM32H5_TIM1_CHANNEL3 + bool "TIM1 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32H5_TIM1_CHANNEL3 + +config STM32H5_TIM1_CH3MODE + int "TIM1 Channel 3 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM1_CH3OUT + bool "TIM1 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32H5_TIM1_CH3NOUT + bool "TIM1 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + +endif # STM32H5_TIM1_CHANNEL3 + +config STM32H5_TIM1_CHANNEL4 + bool "TIM1 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32H5_TIM1_CHANNEL4 + +config STM32H5_TIM1_CH4MODE + int "TIM1 Channel 4 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM1_CH4OUT + bool "TIM1 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM1_CHANNEL4 + +config STM32H5_TIM1_CHANNEL5 + bool "TIM1 Channel 5 (internal)" + default n + ---help--- + Enables channel 5 (not available externally) + +if STM32H5_TIM1_CHANNEL5 + +config STM32H5_TIM1_CH5MODE + int "TIM1 Channel 5 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM1_CH5OUT + bool "TIM1 Channel 5 Output" + default n + ---help--- + Enables channel 5 output. + +endif # STM32H5_TIM1_CHANNEL5 + +config STM32H5_TIM1_CHANNEL6 + bool "TIM1 Channel 6 (internal)" + default n + ---help--- + Enables channel 6 (not available externally) + +if STM32H5_TIM1_CHANNEL6 + +config STM32H5_TIM1_CH6MODE + int "TIM1 Channel 6 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM1_CH6OUT + bool "TIM1 Channel 6 Output" + default n + ---help--- + Enables channel 6 output. + +endif # STM32H5_TIM1_CHANNEL6 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM1_CHANNEL + int "TIM1 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM1 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +if STM32H5_TIM1_CHANNEL = 1 + +config STM32H5_TIM1_CH1OUT + bool "TIM1 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32H5_TIM1_CH1NOUT + bool "TIM1 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32H5_TIM1_CHANNEL = 1 + +if STM32H5_TIM1_CHANNEL = 2 + +config STM32H5_TIM1_CH2OUT + bool "TIM1 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32H5_TIM1_CH2NOUT + bool "TIM1 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32H5_TIM1_CHANNEL = 2 + +if STM32H5_TIM1_CHANNEL = 3 + +config STM32H5_TIM1_CH3OUT + bool "TIM1 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32H5_TIM1_CH3NOUT + bool "TIM1 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + +endif # STM32H5_TIM1_CHANNEL = 3 + +if STM32H5_TIM1_CHANNEL = 4 + +config STM32H5_TIM1_CH4OUT + bool "TIM1 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM1_CHANNEL = 4 + +config STM32H5_TIM1_CHMODE + int "TIM1 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM1_PWM + +config STM32H5_TIM2_PWM + bool "TIM2 PWM" + default n + depends on STM32H5_TIM2 + select STM32H5_PWM + ---help--- + Reserve timer 2 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM2 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM2_PWM + +config STM32H5_TIM2_MODE + int "TIM2 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM2_CHANNEL1 + bool "TIM2 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM2_CHANNEL1 + +config STM32H5_TIM2_CH1MODE + int "TIM2 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM2_CH1OUT + bool "TIM2 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM2_CHANNEL1 + +config STM32H5_TIM2_CHANNEL2 + bool "TIM2 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM2_CHANNEL2 + +config STM32H5_TIM2_CH2MODE + int "TIM2 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM2_CH2OUT + bool "TIM2 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM2_CHANNEL2 + +config STM32H5_TIM2_CHANNEL3 + bool "TIM2 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32H5_TIM2_CHANNEL3 + +config STM32H5_TIM2_CH3MODE + int "TIM2 Channel 3 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM2_CH3OUT + bool "TIM2 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM2_CHANNEL3 + +config STM32H5_TIM2_CHANNEL4 + bool "TIM2 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32H5_TIM2_CHANNEL4 + +config STM32H5_TIM2_CH4MODE + int "TIM2 Channel 4 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM2_CH4OUT + bool "TIM2 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM2_CHANNEL4 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM2_CHANNEL + int "TIM2 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM2 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +if STM32H5_TIM2_CHANNEL = 1 + +config STM32H5_TIM2_CH1OUT + bool "TIM2 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM2_CHANNEL = 1 + +if STM32H5_TIM2_CHANNEL = 2 + +config STM32H5_TIM2_CH2OUT + bool "TIM2 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM2_CHANNEL = 2 + +if STM32H5_TIM2_CHANNEL = 3 + +config STM32H5_TIM2_CH3OUT + bool "TIM2 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM2_CHANNEL = 3 + +if STM32H5_TIM2_CHANNEL = 4 + +config STM32H5_TIM2_CH4OUT + bool "TIM2 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM2_CHANNEL = 4 + +config STM32H5_TIM2_CHMODE + int "TIM2 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM2_PWM + +config STM32H5_TIM3_PWM + bool "TIM3 PWM" + default n + depends on STM32H5_TIM3 + select STM32H5_PWM + ---help--- + Reserve timer 3 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM3 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM3_PWM + +config STM32H5_TIM3_MODE + int "TIM3 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM3_CHANNEL1 + bool "TIM3 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM3_CHANNEL1 + +config STM32H5_TIM3_CH1MODE + int "TIM3 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM3_CH1OUT + bool "TIM3 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM3_CHANNEL1 + +config STM32H5_TIM3_CHANNEL2 + bool "TIM3 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM3_CHANNEL2 + +config STM32H5_TIM3_CH2MODE + int "TIM3 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM3_CH2OUT + bool "TIM3 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM3_CHANNEL2 + +config STM32H5_TIM3_CHANNEL3 + bool "TIM3 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32H5_TIM3_CHANNEL3 + +config STM32H5_TIM3_CH3MODE + int "TIM3 Channel 3 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM3_CH3OUT + bool "TIM3 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM3_CHANNEL3 + +config STM32H5_TIM3_CHANNEL4 + bool "TIM3 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32H5_TIM3_CHANNEL4 + +config STM32H5_TIM3_CH4MODE + int "TIM3 Channel 4 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM3_CH4OUT + bool "TIM3 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM3_CHANNEL4 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM3_CHANNEL + int "TIM3 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM3 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +if STM32H5_TIM3_CHANNEL = 1 + +config STM32H5_TIM3_CH1OUT + bool "TIM3 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM3_CHANNEL = 1 + +if STM32H5_TIM3_CHANNEL = 2 + +config STM32H5_TIM3_CH2OUT + bool "TIM3 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM3_CHANNEL = 2 + +if STM32H5_TIM3_CHANNEL = 3 + +config STM32H5_TIM3_CH3OUT + bool "TIM3 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM3_CHANNEL = 3 + +if STM32H5_TIM3_CHANNEL = 4 + +config STM32H5_TIM3_CH4OUT + bool "TIM3 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM3_CHANNEL = 4 + +config STM32H5_TIM3_CHMODE + int "TIM3 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM3_PWM + +config STM32H5_TIM4_PWM + bool "TIM4 PWM" + default n + depends on STM32H5_TIM4 + select STM32H5_PWM + ---help--- + Reserve timer 4 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM4 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM4_PWM + +config STM32H5_TIM4_MODE + int "TIM4 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM4_CHANNEL1 + bool "TIM4 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM4_CHANNEL1 + +config STM32H5_TIM4_CH1MODE + int "TIM4 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM4_CH1OUT + bool "TIM4 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM4_CHANNEL1 + +config STM32H5_TIM4_CHANNEL2 + bool "TIM4 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM4_CHANNEL2 + +config STM32H5_TIM4_CH2MODE + int "TIM4 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM4_CH2OUT + bool "TIM4 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM4_CHANNEL2 + +config STM32H5_TIM4_CHANNEL3 + bool "TIM4 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32H5_TIM4_CHANNEL3 + +config STM32H5_TIM4_CH3MODE + int "TIM4 Channel 3 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM4_CH3OUT + bool "TIM4 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM4_CHANNEL3 + +config STM32H5_TIM4_CHANNEL4 + bool "TIM4 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32H5_TIM4_CHANNEL4 + +config STM32H5_TIM4_CH4MODE + int "TIM4 Channel 4 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM4_CH4OUT + bool "TIM4 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM4_CHANNEL4 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM4_CHANNEL + int "TIM4 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM4 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +if STM32H5_TIM4_CHANNEL = 1 + +config STM32H5_TIM4_CH1OUT + bool "TIM4 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM4_CHANNEL = 1 + +if STM32H5_TIM4_CHANNEL = 2 + +config STM32H5_TIM4_CH2OUT + bool "TIM4 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM4_CHANNEL = 2 + +if STM32H5_TIM4_CHANNEL = 3 + +config STM32H5_TIM4_CH3OUT + bool "TIM4 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM4_CHANNEL = 3 + +if STM32H5_TIM4_CHANNEL = 4 + +config STM32H5_TIM4_CH4OUT + bool "TIM4 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM4_CHANNEL = 4 + +config STM32H5_TIM4_CHMODE + int "TIM4 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM4_PWM + +config STM32H5_TIM5_PWM + bool "TIM5 PWM" + default n + depends on STM32H5_TIM5 + select STM32H5_PWM + ---help--- + Reserve timer 5 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM5 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM5_PWM + +config STM32H5_TIM5_MODE + int "TIM5 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM5_CHANNEL1 + bool "TIM5 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM5_CHANNEL1 + +config STM32H5_TIM5_CH1MODE + int "TIM5 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM5_CH1OUT + bool "TIM5 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM5_CHANNEL1 + +config STM32H5_TIM5_CHANNEL2 + bool "TIM5 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM5_CHANNEL2 + +config STM32H5_TIM5_CH2MODE + int "TIM5 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM5_CH2OUT + bool "TIM5 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM5_CHANNEL2 + +config STM32H5_TIM5_CHANNEL3 + bool "TIM5 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32H5_TIM5_CHANNEL3 + +config STM32H5_TIM5_CH3MODE + int "TIM5 Channel 3 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM5_CH3OUT + bool "TIM5 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM5_CHANNEL3 + +config STM32H5_TIM5_CHANNEL4 + bool "TIM5 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32H5_TIM5_CHANNEL4 + +config STM32H5_TIM5_CH4MODE + int "TIM5 Channel 4 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM5_CH4OUT + bool "TIM5 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM5_CHANNEL4 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM5_CHANNEL + int "TIM5 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM5 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +if STM32H5_TIM5_CHANNEL = 1 + +config STM32H5_TIM5_CH1OUT + bool "TIM5 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM5_CHANNEL = 1 + +if STM32H5_TIM5_CHANNEL = 2 + +config STM32H5_TIM5_CH2OUT + bool "TIM5 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM5_CHANNEL = 2 + +if STM32H5_TIM5_CHANNEL = 3 + +config STM32H5_TIM5_CH3OUT + bool "TIM5 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32H5_TIM5_CHANNEL = 3 + +if STM32H5_TIM5_CHANNEL = 4 + +config STM32H5_TIM5_CH4OUT + bool "TIM5 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM5_CHANNEL = 4 + +config STM32H5_TIM5_CHMODE + int "TIM5 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM5_PWM + +config STM32H5_TIM8_PWM + bool "TIM8 PWM" + default n + depends on STM32H5_TIM8 + select STM32H5_PWM + ---help--- + Reserve timer 8 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM8 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM8_PWM + +config STM32H5_TIM8_MODE + int "TIM8 Mode" + default 0 + range 0 4 + ---help--- + Specifies the timer mode. + +config STM32H5_TIM8_LOCK + int "TIM8 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 8 lock level configuration + +config STM32H5_TIM8_DEADTIME + int "TIM8 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 8 initial dead-time + +config STM32H5_TIM8_TDTS + int "TIM8 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 8 dead-time and sampling clock (t_DTS) division + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM8_CHANNEL1 + bool "TIM8 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM8_CHANNEL1 + +config STM32H5_TIM8_CH1MODE + int "TIM8 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM8_CH1OUT + bool "TIM8 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32H5_TIM8_CH1NOUT + bool "TIM8 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32H5_TIM8_CHANNEL1 + +config STM32H5_TIM8_CHANNEL2 + bool "TIM8 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM8_CHANNEL2 + +config STM32H5_TIM8_CH2MODE + int "TIM8 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM8_CH2OUT + bool "TIM8 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32H5_TIM8_CH2NOUT + bool "TIM8 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32H5_TIM8_CHANNEL2 + +config STM32H5_TIM8_CHANNEL3 + bool "TIM8 Channel 3" + default n + ---help--- + Enables channel 3. + +if STM32H5_TIM8_CHANNEL3 + +config STM32H5_TIM8_CH3MODE + int "TIM8 Channel 3 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM8_CH3OUT + bool "TIM8 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32H5_TIM8_CH3NOUT + bool "TIM8 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + +endif # STM32H5_TIM8_CHANNEL3 + +config STM32H5_TIM8_CHANNEL4 + bool "TIM8 Channel 4" + default n + ---help--- + Enables channel 4. + +if STM32H5_TIM8_CHANNEL4 + +config STM32H5_TIM8_CH4MODE + int "TIM8 Channel 4 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM8_CH4OUT + bool "TIM8 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM8_CHANNEL4 + +config STM32H5_TIM8_CHANNEL5 + bool "TIM8 Channel 5 (internal)" + default n + ---help--- + Enables channel 5 (not available externally) + +if STM32H5_TIM8_CHANNEL5 + +config STM32H5_TIM8_CH5MODE + int "TIM8 Channel 5 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM8_CH5OUT + bool "TIM8 Channel 5 Output" + default n + ---help--- + Enables channel 5 output. + +endif # STM32H5_TIM8_CHANNEL5 + +config STM32H5_TIM8_CHANNEL6 + bool "TIM8 Channel 6 (internal)" + default n + ---help--- + Enables channel 6 (not available externally) + +if STM32H5_TIM8_CHANNEL6 + +config STM32H5_TIM8_CH6MODE + int "TIM8 Channel 6 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM8_CH6OUT + bool "TIM8 Channel 6 Output" + default n + ---help--- + Enables channel 6 output. + +endif # STM32H5_TIM8_CHANNEL6 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM8_CHANNEL + int "TIM8 PWM Output Channel" + default 1 + range 1 4 + ---help--- + If TIM8 is enabled for PWM usage, you also need specifies the timer output + channel {1,..,4} + +if STM32H5_TIM8_CHANNEL = 1 + +config STM32H5_TIM8_CH1OUT + bool "TIM8 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32H5_TIM8_CH1NOUT + bool "TIM8 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32H5_TIM8_CHANNEL = 1 + +if STM32H5_TIM8_CHANNEL = 2 + +config STM32H5_TIM8_CH2OUT + bool "TIM8 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32H5_TIM8_CH2NOUT + bool "TIM8 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32H5_TIM8_CHANNEL = 2 + +if STM32H5_TIM8_CHANNEL = 3 + +config STM32H5_TIM8_CH3OUT + bool "TIM8 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32H5_TIM8_CH3NOUT + bool "TIM8 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + +endif # STM32H5_TIM8_CHANNEL = 3 + +if STM32H5_TIM8_CHANNEL = 4 + +config STM32H5_TIM8_CH4OUT + bool "TIM8 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32H5_TIM8_CHANNEL = 4 + +config STM32H5_TIM8_CHMODE + int "TIM8 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM8_PWM + +config STM32H5_TIM12_PWM + bool "TIM12 PWM" + default n + depends on STM32H5_TIM12 + select STM32H5_PWM + ---help--- + Reserve timer 12 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM12 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM12_PWM + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM12_CHANNEL1 + bool "TIM12 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM12_CHANNEL1 + +config STM32H5_TIM12_CH1MODE + int "TIM12 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM12_CH1OUT + bool "TIM12 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM12_CHANNEL1 + +config STM32H5_TIM12_CHANNEL2 + bool "TIM12 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM12_CHANNEL2 + +config STM32H5_TIM12_CH2MODE + int "TIM12 Channel 2 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM12_CH2OUT + bool "TIM12 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM12_CHANNEL2 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM12_CHANNEL + int "TIM12 PWM Output Channel" + default 1 + range 1 2 + ---help--- + If TIM12 is enabled for PWM usage, you also need specifies the timer output + channel {1,2} + +if STM32H5_TIM12_CHANNEL = 1 + +config STM32H5_TIM12_CH1OUT + bool "TIM12 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM12_CHANNEL = 1 + +if STM32H5_TIM12_CHANNEL = 2 + +config STM32H5_TIM12_CH2OUT + bool "TIM12 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM12_CHANNEL = 2 + +config STM32H5_TIM12_CHMODE + int "TIM12 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM12_PWM + +config STM32H5_TIM13_PWM + bool "TIM13 PWM" + default n + depends on STM32H5_TIM13 + select STM32H5_PWM + ---help--- + Reserve timer 13 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM13 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM13_PWM + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM13_CHANNEL1 + bool "TIM13 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM13_CHANNEL1 + +config STM32H5_TIM13_CH1MODE + int "TIM13 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM13_CH1OUT + bool "TIM13 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM13_CHANNEL1 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM13_CHANNEL + int "TIM13 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM13 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +if STM32H5_TIM13_CHANNEL = 1 + +config STM32H5_TIM13_CH1OUT + bool "TIM13 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM13_CHANNEL = 1 + +config STM32H5_TIM13_CHMODE + int "TIM13 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM13_PWM + +config STM32H5_TIM14_PWM + bool "TIM14 PWM" + default n + depends on STM32H5_TIM14 + select STM32H5_PWM + ---help--- + Reserve timer 14 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM14 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM14_PWM + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM14_CHANNEL1 + bool "TIM14 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM14_CHANNEL1 + +config STM32H5_TIM14_CH1MODE + int "TIM14 Channel 1 Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM14_CH1OUT + bool "TIM14 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM14_CHANNEL1 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM14_CHANNEL + int "TIM14 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM14 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +if STM32H5_TIM14_CHANNEL = 1 + +config STM32H5_TIM14_CH1OUT + bool "TIM14 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM14_CHANNEL = 1 + +config STM32H5_TIM14_CHMODE + int "TIM14 Channel Mode" + default 6 + range 0 11 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM14_PWM + +config STM32H5_TIM15_PWM + bool "TIM15 PWM" + default n + depends on STM32H5_TIM15 + select STM32H5_PWM + ---help--- + Reserve timer 15 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM15 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM15_PWM + +config STM32H5_TIM15_LOCK + int "TIM15 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 15 lock level configuration + +config STM32H5_TIM15_TDTS + int "TIM15 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 15 dead-time and sampling clock (t_DTS) division + +config STM32H5_TIM15_DEADTIME + int "TIM15 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 15 initial dead-time + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM15_CHANNEL1 + bool "TIM15 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM15_CHANNEL1 + +config STM32H5_TIM15_CH1MODE + int "TIM15 Channel 1 Mode" + default 6 + range 0 9 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM15_CH1OUT + bool "TIM15 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32H5_TIM15_CH1NOUT + bool "TIM15 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32H5_TIM15_CHANNEL1 + +config STM32H5_TIM15_CHANNEL2 + bool "TIM15 Channel 2" + default n + ---help--- + Enables channel 2. + +if STM32H5_TIM15_CHANNEL2 + +config STM32H5_TIM15_CH2MODE + int "TIM15 Channel 2 Mode" + default 6 + range 0 9 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM15_CH2OUT + bool "TIM15 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32H5_TIM15_CHANNEL2 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM15_CHANNEL + int "TIM15 PWM Output Channel" + default 1 + range 1 2 + ---help--- + If TIM15 is enabled for PWM usage, you also need specifies the timer output + channel {1,2} + +if STM32H5_TIM15_CHANNEL = 1 + +config STM32H5_TIM15_CH1OUT + bool "TIM15 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32H5_TIM15_CH1NOUT + bool "TIM15 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32H5_TIM15_CHANNEL = 1 + +if STM32H5_TIM15_CHANNEL = 2 + +config STM32H5_TIM15_CH2OUT + bool "TIM15 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32H5_TIM15_CH2NOUT + bool "TIM15 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32H5_TIM15_CHANNEL = 2 + +config STM32H5_TIM15_CHMODE + int "TIM15 Channel Mode" + default 6 + range 0 9 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM15_PWM + +config STM32H5_TIM16_PWM + bool "TIM16 PWM" + default n + depends on STM32H5_TIM16 + select STM32H5_PWM + ---help--- + Reserve timer 16 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM16 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM16_PWM + +config STM32H5_TIM16_LOCK + int "TIM16 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 16 lock level configuration + +config STM32H5_TIM16_TDTS + int "TIM16 t_DTS division" + default 0 + range 0 2 + ---help--- + Timer 16 dead-time and sampling clock (t_DTS) division + +config STM32H5_TIM16_DEADTIME + int "TIM16 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 16 initial dead-time + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM16_CHANNEL1 + bool "TIM16 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM16_CHANNEL1 + +config STM32H5_TIM16_CH1MODE + int "TIM16 Channel 1 Mode" + default 6 + range 0 7 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM16_CH1OUT + bool "TIM16 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM16_CHANNEL1 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM16_CHANNEL + int "TIM16 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM16 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +if STM32H5_TIM16_CHANNEL = 1 + +config STM32H5_TIM16_CH1OUT + bool "TIM16 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM16_CHANNEL = 1 + +config STM32H5_TIM16_CHMODE + int "TIM16 Channel Mode" + default 6 + range 0 7 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM16_PWM + +config STM32H5_TIM17_PWM + bool "TIM17 PWM" + default n + depends on STM32H5_TIM17 + select STM32H5_PWM + ---help--- + Reserve timer 17 for use by PWM + + Timer devices may be used for different purposes. One special purpose is + to generate modulated outputs for such things as motor control. If STM32H5_TIM17 + is defined then THIS following may also be defined to indicate that + the timer is intended to be used for pulsed output modulation. + +if STM32H5_TIM17_PWM + +config STM32H5_TIM17_LOCK + int "TIM17 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 17 lock level configuration + +config STM32H5_TIM17_TDTS + int "TIM17 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 17 dead-time and sampling clock (t_DTS) division + +config STM32H5_TIM17_DEADTIME + int "TIM17 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 17 initial dead-time + +if STM32H5_PWM_MULTICHAN + +config STM32H5_TIM17_CHANNEL1 + bool "TIM17 Channel 1" + default n + ---help--- + Enables channel 1. + +if STM32H5_TIM17_CHANNEL1 + +config STM32H5_TIM17_CH1MODE + int "TIM17 Channel 1 Mode" + default 6 + range 0 7 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +config STM32H5_TIM17_CH1OUT + bool "TIM17 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM17_CHANNEL1 + +endif # STM32H5_PWM_MULTICHAN + +if !STM32H5_PWM_MULTICHAN + +config STM32H5_TIM17_CHANNEL + int "TIM17 PWM Output Channel" + default 1 + range 1 1 + ---help--- + If TIM17 is enabled for PWM usage, you also need specifies the timer output + channel {1} + +if STM32H5_TIM17_CHANNEL = 1 + +config STM32H5_TIM17_CH1OUT + bool "TIM17 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32H5_TIM17_CHANNEL = 1 + +config STM32H5_TIM17_CHMODE + int "TIM17 Channel Mode" + default 6 + range 0 7 + ---help--- + Specifies the channel mode. See enum stm32_pwm_chanmode_e in stm32_pwm.h. + +endif # !STM32H5_PWM_MULTICHAN + +endif # STM32H5_TIM17_PWM + +config STM32H5_PWM_MULTICHAN + bool "PWM Multiple Output Channels" + default n + depends on STM32H5_PWM + select ARCH_HAVE_PWM_MULTICHAN + ---help--- + Specifies that the PWM driver supports multiple output + channels per timer. + +config STM32H5_TIM1_ADC + bool "TIM1 ADC" + default n + depends on STM32H5_TIM1 && STM32H5_ADC + ---help--- + Reserve timer 1 for use by an ADC + + Timer devices may be used for different purposes. If STM32H5_TIM1 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM1" + default STM32H5_TIM1_ADC1 + depends on STM32H5_TIM1_ADC + +config STM32H5_TIM1_ADC1 + bool "Use TIM1 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM1 to trigger ADC1 + +config STM32H5_TIM1_ADC2 + bool "Use TIM1 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM1 to trigger ADC2 + +endchoice + +config STM32H5_TIM2_ADC + bool "TIM2 ADC" + default n + depends on STM32H5_TIM2 && STM32H5_ADC + ---help--- + Reserve timer 2 for use by an ADC + + Timer devices may be used for different purposes. If STM32H5_TIM2 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM2" + default STM32H5_TIM2_ADC1 + depends on STM32H5_TIM2_ADC + +config STM32H5_TIM2_ADC1 + bool "Use TIM2 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM2 to trigger ADC1 + +config STM32H5_TIM2_ADC2 + bool "Use TIM2 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM2 to trigger ADC2 + +endchoice + +config STM32H5_TIM3_ADC + bool "TIM3 ADC" + default n + depends on STM32H5_TIM3 && STM32H5_ADC + ---help--- + Reserve timer 3 for use by an ADC + + Timer devices may be used for different purposes. If STM32H5_TIM3 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM3" + default STM32H5_TIM3_ADC1 + depends on STM32H5_TIM3_ADC + +config STM32H5_TIM3_ADC1 + bool "Use TIM3 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM3 to trigger ADC1 + +config STM32H5_TIM3_ADC2 + bool "Use TIM3 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM3 to trigger ADC2 + +endchoice + +config STM32H5_TIM4_ADC + bool "TIM4 ADC" + default n + depends on STM32H5_TIM4 && STM32H5_ADC + ---help--- + Reserve timer 4 for use by ADC + + Timer devices may be used for different purposes. If STM32H5_TIM4 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM4" + default STM32H5_TIM4_ADC1 + depends on STM32H5_TIM4_ADC + +config STM32H5_TIM4_ADC1 + bool "Use TIM4 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM4 to trigger ADC1 + +config STM32H5_TIM4_ADC2 + bool "Use TIM4 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM4 to trigger ADC2 + +endchoice + +config STM32H5_TIM6_ADC + bool "TIM6 ADC" + default n + depends on STM32H5_TIM6 && STM32H5_ADC + ---help--- + Reserve timer 6 for use by ADC + + Timer devices may be used for different purposes. If STM32H5_TIM6 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM6" + default STM32H5_TIM6_ADC1 + depends on STM32H5_TIM6_ADC + +config STM32H5_TIM6_ADC1 + bool "Use TIM6 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM6 to trigger ADC1 + +config STM32H5_TIM6_ADC2 + bool "Use TIM6 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM6 to trigger ADC2 + +endchoice + +config STM32H5_TIM8_ADC + bool "TIM8 ADC" + default n + depends on STM32H5_TIM8 && STM32H5_ADC + ---help--- + Reserve timer 8 for use by ADC + + Timer devices may be used for different purposes. If STM32H5_TIM8 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM8" + default STM32H5_TIM8_ADC1 + depends on STM32H5_TIM8_ADC + +config STM32H5_TIM8_ADC1 + bool "Use TIM8 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM8 to trigger ADC1 + +config STM32H5_TIM8_ADC2 + bool "Use TIM8 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM8 to trigger ADC2 + +endchoice + +config STM32H5_TIM15_ADC + bool "TIM15 ADC" + default n + depends on STM32H5_TIM15 && STM32H5_ADC + ---help--- + Reserve timer 15 for use by ADC + + Timer devices may be used for different purposes. If STM32H5_TIM15 is + defined then the following may also be defined to indicate that the + timer is intended to be used for ADC conversion. Note that ADC usage + requires two definition: Not only do you have to assign the timer + for used by the ADC, but then you also have to configure which ADC + channel it is assigned to. + +choice + prompt "Select ADC for use with TIM15" + default STM32H5_TIM15_ADC1 + depends on STM32H5_TIM15_ADC + +config STM32H5_TIM15_ADC1 + bool "Use TIM15 for ADC1" + depends on STM32H5_ADC1 + select STM32H5_HAVE_ADC1_TIMER + ---help--- + Reserve TIM15 to trigger ADC1 + +config STM32H5_TIM15_ADC2 + bool "Use TIM15 for ADC2" + depends on STM32H5_ADC2 + select STM32H5_HAVE_ADC2_TIMER + ---help--- + Reserve TIM15 to trigger ADC2 + +endchoice + +config STM32H5_HAVE_ADC1_TIMER + bool + +config STM32H5_HAVE_ADC2_TIMER + bool + +config STM32H5_ADC1_SAMPLE_FREQUENCY + int "ADC1 Sampling Frequency" + default 100 + depends on STM32H5_HAVE_ADC1_TIMER + ---help--- + ADC1 sampling frequency. Default: 100Hz + +config STM32H5_ADC1_TIMTRIG + int "ADC1 Timer Trigger" + default 0 + range 0 4 + depends on STM32H5_HAVE_ADC1_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32H5_ADC2_SAMPLE_FREQUENCY + int "ADC2 Sampling Frequency" + default 100 + depends on STM32H5_HAVE_ADC2_TIMER + ---help--- + ADC2 sampling frequency. Default: 100Hz + +config STM32H5_ADC2_TIMTRIG + int "ADC2 Timer Trigger" + default 0 + range 0 4 + depends on STM32H5_HAVE_ADC2_TIMER + ---help--- + Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO + +config STM32H5_TIM1_CAP + bool "TIM1 Capture" + default n + depends on STM32H5_TIM1 + ---help--- + Reserve timer 1 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM2_CAP + bool "TIM2 Capture" + default n + depends on STM32H5_TIM2 + ---help--- + Reserve timer 2 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM3_CAP + bool "TIM3 Capture" + default n + depends on STM32H5_TIM3 + ---help--- + Reserve timer 3 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM4_CAP + bool "TIM4 Capture" + default n + depends on STM32H5_TIM4 + ---help--- + Reserve timer 4 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM5_CAP + bool "TIM5 Capture" + default n + depends on STM32H5_TIM5 + ---help--- + Reserve timer 5 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM8_CAP + bool "TIM8 Capture" + default n + depends on STM32H5_TIM8 + ---help--- + Reserve timer 8 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM12_CAP + bool "TIM12 Capture" + default n + depends on STM32H5_TIM12 + ---help--- + Reserve timer 12 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM13_CAP + bool "TIM13 Capture" + default n + depends on STM32H5_TIM13 + ---help--- + Reserve timer 13 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM14_CAP + bool "TIM14 Capture" + default n + depends on STM32H5_TIM14 + ---help--- + Reserve timer 14 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM15_CAP + bool "TIM15 Capture" + default n + depends on STM32H5_TIM15 + ---help--- + Reserve timer 15 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM16_CAP + bool "TIM16 Capture" + default n + depends on STM32H5_TIM16 + ---help--- + Reserve timer 16 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +config STM32H5_TIM17_CAP + bool "TIM14 Capture" + default n + depends on STM32H5_TIM17 + ---help--- + Reserve timer 17 for use by Capture + + Timer devices may be used for different purposes. One special purpose is + to capture input. + +menu "STM32 TIMx Outputs Configuration" + +config STM32H5_TIM1_CH1POL + int "TIM1 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH1OUT + ---help--- + TIM1 Channel 1 output polarity + +config STM32H5_TIM1_CH1IDLE + int "TIM1 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH1OUT + ---help--- + TIM1 Channel 1 output IDLE + +config STM32H5_TIM1_CH1NPOL + int "TIM1 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH1NOUT + ---help--- + TIM1 Channel 1 Complementary Output polarity + +config STM32H5_TIM1_CH1NIDLE + int "TIM1 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH1NOUT + ---help--- + TIM1 Channel 1 Complementary Output IDLE + +config STM32H5_TIM1_CH2POL + int "TIM1 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH2OUT + ---help--- + TIM1 Channel 2 output polarity + +config STM32H5_TIM1_CH2IDLE + int "TIM1 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH2OUT + ---help--- + TIM1 Channel 2 output IDLE + +config STM32H5_TIM1_CH2NPOL + int "TIM1 Channel 2 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH2NOUT + ---help--- + TIM1 Channel 2 Complementary Output polarity + +config STM32H5_TIM1_CH2NIDLE + int "TIM1 Channel 2 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH2NOUT + ---help--- + TIM1 Channel 2 Complementary Output IDLE + +config STM32H5_TIM1_CH3POL + int "TIM1 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH3OUT + ---help--- + TIM1 Channel 3 output polarity + +config STM32H5_TIM1_CH3IDLE + int "TIM1 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH3OUT + ---help--- + TIM1 Channel 3 output IDLE + +config STM32H5_TIM1_CH3NPOL + int "TIM1 Channel 3 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH3NOUT + ---help--- + TIM1 Channel 3 Complementary Output polarity + +config STM32H5_TIM1_CH3NIDLE + int "TIM1 Channel 3 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH3NOUT + ---help--- + TIM1 Channel 3 Complementary Output IDLE + +config STM32H5_TIM1_CH4POL + int "TIM1 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH4OUT + ---help--- + TIM1 Channel 4 output polarity + +config STM32H5_TIM1_CH4IDLE + int "TIM1 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH4OUT + ---help--- + TIM1 Channel 4 output IDLE + +config STM32H5_TIM1_CH5POL + int "TIM1 Channel 5 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH5OUT + ---help--- + TIM1 Channel 5 output polarity + +config STM32H5_TIM1_CH5IDLE + int "TIM1 Channel 5 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH5OUT + ---help--- + TIM1 Channel 5 output IDLE + +config STM32H5_TIM1_CH6POL + int "TIM1 Channel 6 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH6OUT + ---help--- + TIM1 Channel 6 output polarity + +config STM32H5_TIM1_CH6IDLE + int "TIM1 Channel 6 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM1_CH6OUT + ---help--- + TIM1 Channel 6 output IDLE + +config STM32H5_TIM2_CH1POL + int "TIM2 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH1OUT + ---help--- + TIM2 Channel 1 output polarity + +config STM32H5_TIM2_CH1IDLE + int "TIM2 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH1OUT + ---help--- + TIM2 Channel 1 output IDLE + +config STM32H5_TIM2_CH2POL + int "TIM2 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH2OUT + ---help--- + TIM2 Channel 2 output polarity + +config STM32H5_TIM2_CH2IDLE + int "TIM2 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH2OUT + ---help--- + TIM2 Channel 2 output IDLE + +config STM32H5_TIM2_CH3POL + int "TIM2 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH3OUT + ---help--- + TIM2 Channel 3 output polarity + +config STM32H5_TIM2_CH3IDLE + int "TIM2 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH3OUT + ---help--- + TIM2 Channel 3 output IDLE + +config STM32H5_TIM2_CH4POL + int "TIM2 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH4OUT + ---help--- + TIM2 Channel 4 output polarity + +config STM32H5_TIM2_CH4IDLE + int "TIM2 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM2_CH4OUT + ---help--- + TIM2 Channel 4 output IDLE + +config STM32H5_TIM3_CH1POL + int "TIM3 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH1OUT + ---help--- + TIM3 Channel 1 output polarity + +config STM32H5_TIM3_CH1IDLE + int "TIM3 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH1OUT + ---help--- + TIM3 Channel 1 output IDLE + +config STM32H5_TIM3_CH2POL + int "TIM3 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH2OUT + ---help--- + TIM3 Channel 2 output polarity + +config STM32H5_TIM3_CH2IDLE + int "TIM3 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH2OUT + ---help--- + TIM3 Channel 2 output IDLE + +config STM32H5_TIM3_CH3POL + int "TIM3 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH3OUT + ---help--- + TIM3 Channel 3 output polarity + +config STM32H5_TIM3_CH3IDLE + int "TIM3 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH3OUT + ---help--- + TIM3 Channel 3 output IDLE + +config STM32H5_TIM3_CH4POL + int "TIM3 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH4OUT + ---help--- + TIM3 Channel 4 output polarity + +config STM32H5_TIM3_CH4IDLE + int "TIM3 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM3_CH4OUT + ---help--- + TIM3 Channel 4 output IDLE + +config STM32H5_TIM4_CH1POL + int "TIM4 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH1OUT + ---help--- + TIM4 Channel 1 output polarity + +config STM32H5_TIM4_CH1IDLE + int "TIM4 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH1OUT + ---help--- + TIM4 Channel 1 output IDLE + +config STM32H5_TIM4_CH2POL + int "TIM4 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH2OUT + ---help--- + TIM4 Channel 2 output polarity + +config STM32H5_TIM4_CH2IDLE + int "TIM4 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH2OUT + ---help--- + TIM4 Channel 2 output IDLE + +config STM32H5_TIM4_CH3POL + int "TIM4 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH3OUT + ---help--- + TIM4 Channel 3 output polarity + +config STM32H5_TIM4_CH3IDLE + int "TIM4 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH3OUT + ---help--- + TIM4 Channel 3 output IDLE + +config STM32H5_TIM4_CH4POL + int "TIM4 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH4OUT + ---help--- + TIM4 Channel 4 output polarity + +config STM32H5_TIM4_CH4IDLE + int "TIM4 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM4_CH4OUT + ---help--- + TIM4 Channel 4 output IDLE + +config STM32H5_TIM5_CH1POL + int "TIM5 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH1OUT + ---help--- + TIM5 Channel 1 output polarity + +config STM32H5_TIM5_CH1IDLE + int "TIM5 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH1OUT + ---help--- + TIM5 Channel 1 output IDLE + +config STM32H5_TIM5_CH2POL + int "TIM5 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH2OUT + ---help--- + TIM5 Channel 2 output polarity + +config STM32H5_TIM5_CH2IDLE + int "TIM5 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH2OUT + ---help--- + TIM5 Channel 2 output IDLE + +config STM32H5_TIM5_CH3POL + int "TIM5 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH3OUT + ---help--- + TIM5 Channel 3 output polarity + +config STM32H5_TIM5_CH3IDLE + int "TIM5 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH3OUT + ---help--- + TIM5 Channel 3 output IDLE + +config STM32H5_TIM5_CH4POL + int "TIM5 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH4OUT + ---help--- + TIM5 Channel 4 output polarity + +config STM32H5_TIM5_CH4IDLE + int "TIM5 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM5_CH4OUT + ---help--- + TIM5 Channel 4 output IDLE + +config STM32H5_TIM8_CH1POL + int "TIM8 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH1OUT + ---help--- + TIM8 Channel 1 output polarity + +config STM32H5_TIM8_CH1IDLE + int "TIM8 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH1OUT + ---help--- + TIM8 Channel 1 output IDLE + +config STM32H5_TIM8_CH1NPOL + int "TIM8 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH1NOUT + ---help--- + TIM8 Channel 1 Complementary Output polarity + +config STM32H5_TIM8_CH1NIDLE + int "TIM8 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH1NOUT + ---help--- + TIM8 Channel 1 Complementary Output IDLE + +config STM32H5_TIM8_CH2POL + int "TIM8 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH2OUT + ---help--- + TIM8 Channel 2 output polarity + +config STM32H5_TIM8_CH2IDLE + int "TIM8 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH2OUT + ---help--- + TIM8 Channel 2 output IDLE + +config STM32H5_TIM8_CH2NPOL + int "TIM8 Channel 2 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH2NOUT + ---help--- + TIM8 Channel 2 Complementary Output polarity + +config STM32H5_TIM8_CH2NIDLE + int "TIM8 Channel 2 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH2NOUT + ---help--- + TIM8 Channel 2 Complementary Output IDLE + +config STM32H5_TIM8_CH3POL + int "TIM8 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH3OUT + ---help--- + TIM8 Channel 3 output polarity + +config STM32H5_TIM8_CH3IDLE + int "TIM8 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH3OUT + ---help--- + TIM8 Channel 3 output IDLE + +config STM32H5_TIM8_CH3NPOL + int "TIM8 Channel 3 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH3NOUT + ---help--- + TIM8 Channel 3 Complementary Output polarity + +config STM32H5_TIM8_CH3NIDLE + int "TIM8 Channel 3 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH3NOUT + ---help--- + TIM8 Channel 3 Complementary Output IDLE + +config STM32H5_TIM8_CH4POL + int "TIM8 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH4OUT + ---help--- + TIM8 Channel 4 output polarity + +config STM32H5_TIM8_CH4IDLE + int "TIM8 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH4OUT + ---help--- + TIM8 Channel 4 output IDLE + +config STM32H5_TIM8_CH5POL + int "TIM8 Channel 5 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH5OUT + ---help--- + TIM8 Channel 5 output polarity + +config STM32H5_TIM8_CH5IDLE + int "TIM8 Channel 5 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH5OUT + ---help--- + TIM8 Channel 5 output IDLE + +config STM32H5_TIM8_CH6POL + int "TIM8 Channel 6 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH6OUT + ---help--- + TIM8 Channel 6 output polarity + +config STM32H5_TIM8_CH6IDLE + int "TIM8 Channel 6 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM8_CH6OUT + ---help--- + TIM8 Channel 6 output IDLE + +config STM32H5_TIM12_CH1POL + int "TIM12 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM12_CH1OUT + ---help--- + TIM12 Channel 1 output polarity + +config STM32H5_TIM12_CH1IDLE + int "TIM12 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM12_CH1OUT + ---help--- + TIM12 Channel 1 output IDLE + +config STM32H5_TIM12_CH2POL + int "TIM12 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM12_CH2OUT + ---help--- + TIM12 Channel 2 output polarity + +config STM32H5_TIM12_CH2IDLE + int "TIM12 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM12_CH2OUT + ---help--- + TIM12 Channel 2 output IDLE + +config STM32H5_TIM13_CH1POL + int "TIM13 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM13_CH1OUT + ---help--- + TIM13 Channel 1 output polarity + +config STM32H5_TIM13_CH1IDLE + int "TIM13 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM13_CH1OUT + ---help--- + TIM13 Channel 1 output IDLE + +config STM32H5_TIM14_CH1POL + int "TIM14 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM14_CH1OUT + ---help--- + TIM14 Channel 1 output polarity + +config STM32H5_TIM14_CH1IDLE + int "TIM14 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM14_CH1OUT + ---help--- + TIM14 Channel 1 output IDLE + +config STM32H5_TIM15_CH1POL + int "TIM15 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH1OUT + ---help--- + TIM15 Channel 1 output polarity + +config STM32H5_TIM15_CH1IDLE + int "TIM15 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH1OUT + ---help--- + TIM15 Channel 1 output IDLE + +config STM32H5_TIM15_CH1NPOL + int "TIM15 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH1NOUT + ---help--- + TIM15 Channel 1 Complementary Output polarity + +config STM32H5_TIM15_CH1NIDLE + int "TIM15 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH1NOUT + ---help--- + TIM15 Channel 1 Complementary Output IDLE + +config STM32H5_TIM15_CH2POL + int "TIM15 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH2OUT + ---help--- + TIM15 Channel 2 output polarity + +config STM32H5_TIM15_CH2IDLE + int "TIM15 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH2OUT + ---help--- + TIM15 Channel 2 output IDLE + +config STM32H5_TIM15_CH2NPOL + int "TIM15 Channel 2 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH2NOUT + ---help--- + TIM15 Channel 2 Complementary Output polarity + +config STM32H5_TIM15_CH2NIDLE + int "TIM15 Channel 2 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM15_CH2NOUT + ---help--- + TIM15 Channel 2 Complementary Output IDLE + +config STM32H5_TIM16_CH1POL + int "TIM16 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM16_CH1OUT + ---help--- + TIM16 Channel 1 output polarity + +config STM32H5_TIM16_CH1IDLE + int "TIM16 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM16_CH1OUT + ---help--- + TIM16 Channel 1 output IDLE + +config STM32H5_TIM17_CH1POL + int "TIM17 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32H5_TIM17_CH1OUT + ---help--- + TIM17 Channel 1 output polarity + +config STM32H5_TIM17_CH1IDLE + int "TIM17 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32H5_TIM17_CH1OUT + ---help--- + TIM17 Channel 1 output IDLE + +endmenu #STM32 TIMx Outputs Configuration + +endmenu # Timer Configuration + config STM32H5_SERIALDRIVER bool diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs index 598d16cf5e..96f055b5f9 100644 --- a/arch/arm/src/stm32h5/Make.defs +++ b/arch/arm/src/stm32h5/Make.defs @@ -43,7 +43,7 @@ CHIP_CSRCS += stm32_idle.c endif ifeq ($(CONFIG_TIMER),y) -CHIP_CSRCS += stm32h5_tim_lowerhalf.c +CHIP_CSRCS += stm32_tim_lowerhalf.c endif ifeq ($(CONFIG_STM32H5_I2C),y) @@ -66,6 +66,10 @@ ifeq ($(CONFIG_STM32H5_QSPI1),y) CHIP_CSRCS += stm32_qspi.c endif +ifeq ($(CONFIG_STM32H5_TIM),y) +CHIP_CSRCS += stm32_tim.c +endif + # Required chip type specific files ifeq ($(CONFIG_STM32H5_STM32H5XXXX),y) diff --git a/arch/arm/src/stm32h5/stm32_tim.c b/arch/arm/src/stm32h5/stm32_tim.c new file mode 100644 index 0000000000..b36dcae502 --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_tim.c @@ -0,0 +1,1553 @@ +/**************************************************************************** + * arch/arm/src/stm32h5/stm32_tim.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_tim.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Timer devices may be used for different purposes. Such special purposes + * include: + * + * - To generate modulated outputs for such things as motor control. If + * CONFIG_STM32H5_TIMn is defined then the CONFIG_STM32H5_TIMn_PWM may + * also be defined to indicate that the timer is intended to be used for + * pulsed output modulation. + * + * - To control periodic ADC input sampling. If CONFIG_STM32H5_TIMn is + * defined then CONFIG_STM32H5_TIMn_ADC may also be defined to indicate + * that timer "n" is intended to be used for that purpose. + * + * - To control periodic DAC outputs. If CONFIG_STM32H5_TIMn is defined + * then CONFIG_STM32H5_TIMn_DAC may also be defined to indicate that + * timer "n" is intended to be used for that purpose. + * + * - To use a Quadrature Encoder. If CONFIG_STM32H5_TIMn is defined then + * CONFIG_STM32H5_TIMn_QE may also be defined to indicate that timer "n" + * is intended to be used for that purpose. + * + * In any of these cases, the timer will not be used by this timer module. + */ + +#if defined(CONFIG_STM32H5_TIM1_PWM) || defined (CONFIG_STM32H5_TIM1_ADC) || \ + defined(CONFIG_STM32H5_TIM1_DAC) || defined(CONFIG_STM32H5_TIM1_QE) +# undef CONFIG_STM32H5_TIM1 +#endif + +#if defined(CONFIG_STM32H5_TIM2_PWM) || defined (CONFIG_STM32H5_TIM2_ADC) || \ + defined(CONFIG_STM32H5_TIM2_DAC) || defined(CONFIG_STM32H5_TIM2_QE) +# undef CONFIG_STM32H5_TIM2 +#endif + +#if defined(CONFIG_STM32H5_TIM3_PWM) || defined (CONFIG_STM32H5_TIM3_ADC) || \ + defined(CONFIG_STM32H5_TIM3_DAC) || defined(CONFIG_STM32H5_TIM3_QE) +# undef CONFIG_STM32H5_TIM3 +#endif + +#if defined(CONFIG_STM32H5_TIM4_PWM) || defined (CONFIG_STM32H5_TIM4_ADC) || \ + defined(CONFIG_STM32H5_TIM4_DAC) || defined(CONFIG_STM32H5_TIM4_QE) +# undef CONFIG_STM32H5_TIM4 +#endif + +#if defined(CONFIG_STM32H5_TIM5_PWM) || defined (CONFIG_STM32H5_TIM5_ADC) || \ + defined(CONFIG_STM32H5_TIM5_DAC) || defined(CONFIG_STM32H5_TIM5_QE) +# undef CONFIG_STM32H5_TIM5 +#endif + +#if defined(CONFIG_STM32H5_TIM6_PWM) || defined (CONFIG_STM32H5_TIM6_ADC) || \ + defined(CONFIG_STM32H5_TIM6_DAC) || defined(CONFIG_STM32H5_TIM6_QE) +# undef CONFIG_STM32H5_TIM6 +#endif + +#if defined(CONFIG_STM32H5_TIM7_PWM) || defined (CONFIG_STM32H5_TIM7_ADC) || \ + defined(CONFIG_STM32H5_TIM7_DAC) || defined(CONFIG_STM32H5_TIM7_QE) +# undef CONFIG_STM32H5_TIM7 +#endif + +#if defined(CONFIG_STM32H5_TIM8_PWM) || defined (CONFIG_STM32H5_TIM8_ADC) || \ + defined(CONFIG_STM32H5_TIM8_DAC) || defined(CONFIG_STM32H5_TIM8_QE) +# undef CONFIG_STM32H5_TIM8 +#endif + +#if defined(CONFIG_STM32H5_TIM12_PWM) || defined (CONFIG_STM32H5_TIM12_ADC) || \ + defined(CONFIG_STM32H5_TIM12_DAC) || defined(CONFIG_STM32H5_TIM12_QE) +# undef CONFIG_STM32H5_TIM12 +#endif + +#if defined(CONFIG_STM32H5_TIM13_PWM) || defined (CONFIG_STM32H5_TIM13_ADC) || \ + defined(CONFIG_STM32H5_TIM13_DAC) || defined(CONFIG_STM32H5_TIM13_QE) +# undef CONFIG_STM32H5_TIM13 +#endif + +#if defined(CONFIG_STM32H5_TIM14_PWM) || defined (CONFIG_STM32H5_TIM14_ADC) || \ + defined(CONFIG_STM32H5_TIM14_DAC) || defined(CONFIG_STM32H5_TIM14_QE) +# undef CONFIG_STM32H5_TIM14 +#endif + +#if defined(CONFIG_STM32H5_TIM15_PWM) || defined (CONFIG_STM32H5_TIM15_ADC) || \ + defined(CONFIG_STM32H5_TIM15_DAC) || defined(CONFIG_STM32H5_TIM15_QE) +# undef CONFIG_STM32H5_TIM15 +#endif + +#if defined(CONFIG_STM32H5_TIM16_PWM) || defined (CONFIG_STM32H5_TIM16_ADC) || \ + defined(CONFIG_STM32H5_TIM16_DAC) || defined(CONFIG_STM32H5_TIM16_QE) +# undef CONFIG_STM32H5_TIM16 +#endif + +#if defined(CONFIG_STM32H5_TIM17_PWM) || defined (CONFIG_STM32H5_TIM17_ADC) || \ + defined(CONFIG_STM32H5_TIM17_DAC) || defined(CONFIG_STM32H5_TIM17_QE) +# undef CONFIG_STM32H5_TIM17 +#endif + +#if defined(CONFIG_STM32H5_TIM1) +# if defined(GPIO_TIM1_CH1OUT) ||defined(GPIO_TIM1_CH2OUT)||\ + defined(GPIO_TIM1_CH3OUT) ||defined(GPIO_TIM1_CH4OUT)||\ + defined(GPIO_TIM1_CH5OUT) ||defined(GPIO_TIM1_CH6OUT) +# define HAVE_TIM1_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM2) +# if defined(GPIO_TIM2_CH1OUT) ||defined(GPIO_TIM2_CH2OUT)||\ + defined(GPIO_TIM2_CH3OUT) ||defined(GPIO_TIM2_CH4OUT) +# define HAVE_TIM2_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM3) +# if defined(GPIO_TIM3_CH1OUT) ||defined(GPIO_TIM3_CH2OUT)||\ + defined(GPIO_TIM3_CH3OUT) ||defined(GPIO_TIM3_CH4OUT) +# define HAVE_TIM3_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM4) +# if defined(GPIO_TIM4_CH1OUT) ||defined(GPIO_TIM4_CH2OUT)||\ + defined(GPIO_TIM4_CH3OUT) ||defined(GPIO_TIM4_CH4OUT) +# define HAVE_TIM4_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM5) +# if defined(GPIO_TIM5_CH1OUT) ||defined(GPIO_TIM5_CH2OUT)||\ + defined(GPIO_TIM5_CH3OUT) ||defined(GPIO_TIM5_CH4OUT) +# define HAVE_TIM5_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM8) +# if defined(GPIO_TIM8_CH1OUT) ||defined(GPIO_TIM8_CH2OUT)||\ + defined(GPIO_TIM8_CH3OUT) ||defined(GPIO_TIM8_CH4OUT)||\ + defined(GPIO_TIM8_CH5OUT) ||defined(GPIO_TIM8_CH6OUT) +# define HAVE_TIM8_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM12) +# if defined(GPIO_TIM12_CH1OUT) ||defined(GPIO_TIM12_CH2OUT) +# define HAVE_TIM12_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM13) +# if defined(GPIO_TIM13_CH1OUT) +# define HAVE_TIM13_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM14) +# if defined(GPIO_TIM14_CH1OUT) +# define HAVE_TIM14_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM15) +# if defined(GPIO_TIM15_CH1OUT) ||defined(GPIO_TIM15_CH2OUT) +# define HAVE_TIM15_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM16) +# if defined(GPIO_TIM16_CH1OUT) +# define HAVE_TIM16_GPIOCONFIG 1 +# endif +#endif + +#if defined(CONFIG_STM32H5_TIM17) +# if defined(GPIO_TIM17_CH1OUT) +# define HAVE_TIM17_GPIOCONFIG 1 +# endif +#endif + +/* This module then only compiles if there are enabled timers that are not + * intended for some other purpose. + */ + +#if defined(CONFIG_STM32H5_TIM1) || defined(CONFIG_STM32H5_TIM2) || \ + defined(CONFIG_STM32H5_TIM3) || defined(CONFIG_STM32H5_TIM4) || \ + defined(CONFIG_STM32H5_TIM5) || defined(CONFIG_STM32H5_TIM6) || \ + defined(CONFIG_STM32H5_TIM7) || defined(CONFIG_STM32H5_TIM8) || \ + defined(CONFIG_STM32H5_TIM12) || defined(CONFIG_STM32H5_TIM13) || \ + defined(CONFIG_STM32H5_TIM14) || defined(CONFIG_STM32H5_TIM15) || \ + defined(CONFIG_STM32H5_TIM16) || defined(CONFIG_STM32H5_TIM17) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* TIM Device Structure */ + +struct stm32_tim_priv_s +{ + const struct stm32_tim_ops_s *ops; + stm32_tim_mode_t mode; + uint32_t base; /* TIMn base address */ +}; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ + +/* Timer methods */ + +static void stm32_tim_enable(struct stm32_tim_dev_s *dev); +static void stm32_tim_disable(struct stm32_tim_dev_s *dev); +static int stm32_tim_setmode(struct stm32_tim_dev_s *dev, + stm32_tim_mode_t mode); +static int stm32_tim_setclock(struct stm32_tim_dev_s *dev, + uint32_t freq); +static void stm32_tim_setperiod(struct stm32_tim_dev_s *dev, + uint32_t period); +static uint32_t stm32_tim_getcounter(struct stm32_tim_dev_s *dev); +static void stm32_tim_setcounter(struct stm32_tim_dev_s *dev, + uint32_t count); +static int stm32_tim_getwidth(struct stm32_tim_dev_s *dev); +static int stm32_tim_setchannel(struct stm32_tim_dev_s *dev, + uint8_t channel, + stm32_tim_channel_t mode); +static int stm32_tim_setcompare(struct stm32_tim_dev_s *dev, + uint8_t channel, uint32_t compare); +static int stm32_tim_getcapture(struct stm32_tim_dev_s *dev, + uint8_t channel); +static int stm32_tim_setisr(struct stm32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source); +static void stm32_tim_enableint(struct stm32_tim_dev_s *dev, + int source); +static void stm32_tim_disableint(struct stm32_tim_dev_s *dev, + int source); +static void stm32_tim_ackint(struct stm32_tim_dev_s *dev, + int source); +static int stm32_tim_checkint(struct stm32_tim_dev_s *dev, + int source); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct stm32_tim_ops_s stm32_tim_ops = +{ + .enable = &stm32_tim_enable, + .disable = &stm32_tim_disable, + .setmode = &stm32_tim_setmode, + .setclock = &stm32_tim_setclock, + .setperiod = &stm32_tim_setperiod, + .getcounter = &stm32_tim_getcounter, + .setcounter = &stm32_tim_setcounter, + .getwidth = &stm32_tim_getwidth, + .setchannel = &stm32_tim_setchannel, + .setcompare = &stm32_tim_setcompare, + .getcapture = &stm32_tim_getcapture, + .setisr = &stm32_tim_setisr, + .enableint = &stm32_tim_enableint, + .disableint = &stm32_tim_disableint, + .ackint = &stm32_tim_ackint, + .checkint = &stm32_tim_checkint, +}; + +#ifdef CONFIG_STM32H5_TIM1 +struct stm32_tim_priv_s stm32_tim1_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM1_BASE, +}; +#endif +#ifdef CONFIG_STM32H5_TIM2 +struct stm32_tim_priv_s stm32_tim2_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM2_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM3 +struct stm32_tim_priv_s stm32_tim3_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM3_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM4 +struct stm32_tim_priv_s stm32_tim4_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM4_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM5 +struct stm32_tim_priv_s stm32_tim5_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM5_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM6 +struct stm32_tim_priv_s stm32_tim6_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM6_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM7 +struct stm32_tim_priv_s stm32_tim7_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM7_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM8 +struct stm32_tim_priv_s stm32_tim8_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM8_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM12 +struct stm32_tim_priv_s stm32_tim12_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM12_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM13 +struct stm32_tim_priv_s stm32_tim13_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM13_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM14 +struct stm32_tim_priv_s stm32_tim14_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM14_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM15 +struct stm32_tim_priv_s stm32_tim15_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM15_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM16 +struct stm32_tim_priv_s stm32_tim16_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM16_BASE, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM17 +struct stm32_tim_priv_s stm32_tim17_priv = +{ + .ops = &stm32_tim_ops, + .mode = STM32_TIM_MODE_UNUSED, + .base = STM32_TIM17_BASE, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Get a 16-bit register value by offset */ + +static inline uint16_t stm32_getreg16(struct stm32_tim_dev_s *dev, + uint8_t offset) +{ + return getreg16(((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/* Put a 16-bit register value by offset */ + +static inline void stm32_putreg16(struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t value) +{ + putreg16(value, ((struct stm32_tim_priv_s *)dev)->base + offset); +} + +/* Modify a 16-bit register value by offset */ + +static inline void stm32_modifyreg16(struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t clearbits, + uint16_t setbits) +{ + modifyreg16(((struct stm32_tim_priv_s *)dev)->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-5. + */ + +static inline uint32_t stm32_getreg32(struct stm32_tim_dev_s *dev, + uint8_t offset) +{ + return getreg32(((struct stm32_tim_priv_s *)dev)->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-5. + */ + +static inline void stm32_putreg32(struct stm32_tim_dev_s *dev, + uint8_t offset, uint32_t value) +{ + putreg32(value, ((struct stm32_tim_priv_s *)dev)->base + offset); +} + +static void stm32_tim_reload_counter(struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32_GTIM_EGR_OFFSET); + val |= GTIM_EGR_UG; + stm32_putreg16(dev, STM32_GTIM_EGR_OFFSET, val); +} + +static void stm32_tim_enable(struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32_GTIM_CR1_OFFSET); + val |= GTIM_CR1_CEN; + stm32_tim_reload_counter(dev); + stm32_putreg16(dev, STM32_GTIM_CR1_OFFSET, val); +} + +static void stm32_tim_disable(struct stm32_tim_dev_s *dev) +{ + uint16_t val = stm32_getreg16(dev, STM32_GTIM_CR1_OFFSET); + val &= ~GTIM_CR1_CEN; + stm32_putreg16(dev, STM32_GTIM_CR1_OFFSET, val); +} + +/**************************************************************************** + * Name: stm32_tim_getwidth + ****************************************************************************/ + +static int stm32_tim_getwidth(struct stm32_tim_dev_s *dev) +{ + /* Only TIM2 and TIM5 timers may be 32-bits in width */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#if defined(CONFIG_STM32H5_TIM2) + case STM32_TIM2_BASE: + return 32; +#endif + +#if defined(CONFIG_STM32H5_TIM5) + case STM32_TIM5_BASE: + return 32; +#endif + + /* All others are 16-bit times */ + + default: + return 16; + } +} + +/**************************************************************************** + * Name: stm32_tim_getcounter + ****************************************************************************/ + +static uint32_t stm32_tim_getcounter(struct stm32_tim_dev_s *dev) +{ + DEBUGASSERT(dev != NULL); + return stm32_tim_getwidth(dev) > 16 ? + stm32_getreg32(dev, STM32_BTIM_CNT_OFFSET) : + (uint32_t)stm32_getreg16(dev, STM32_BTIM_CNT_OFFSET); +} + +/**************************************************************************** + * Name: stm32_tim_setcounter + ****************************************************************************/ + +static void stm32_tim_setcounter(struct stm32_tim_dev_s *dev, + uint32_t count) +{ + DEBUGASSERT(dev != NULL); + + if (stm32_tim_getwidth(dev) > 16) + { + stm32_putreg32(dev, STM32_BTIM_CNT_OFFSET, count); + } + else + { + stm32_putreg16(dev, STM32_BTIM_CNT_OFFSET, (uint16_t)count); + } +} + +/* Reset timer into system default state, but do not affect output/input + * pins + */ + +static void stm32_tim_reset(struct stm32_tim_dev_s *dev) +{ + ((struct stm32_tim_priv_s *)dev)->mode = STM32_TIM_MODE_DISABLED; + stm32_tim_disable(dev); +} + +#if defined(HAVE_TIM1_GPIOCONFIG)||defined(HAVE_TIM2_GPIOCONFIG)||\ + defined(HAVE_TIM3_GPIOCONFIG)||defined(HAVE_TIM4_GPIOCONFIG)||\ + defined(HAVE_TIM5_GPIOCONFIG)||defined(HAVE_TIM6_GPIOCONFIG)||\ + defined(HAVE_TIM7_GPIOCONFIG)||defined(HAVE_TIM8_GPIOCONFIG)||\ + defined(HAVE_TIM12_GPIOCONFIG)||defined(HAVE_TIM13_GPIOCONFIG)||\ + defined(HAVE_TIM14_GPIOCONFIG)||defined(HAVE_TIM15_GPIOCONFIG)||\ + defined(HAVE_TIM16_GPIOCONFIG)||defined(HAVE_TIM17_GPIOCONFIG) +static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode) +{ + /* TODO: Add support for input capture and bipolar dual outputs for TIM8 */ + + if (mode & STM32_TIM_CH_MODE_MASK) + { + stm32_configgpio(cfg); + } + else + { + stm32_unconfiggpio(cfg); + } +} +#endif + +/**************************************************************************** + * Basic Functions + ****************************************************************************/ + +static int stm32_tim_setclock(struct stm32_tim_dev_s *dev, uint32_t freq) +{ + uint32_t freqin; + int prescaler; + + DEBUGASSERT(dev != NULL); + + /* Disable Timer? */ + + if (freq == 0) + { + stm32_tim_disable(dev); + 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 (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32H5_TIM1 + case STM32_TIM1_BASE: + freqin = STM32_APB2_TIM1_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM2 + case STM32_TIM2_BASE: + freqin = STM32_APB1_TIM2_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM3 + case STM32_TIM3_BASE: + freqin = STM32_APB1_TIM3_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM4 + case STM32_TIM4_BASE: + freqin = STM32_APB1_TIM4_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM5 + case STM32_TIM5_BASE: + freqin = STM32_APB1_TIM5_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM6 + case STM32_TIM6_BASE: + freqin = STM32_APB1_TIM6_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM7 + case STM32_TIM7_BASE: + freqin = STM32_APB1_TIM7_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM8 + case STM32_TIM8_BASE: + freqin = STM32_APB2_TIM8_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM12 + case STM32_TIM12_BASE: + freqin = STM32_APB1_TIM12_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM13 + case STM32_TIM13_BASE: + freqin = STM32_APB1_TIM13_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM14 + case STM32_TIM14_BASE: + freqin = STM32_APB1_TIM14_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM15 + case STM32_TIM15_BASE: + freqin = STM32_APB2_TIM15_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM16 + case STM32_TIM16_BASE: + freqin = STM32_APB2_TIM16_CLKIN; + break; +#endif +#ifdef CONFIG_STM32H5_TIM17 + case STM32_TIM17_BASE: + freqin = STM32_APB2_TIM17_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 that will not to + * cause underflow. + */ + + if (prescaler > 0) + { + prescaler--; + } + + /* Check for overflow as well. */ + + if (prescaler > 0xffff) + { + prescaler = 0xffff; + } + + stm32_putreg16(dev, STM32_GTIM_PSC_OFFSET, prescaler); + stm32_tim_enable(dev); + + return prescaler; +} + +static void stm32_tim_setperiod(struct stm32_tim_dev_s *dev, + uint32_t period) +{ + DEBUGASSERT(dev != NULL); + stm32_putreg32(dev, STM32_GTIM_ARR_OFFSET, period); +} + +static int stm32_tim_setisr(struct stm32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source) +{ + int vectorno; + + DEBUGASSERT(dev != NULL); + DEBUGASSERT(source == 0); + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32H5_TIM1 + case STM32_TIM1_BASE: + vectorno = STM32_IRQ_TIM1_UP; + break; +#endif +#ifdef CONFIG_STM32H5_TIM2 + case STM32_TIM2_BASE: + vectorno = STM32_IRQ_TIM2; + break; +#endif +#ifdef CONFIG_STM32H5_TIM3 + case STM32_TIM3_BASE: + vectorno = STM32_IRQ_TIM3; + break; +#endif +#ifdef CONFIG_STM32H5_TIM4 + case STM32_TIM4_BASE: + vectorno = STM32_IRQ_TIM4; + break; +#endif +#ifdef CONFIG_STM32H5_TIM5 + case STM32_TIM5_BASE: + vectorno = STM32_IRQ_TIM5; + break; +#endif +#ifdef CONFIG_STM32H5_TIM6 + case STM32_TIM6_BASE: + vectorno = STM32_IRQ_TIM6; + break; +#endif +#ifdef CONFIG_STM32H5_TIM7 + case STM32_TIM7_BASE: + vectorno = STM32_IRQ_TIM7; + break; +#endif +#ifdef CONFIG_STM32H5_TIM8 + case STM32_TIM8_BASE: + vectorno = STM32_IRQ_TIM8_UP; + break; +#endif +#ifdef CONFIG_STM32H5_TIM12 + case STM32_TIM12_BASE: + vectorno = STM32_IRQ_TIM12; + break; +#endif +#ifdef CONFIG_STM32H5_TIM13 + case STM32_TIM13_BASE: + vectorno = STM32_IRQ_TIM13; + break; +#endif +#ifdef CONFIG_STM32H5_TIM14 + case STM32_TIM14_BASE: + vectorno = STM32_IRQ_TIM14; + break; +#endif +#ifdef CONFIG_STM32H5_TIM15 + case STM32_TIM15_BASE: + vectorno = STM32_IRQ_TIM15; + break; +#endif +#ifdef CONFIG_STM32H5_TIM16 + case STM32_TIM16_BASE: + vectorno = STM32_IRQ_TIM16; + break; +#endif +#ifdef CONFIG_STM32H5_TIM17 + case STM32_TIM17_BASE: + vectorno = STM32_IRQ_TIM17; + break; +#endif + + default: + return -EINVAL; + } + + /* Disable interrupt when callback is removed */ + + if (!handler) + { + up_disable_irq(vectorno); + irq_detach(vectorno); + return OK; + } + + /* Otherwise set callback and enable interrupt */ + + irq_attach(vectorno, handler, arg); + up_enable_irq(vectorno); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT); +#endif + + return OK; +} + +static void stm32_tim_enableint(struct stm32_tim_dev_s *dev, int source) +{ + DEBUGASSERT(dev != NULL); + stm32_modifyreg16(dev, STM32_GTIM_DIER_OFFSET, 0, source); +} + +static void stm32_tim_disableint(struct stm32_tim_dev_s *dev, int source) +{ + DEBUGASSERT(dev != NULL); + stm32_modifyreg16(dev, STM32_GTIM_DIER_OFFSET, source, 0); +} + +static int stm32_tim_checkint(struct stm32_tim_dev_s *dev, int source) +{ + uint16_t regval = stm32_getreg16(dev, STM32_BTIM_SR_OFFSET); + return (regval & source) ? 1 : 0; +} + +static void stm32_tim_ackint(struct stm32_tim_dev_s *dev, int source) +{ + stm32_putreg16(dev, STM32_GTIM_SR_OFFSET, ~source); +} + +/**************************************************************************** + * General Functions + ****************************************************************************/ + +static int stm32_tim_setmode(struct stm32_tim_dev_s *dev, + stm32_tim_mode_t mode) +{ + uint16_t val = GTIM_CR1_CEN | GTIM_CR1_ARPE; + + DEBUGASSERT(dev != NULL); + + /* This function is not supported on basic timers. To enable or + * disable it, simply set its clock to valid frequency or zero. + */ + + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE || \ + ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE) + { + return -EINVAL; + } + + /* Decode operational modes */ + + switch (mode & STM32_TIM_MODE_MASK) + { + case STM32_TIM_MODE_DISABLED: + val = 0; + break; + + case STM32_TIM_MODE_DOWN: + val |= GTIM_CR1_DIR; + + case STM32_TIM_MODE_UP: + break; + + case STM32_TIM_MODE_UPDOWN: + val |= GTIM_CR1_CENTER1; + + /* Our default: Interrupts are generated on compare, when counting + * down + */ + + break; + + case STM32_TIM_MODE_PULSE: + val |= GTIM_CR1_OPM; + break; + + default: + return -EINVAL; + } + + stm32_tim_reload_counter(dev); + stm32_putreg16(dev, STM32_GTIM_CR1_OFFSET, val); + + /* Advanced registers require Main Output Enable */ + + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE || + ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE) + { + stm32_modifyreg16(dev, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE); + } + + return OK; +} + +static int stm32_tim_setchannel(struct stm32_tim_dev_s *dev, + uint8_t channel, stm32_tim_channel_t mode) +{ + uint16_t ccmr_orig = 0; + uint16_t ccmr_val = 0; + uint16_t ccmr_mask = 0xff; + uint16_t ccer_val = stm32_getreg16(dev, STM32_GTIM_CCER_OFFSET); + uint8_t ccmr_offset = STM32_GTIM_CCMR1_OFFSET; + + DEBUGASSERT(dev != NULL); + + /* Further we use range as 0..3; if channel=0 it will also overflow here */ + + if (--channel > 4) + { + return -EINVAL; + } + + /* Assume that channel is disabled and polarity is active high */ + + ccer_val &= ~(3 << GTIM_CCER_CCXBASE(channel)); + + /* This function is not supported on basic timers. To enable or + * disable it, simply set its clock to valid frequency or zero. + */ + + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM6_BASE || \ + ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM7_BASE) + { + return -EINVAL; + } + + /* Decode configuration */ + + switch (mode & STM32_TIM_CH_MODE_MASK) + { + case STM32_TIM_CH_DISABLED: + break; + + case STM32_TIM_CH_OUTTOGGLE: + ccmr_val = (GTIM_CCMR_MODE_OCREFTOG << GTIM_CCMR1_OC1M_SHIFT); + ccer_val |= GTIM_CCER_CC1E << GTIM_CCER_CCXBASE(channel); + break; + + case STM32_TIM_CH_OUTPWM: + ccmr_val = (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) + + GTIM_CCMR1_OC1PE; + ccer_val |= GTIM_CCER_CC1E << GTIM_CCER_CCXBASE(channel); + break; + + default: + return -EINVAL; + } + + /* Set polarity */ + + if (mode & STM32_TIM_CH_POLARITY_NEG) + { + ccer_val |= GTIM_CCER_CC1P << GTIM_CCER_CCXBASE(channel); + } + + /* Define its position (shift) and get register offset */ + + if (channel & 1) + { + ccmr_val <<= 8; + ccmr_mask <<= 8; + } + + if (channel > 1) + { + ccmr_offset = STM32_GTIM_CCMR2_OFFSET; + } + + ccmr_orig = stm32_getreg16(dev, ccmr_offset); + ccmr_orig &= ~ccmr_mask; + ccmr_orig |= ccmr_val; + stm32_putreg16(dev, ccmr_offset, ccmr_orig); + stm32_putreg16(dev, STM32_GTIM_CCER_OFFSET, ccer_val); + + /* set GPIO */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32H5_TIM1 + case STM32_TIM1_BASE: + switch (channel) + { +# if defined(GPIO_TIM1_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM1_CH1OUT, mode); break; +# endif +# if defined(GPIO_TIM1_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM1_CH2OUT, mode); break; +# endif +# if defined(GPIO_TIM1_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM1_CH3OUT, mode); break; +# endif +# if defined(GPIO_TIM1_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM1_CH4OUT, mode); break; +# endif +# if defined(GPIO_TIM1_CH5OUT) + case 4: + stm32_tim_gpioconfig(GPIO_TIM1_CH5OUT, mode); break; +# endif +# if defined(GPIO_TIM1_CH6OUT) + case 5: + stm32_tim_gpioconfig(GPIO_TIM1_CH6OUT, mode); break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM2 + case STM32_TIM2_BASE: + switch (channel) + { +# if defined(GPIO_TIM2_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM2_CH1OUT, mode); + break; +# endif +# if defined(GPIO_TIM2_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM2_CH2OUT, mode); + break; +# endif +# if defined(GPIO_TIM2_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM2_CH3OUT, mode); + break; +# endif +# if defined(GPIO_TIM2_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM2_CH4OUT, mode); + break; +#endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM3 + case STM32_TIM3_BASE: + switch (channel) + { +# if defined(GPIO_TIM3_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM3_CH1OUT, mode); + break; +# endif +# if defined(GPIO_TIM3_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM3_CH2OUT, mode); + break; +# endif +# if defined(GPIO_TIM3_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM3_CH3OUT, mode); + break; +# endif +# if defined(GPIO_TIM3_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM3_CH4OUT, mode); + break; +#endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM4 + case STM32_TIM4_BASE: + switch (channel) + { +# if defined(GPIO_TIM4_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM4_CH1OUT, mode); + break; +# endif +# if defined(GPIO_TIM4_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM4_CH2OUT, mode); + break; +# endif +# if defined(GPIO_TIM4_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM4_CH3OUT, mode); + break; +# endif +# if defined(GPIO_TIM4_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM4_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM5 + case STM32_TIM5_BASE: + switch (channel) + { +# if defined(GPIO_TIM5_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM5_CH1OUT, mode); + break; +# endif +# if defined(GPIO_TIM5_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM5_CH2OUT, mode); + break; +# endif +# if defined(GPIO_TIM5_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM5_CH3OUT, mode); + break; +# endif +# if defined(GPIO_TIM5_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM5_CH4OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM8 + case STM32_TIM8_BASE: + switch (channel) + { +# if defined(GPIO_TIM8_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM8_CH1OUT, mode); break; +# endif +# if defined(GPIO_TIM8_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM8_CH2OUT, mode); break; +# endif +# if defined(GPIO_TIM8_CH3OUT) + case 2: + stm32_tim_gpioconfig(GPIO_TIM8_CH3OUT, mode); break; +# endif +# if defined(GPIO_TIM8_CH4OUT) + case 3: + stm32_tim_gpioconfig(GPIO_TIM8_CH4OUT, mode); break; +# endif +# if defined(GPIO_TIM8_CH5OUT) + case 4: + stm32_tim_gpioconfig(GPIO_TIM8_CH5OUT, mode); break; +# endif +# if defined(GPIO_TIM8_CH6OUT) + case 5: + stm32_tim_gpioconfig(GPIO_TIM8_CH6OUT, mode); break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_STM32H5_TIM12 + case STM32_TIM12_BASE: + switch (channel) + { +# if defined(GPIO_TIM12_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM12_CH1OUT, mode); + break; +# endif +# if defined(GPIO_TIM12_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM12_CH2OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM13 + case STM32_TIM13_BASE: + switch (channel) + { +# if defined(GPIO_TIM13_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM13_CH1OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM14 + case STM32_TIM14_BASE: + switch (channel) + { +# if defined(GPIO_TIM14_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM14_CH1OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + +#ifdef CONFIG_STM32H5_TIM15 + case STM32_TIM15_BASE: + switch (channel) + { +# if defined(GPIO_TIM15_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM15_CH1OUT, mode); + break; +# endif +# if defined(GPIO_TIM15_CH2OUT) + case 1: + stm32_tim_gpioconfig(GPIO_TIM15_CH2OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM16 + case STM32_TIM16_BASE: + switch (channel) + { +# if defined(GPIO_TIM16_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM16_CH1OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif +#ifdef CONFIG_STM32H5_TIM17 + case STM32_TIM17_BASE: + switch (channel) + { +# if defined(GPIO_TIM17_CH1OUT) + case 0: + stm32_tim_gpioconfig(GPIO_TIM17_CH1OUT, mode); + break; +# endif + default: + return -EINVAL; + } + break; +#endif + } + + return OK; +} + +static int stm32_tim_setcompare(struct stm32_tim_dev_s *dev, + uint8_t channel, uint32_t compare) +{ + DEBUGASSERT(dev != NULL); + + switch (channel) + { + case 1: + stm32_putreg32(dev, STM32_GTIM_CCR1_OFFSET, compare); + break; + + case 2: + stm32_putreg32(dev, STM32_GTIM_CCR2_OFFSET, compare); + break; + + case 3: + stm32_putreg32(dev, STM32_GTIM_CCR3_OFFSET, compare); + break; + + case 4: + stm32_putreg32(dev, STM32_GTIM_CCR4_OFFSET, compare); + break; + + default: + return -EINVAL; + } + + return OK; +} + +static int stm32_tim_getcapture(struct stm32_tim_dev_s *dev, + uint8_t channel) +{ + DEBUGASSERT(dev != NULL); + + switch (channel) + { + case 1: + return stm32_getreg32(dev, STM32_GTIM_CCR1_OFFSET); + + case 2: + return stm32_getreg32(dev, STM32_GTIM_CCR2_OFFSET); + + case 3: + return stm32_getreg32(dev, STM32_GTIM_CCR3_OFFSET); + + case 4: + return stm32_getreg32(dev, STM32_GTIM_CCR4_OFFSET); + } + + return -EINVAL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct stm32_tim_dev_s *stm32_tim_init(int timer) +{ + struct stm32_tim_dev_s *dev = NULL; + + /* Get structure and enable power */ + + switch (timer) + { +#ifdef CONFIG_STM32H5_TIM1 + case 1: + dev = (struct stm32_tim_dev_s *)&stm32_tim1_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM2 + case 2: + dev = (struct stm32_tim_dev_s *)&stm32_tim2_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM2EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM3 + case 3: + dev = (struct stm32_tim_dev_s *)&stm32_tim3_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM3EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM4 + case 4: + dev = (struct stm32_tim_dev_s *)&stm32_tim4_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM4EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM5 + case 5: + dev = (struct stm32_tim_dev_s *)&stm32_tim5_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM5EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM6 + case 6: + dev = (struct stm32_tim_dev_s *)&stm32_tim6_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM6EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM7 + case 7: + dev = (struct stm32_tim_dev_s *)&stm32_tim7_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM7EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM8 + case 8: + dev = (struct stm32_tim_dev_s *)&stm32_tim8_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM8EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM12 + case 12: + dev = (struct stm32_tim_dev_s *)&stm32_tim12_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM12EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM13 + case 13: + dev = (struct stm32_tim_dev_s *)&stm32_tim13_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM13EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM14 + case 14: + dev = (struct stm32_tim_dev_s *)&stm32_tim14_priv; + modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM14EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM15 + case 15: + dev = (struct stm32_tim_dev_s *)&stm32_tim15_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM15EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM16 + case 16: + dev = (struct stm32_tim_dev_s *)&stm32_tim16_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM16EN); + break; +#endif +#ifdef CONFIG_STM32H5_TIM17 + case 17: + dev = (struct stm32_tim_dev_s *)&stm32_tim17_priv; + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM17EN); + break; +#endif + default: + return NULL; + } + + /* Is device already allocated */ + + if (((struct stm32_tim_priv_s *)dev)->mode != STM32_TIM_MODE_UNUSED) + { + return NULL; + } + + stm32_tim_reset(dev); + + return dev; +} + +/* TODO: Detach interrupts, and close down all TIM Channels */ + +int stm32_tim_deinit(struct stm32_tim_dev_s * dev) +{ + DEBUGASSERT(dev != NULL); + + /* Disable power */ + + switch (((struct stm32_tim_priv_s *)dev)->base) + { +#ifdef CONFIG_STM32H5_TIM1 + case STM32_TIM1_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM1EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM2 + case STM32_TIM2_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM2EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM3 + case STM32_TIM3_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM3EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM4 + case STM32_TIM4_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM4EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM5 + case STM32_TIM5_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM5EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM6 + case STM32_TIM6_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM6EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM7 + case STM32_TIM7_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM7EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM8 + case STM32_TIM8_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM8EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM12 + case STM32_TIM12_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM12EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM13 + case STM32_TIM13_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM13EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM14 + case STM32_TIM14_BASE: + modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM14EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM15 + case STM32_TIM15_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM15EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM16 + case STM32_TIM16_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM16EN, 0); + break; +#endif +#ifdef CONFIG_STM32H5_TIM17 + case STM32_TIM17_BASE: + modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM17EN, 0); + break; +#endif + default: + return -EINVAL; + } + + /* Mark it as free */ + + ((struct stm32_tim_priv_s *)dev)->mode = STM32_TIM_MODE_UNUSED; + + return OK; +} + +#endif /* defined(CONFIG_STM32H5_TIM1 || ... || TIM17) */ diff --git a/arch/arm/src/stm32h5/stm32_tim.h b/arch/arm/src/stm32h5/stm32_tim.h new file mode 100644 index 0000000000..b571fcb715 --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_tim.h @@ -0,0 +1,223 @@ +/**************************************************************************** + * arch/arm/src/stm32h5/stm32_tim.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_TIM_H +#define __ARCH_ARM_SRC_STM32H5_STM32_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "hardware/stm32_tim.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Helpers ******************************************************************/ + +#define STM32_TIM_ENABLE(d) ((d)->ops->enable(d)) +#define STM32_TIM_DISABLE(d) ((d)->ops->disable(d)) +#define STM32_TIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode)) +#define STM32_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq)) +#define STM32_TIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period)) +#define STM32_TIM_GETCOUNTER(d) ((d)->ops->getcounter(d)) +#define STM32_TIM_SETCOUNTER(d,c) ((d)->ops->setcounter(d,c)) +#define STM32_TIM_GETWIDTH(d) ((d)->ops->getwidth(d)) +#define STM32_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode)) +#define STM32_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp)) +#define STM32_TIM_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch)) +#define STM32_TIM_SETISR(d,hnd,arg,s) ((d)->ops->setisr(d,hnd,arg,s)) +#define STM32_TIM_ENABLEINT(d,s) ((d)->ops->enableint(d,s)) +#define STM32_TIM_DISABLEINT(d,s) ((d)->ops->disableint(d,s)) +#define STM32_TIM_ACKINT(d,s) ((d)->ops->ackint(d,s)) +#define STM32_TIM_CHECKINT(d,s) ((d)->ops->checkint(d,s)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* TIM Device Structure */ + +struct stm32_tim_dev_s +{ + struct stm32_tim_ops_s *ops; +}; + +/* TIM Modes of Operation */ + +typedef enum +{ + STM32_TIM_MODE_UNUSED = -1, + + /* One of the following */ + + STM32_TIM_MODE_MASK = 0x0310, + STM32_TIM_MODE_DISABLED = 0x0000, + STM32_TIM_MODE_UP = 0x0100, + STM32_TIM_MODE_DOWN = 0x0110, + STM32_TIM_MODE_UPDOWN = 0x0200, + STM32_TIM_MODE_PULSE = 0x0300, + + /* One of the following */ + + STM32_TIM_MODE_CK_INT = 0x0000, +#if 0 + STM32_TIM_MODE_CK_INT_TRIG = 0x0400, + STM32_TIM_MODE_CK_EXT = 0x0800, + STM32_TIM_MODE_CK_EXT_TRIG = 0x0c00, + + /* Clock sources, OR'ed with CK_EXT */ + + STM32_TIM_MODE_CK_CHINVALID = 0x0000, + STM32_TIM_MODE_CK_CH1 = 0x0001, + STM32_TIM_MODE_CK_CH2 = 0x0002, + STM32_TIM_MODE_CK_CH3 = 0x0003, + STM32_TIM_MODE_CK_CH4 = 0x0004 +#endif + + /* Todo: external trigger block */ +} stm32_tim_mode_t; + +/* TIM Channel Modes */ + +typedef enum +{ + STM32_TIM_CH_DISABLED = 0x00, + + /* Common configuration */ + + STM32_TIM_CH_POLARITY_POS = 0x00, + STM32_TIM_CH_POLARITY_NEG = 0x01, + + /* MODES: */ + + STM32_TIM_CH_MODE_MASK = 0x0e, + + /* Output Compare Modes */ + + /* Enable standard PWM mode, active high when counter < compare */ + + STM32_TIM_CH_OUTPWM = 0x04, + + /* Toggle TIM_CHx output on UEV */ + + STM32_TIM_CH_OUTTOGGLE = 0x08, +#if 0 + STM32_TIM_CH_OUTCOMPARE = 0x06, + + /* TODO other modes ... as PWM capture, ENCODER and Hall Sensor */ + + STM32_TIM_CH_INCAPTURE = 0x10, + STM32_TIM_CH_INPWM = 0x20 + STM32_TIM_CH_DRIVE_OC - open collector mode +#endif +} stm32_tim_channel_t; + +/* TIM Operations */ + +struct stm32_tim_ops_s +{ + /* Basic Timers */ + + void (*enable)(struct stm32_tim_dev_s *dev); + void (*disable)(struct stm32_tim_dev_s *dev); + int (*setmode)(struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode); + int (*setclock)(struct stm32_tim_dev_s *dev, uint32_t freq); + void (*setperiod)(struct stm32_tim_dev_s *dev, uint32_t period); + uint32_t (*getcounter)(struct stm32_tim_dev_s *dev); + void (*setcounter)(struct stm32_tim_dev_s *dev, uint32_t count); + + /* General and Advanced Timers Adds */ + + int (*getwidth)(struct stm32_tim_dev_s *dev); + int (*setchannel)(struct stm32_tim_dev_s *dev, uint8_t channel, + stm32_tim_channel_t mode); + int (*setcompare)(struct stm32_tim_dev_s *dev, uint8_t channel, + uint32_t compare); + int (*getcapture)(struct stm32_tim_dev_s *dev, uint8_t channel); + + /* Timer interrupts */ + + int (*setisr)(struct stm32_tim_dev_s *dev, xcpt_t handler, void *arg, + int source); + void (*enableint)(struct stm32_tim_dev_s *dev, int source); + void (*disableint)(struct stm32_tim_dev_s *dev, int source); + void (*ackint)(struct stm32_tim_dev_s *dev, int source); + int (*checkint)(struct stm32_tim_dev_s *dev, int source); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Power-up timer and get its structure */ + +struct stm32_tim_dev_s *stm32_tim_init(int timer); + +/* Power-down timer, mark it as unused */ + +int stm32_tim_deinit(struct stm32_tim_dev_s *dev); + +/**************************************************************************** + * Name: stm32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * timer - the timer number. + * + * Returned Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_TIMER +int stm32_timer_initialize(const char *devpath, int timer); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32H5_STM32_TIM_H */ diff --git a/arch/arm/src/stm32h5/stm32_tim_lowerhalf.c b/arch/arm/src/stm32h5/stm32_tim_lowerhalf.c new file mode 100644 index 0000000000..b31f677121 --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_tim_lowerhalf.c @@ -0,0 +1,586 @@ +/**************************************************************************** + * arch/arm/src/stm32h5/stm32_tim_lowerhalf.c + * + * SPDX-License-Identifier: BSD-3-Clause + * SPDX-FileCopyrightText: 2023 Max Kriegleder. All rights reserved. + * SPDX-FileCopyrightText: 2015 Wail Khemir. All rights reserved. + * SPDX-FileCopyrightText: 2015 Omni Hoverboards Inc. All rights reserved. + * SPDX-FileContributor: Wail Khemir + * SPDX-FileContributor: Paul Alexander Patience + * SPDX-FileContributor: Max Kriegleder + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#include "stm32_tim.h" + +#if defined(CONFIG_TIMER) && \ + (defined(CONFIG_STM32H5_TIM1) || defined(CONFIG_STM32H5_TIM2) || \ + defined(CONFIG_STM32H5_TIM3) || defined(CONFIG_STM32H5_TIM4) || \ + defined(CONFIG_STM32H5_TIM5) || defined(CONFIG_STM32H5_TIM6) || \ + defined(CONFIG_STM32H5_TIM7) || defined(CONFIG_STM32H5_TIM8) || \ + defined(CONFIG_STM32H5_TIM12) || defined(CONFIG_STM32H5_TIM13) || \ + defined(CONFIG_STM32H5_TIM14) || defined(CONFIG_STM32H5_TIM15) || \ + defined(CONFIG_STM32H5_TIM16) || defined(CONFIG_STM32H5_TIM17)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32_TIM1_RES 16 +#define STM32_TIM2_RES 32 +#define STM32_TIM3_RES 16 +#define STM32_TIM4_RES 16 +#define STM32_TIM5_RES 32 +#define STM32_TIM6_RES 16 +#define STM32_TIM7_RES 16 +#define STM32_TIM8_RES 16 +#define STM32_TIM12_RES 16 +#define STM32_TIM13_RES 16 +#define STM32_TIM14_RES 16 +#define STM32_TIM15_RES 16 +#define STM32_TIM16_RES 16 +#define STM32_TIM17_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 + * timer_lowerhalf_s structure. + */ + +struct stm32_lowerhalf_s +{ + const struct timer_ops_s *ops; /* Lower half operations */ + struct stm32_tim_dev_s *tim; /* stm32 timer driver */ + tccb_t callback; /* Current user interrupt callback */ + void *arg; /* Argument passed to upper half callback */ + bool started; /* True: Timer has been started */ + const uint8_t resolution; /* Number of bits in the timer (16 or 32 bits) */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32_timer_handler(int irq, void * context, void * arg); + +/* "Lower half" driver methods **********************************************/ + +static int stm32_start(struct timer_lowerhalf_s *lower); +static int stm32_stop(struct timer_lowerhalf_s *lower); +static int stm32_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout); +static void stm32_setcallback(struct timer_lowerhalf_s *lower, + tccb_t callback, void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_timer_ops = +{ + .start = stm32_start, + .stop = stm32_stop, + .getstatus = NULL, + .settimeout = stm32_settimeout, + .setcallback = stm32_setcallback, + .ioctl = NULL, +}; + +#ifdef CONFIG_STM32H5_TIM1 +static struct stm32_lowerhalf_s g_tim1_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM1_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM2 +static struct stm32_lowerhalf_s g_tim2_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM2_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM3 +static struct stm32_lowerhalf_s g_tim3_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM3_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM4 +static struct stm32_lowerhalf_s g_tim4_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM4_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM5 +static struct stm32_lowerhalf_s g_tim5_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM5_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM6 +static struct stm32_lowerhalf_s g_tim6_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM6_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM7 +static struct stm32_lowerhalf_s g_tim7_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM7_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM8 +static struct stm32_lowerhalf_s g_tim8_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM8_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM12 +static struct stm32_lowerhalf_s g_tim12_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM12_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM13 +static struct stm32_lowerhalf_s g_tim13_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM13_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM14 +static struct stm32_lowerhalf_s g_tim14_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM14_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM15 +static struct stm32_lowerhalf_s g_tim15_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM15_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM16 +static struct stm32_lowerhalf_s g_tim16_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM16_RES, +}; +#endif + +#ifdef CONFIG_STM32H5_TIM17 +static struct stm32_lowerhalf_s g_tim17_lowerhalf = +{ + .ops = &g_timer_ops, + .resolution = STM32_TIM17_RES, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_timer_handler + * + * Description: + * timer interrupt handler + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int stm32_timer_handler(int irq, void * context, void * arg) +{ + struct stm32_lowerhalf_s *lower = (struct stm32_lowerhalf_s *) arg; + uint32_t next_interval_us = 0; + + STM32_TIM_ACKINT(lower->tim, ATIM_DIER_UIE); + + if (lower->callback(&next_interval_us, lower->arg)) + { + if (next_interval_us > 0) + { + STM32_TIM_SETPERIOD(lower->tim, next_interval_us); + } + } + else + { + stm32_stop((struct timer_lowerhalf_s *)lower); + } + + 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 timer_lowerhalf_s *lower) +{ + struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + + if (!priv->started) + { + STM32_TIM_SETMODE(priv->tim, STM32_TIM_MODE_UP); + + if (priv->callback != NULL) + { + STM32_TIM_SETISR(priv->tim, stm32_timer_handler, priv, 0); + STM32_TIM_ENABLEINT(priv->tim, ATIM_DIER_UIE); + } + + priv->started = true; + return OK; + } + + /* Return EBUSY to indicate that the timer was already running */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: stm32_stop + * + * Description: + * Stop the timer + * + * 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 timer_lowerhalf_s *lower) +{ + struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + + if (priv->started) + { + STM32_TIM_SETMODE(priv->tim, STM32_TIM_MODE_DISABLED); + STM32_TIM_DISABLEINT(priv->tim, ATIM_DIER_UIE); + STM32_TIM_SETISR(priv->tim, NULL, NULL, 0); + priv->started = false; + return OK; + } + + /* Return ENODEV to indicate that the timer was not running */ + + return -ENODEV; +} + +/**************************************************************************** + * Name: stm32_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * timeout - The new timeout value in microseconds. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int stm32_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + uint64_t maxtimeout; + + if (priv->started) + { + return -EPERM; + } + + maxtimeout = (1 << priv->resolution) - 1; + if (timeout > maxtimeout) + { + uint64_t freq = (maxtimeout * 1000000) / timeout; + STM32_TIM_SETCLOCK(priv->tim, freq); + STM32_TIM_SETPERIOD(priv->tim, maxtimeout); + } + else + { + STM32_TIM_SETCLOCK(priv->tim, 1000000); + STM32_TIM_SETPERIOD(priv->tim, timeout); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_setcallback + * + * Description: + * Call this user provided timeout callback. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * callback - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * arg - Argument that will be provided in the callback + * + * Returned Value: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static void stm32_setcallback(struct timer_lowerhalf_s *lower, + tccb_t callback, void *arg) +{ + struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower; + + irqstate_t flags = enter_critical_section(); + + /* Save the new callback */ + + priv->callback = callback; + priv->arg = arg; + + if (callback != NULL && priv->started) + { + STM32_TIM_SETISR(priv->tim, stm32_timer_handler, priv, 0); + STM32_TIM_ENABLEINT(priv->tim, ATIM_DIER_UIE); + } + else + { + STM32_TIM_DISABLEINT(priv->tim, ATIM_DIER_UIE); + STM32_TIM_SETISR(priv->tim, NULL, NULL, 0); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * timer - the timer's number. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int stm32_timer_initialize(const char *devpath, int timer) +{ + struct stm32_lowerhalf_s *lower; + + switch (timer) + { +#ifdef CONFIG_STM32H5_TIM1 + case 1: + lower = &g_tim1_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM2 + case 2: + lower = &g_tim2_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM3 + case 3: + lower = &g_tim3_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM4 + case 4: + lower = &g_tim4_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM5 + case 5: + lower = &g_tim5_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM6 + case 6: + lower = &g_tim6_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM7 + case 7: + lower = &g_tim7_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM8 + case 8: + lower = &g_tim8_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM12 + case 12: + lower = &g_tim12_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM13 + case 13: + lower = &g_tim13_lowerhalf; + break; +#endif +#ifdef CONFIG_STM32H5_TIM14 + case 14: + lower = &g_tim14_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32H5_TIM15 + case 15: + lower = &g_tim15_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32H5_TIM16 + case 16: + lower = &g_tim16_lowerhalf; + break; +#endif + +#ifdef CONFIG_STM32H5_TIM17 + case 17: + lower = &g_tim17_lowerhalf; + break; +#endif + + default: + return -ENODEV; + } + + /* Initialize the elements of lower half state structure */ + + lower->started = false; + lower->callback = NULL; + lower->tim = stm32_tim_init(timer); + + if (lower->tim == NULL) + { + return -EINVAL; + } + + /* Register the timer driver as /dev/timerX. The returned value from + * timer_register is a handle that could be used with timer_unregister(). + * REVISIT: The returned handle is discard here. + */ + + void *drvr = timer_register(devpath, + (struct timer_lowerhalf_s *)lower); + if (drvr == NULL) + { + /* The actual cause of the failure may have been a failure to allocate + * perhaps a failure to register the timer driver (such as if the + * 'depath' were not unique). We know here but we return EEXIST to + * indicate the failure (implying the non-unique devpath). + */ + + return -EEXIST; + } + + return OK; +} + +#endif /* CONFIG_TIMER */ diff --git a/arch/arm/src/stm32h5/stm32h5xx_rcc.c b/arch/arm/src/stm32h5/stm32h5xx_rcc.c index 18a051341e..b01905edb3 100644 --- a/arch/arm/src/stm32h5/stm32h5xx_rcc.c +++ b/arch/arm/src/stm32h5/stm32h5xx_rcc.c @@ -355,60 +355,6 @@ static inline void rcc_enableapb1l(void) regval = getreg32(STM32_RCC_APB1LENR); -#ifdef CONFIG_STM32H5_TIM2 - /* Bit 0: TIM2 clock enable */ - - regval |= RCC_APB1LENR_TIM2EN; -#endif - -#ifdef CONFIG_STM32H5_TIM3 - /* Bit 1: TIM3 clock enable */ - - regval |= RCC_APB1LENR_TIM3EN; -#endif - -#ifdef CONFIG_STM32H5_TIM4 - /* Bit 2: TIM4 clock enable */ - - regval |= RCC_APB1LENR_TIM4EN; -#endif - -#ifdef CONFIG_STM32H5_TIM5 - /* Bit 3: TIM5 clock enable */ - - regval |= RCC_APB1LENR_TIM5EN; -#endif - -#ifdef CONFIG_STM32H5_TIM6 - /* Bit 4: TIM6 clock enable */ - - regval |= RCC_APB1LENR_TIM6EN; -#endif - -#ifdef CONFIG_STM32H5_TIM7 - /* Bit 5: TIM7 clock enable */ - - regval |= RCC_APB1LENR_TIM7EN; -#endif - -#ifdef CONFIG_STM32H5_TIM12 - /* Bit 5: TIM12 clock enable */ - - regval |= RCC_APB1LENR_TIM12EN; -#endif - -#ifdef CONFIG_STM32H5_TIM13 - /* Bit 5: TIM13 clock enable */ - - regval |= RCC_APB1LENR_TIM13EN; -#endif - -#ifdef CONFIG_STM32H5_TIM14 - /* Bit 5: TIM14 clock enable */ - - regval |= RCC_APB1LENR_TIM14EN; -#endif - #ifdef CONFIG_STM32H5_SPI2 /* Bit 14: SPI2 clock enable */ @@ -588,48 +534,18 @@ static inline void rcc_enableapb2(void) regval = getreg32(STM32_RCC_APB2ENR); -#ifdef CONFIG_STM32H5_TIM1 - /* TIM1 clock enable */ - - regval |= RCC_APB2ENR_TIM1EN; -#endif - #ifdef CONFIG_STM32H5_SPI1 /* SPI1 clock enable */ regval |= RCC_APB2ENR_SPI1EN; #endif -#ifdef CONFIG_STM32H5_TIM8 - /* TIM8 clock enable */ - - regval |= RCC_APB2ENR_TIM8EN; -#endif - #ifdef CONFIG_STM32H5_USART1 /* USART1 clock enable */ regval |= RCC_APB2ENR_USART1EN; #endif -#ifdef CONFIG_STM32H5_TIM15 - /* TIM15 clock enable */ - - regval |= RCC_APB2ENR_TIM15EN; -#endif - -#ifdef CONFIG_STM32H5_TIM16 - /* TIM16 clock enable */ - - regval |= RCC_APB2ENR_TIM16EN; -#endif - -#ifdef CONFIG_STM32H5_TIM17 - /* TIM17 clock enable */ - - regval |= RCC_APB2ENR_TIM17EN; -#endif - #ifdef CONFIG_STM32H5_SPI4 /* SPI4 clock enable */