diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 9c9e39e17d..e9d597c948 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -1532,6 +1532,7 @@ config STM32_STM32F30XX select STM32_HAVE_TIM15 select STM32_HAVE_TIM16 select STM32_HAVE_TIM17 + select STM32_HAVE_IP_TIMERS_V2 config STM32_STM32F302 bool @@ -1570,6 +1571,7 @@ config STM32_STM32F33XX select STM32_HAVE_DAC1 select STM32_HAVE_DAC2 select STM32_HAVE_USART3 + select STM32_HAVE_IP_TIMERS_V2 config STM32_STM32F37XX bool @@ -1965,6 +1967,10 @@ config STM32_HAVE_UART8 bool default n +config STM32_HAVE_IP_TIMERS_V2 + bool + default n + config STM32_HAVE_TIM1 bool default n @@ -3151,6 +3157,12 @@ config STM32_ONESHOT_MAXTIMERS of the timers and places an upper limit on the number of oneshot timers that you can use. +config STM32_PWM_LL_OPS + bool "PWM low-lewel operations" + default n + ---help--- + Enable low-level PWM ops. + config STM32_TIM1_PWM bool "TIM1 PWM" default n @@ -3173,6 +3185,27 @@ config STM32_TIM1_MODE ---help--- Specifies the timer mode. +config STM32_TIM1_LOCK + int "TIM1 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 1 lock level configuration + +config STM32_TIM1_TDTS + int "TIM1 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 1 dead-time and sampling clock (t_DTS) division + +config STM32_TIM1_DEADTIME + int "TIM1 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 1 initial dead-time + if STM32_PWM_MULTICHAN config STM32_TIM1_CHANNEL1 @@ -3186,8 +3219,8 @@ if STM32_TIM1_CHANNEL1 config STM32_TIM1_CH1MODE int "TIM1 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3197,6 +3230,12 @@ config STM32_TIM1_CH1OUT ---help--- Enables channel 1 output. +config STM32_TIM1_CH1NOUT + bool "TIM1 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + endif # STM32_TIM1_CHANNEL1 config STM32_TIM1_CHANNEL2 @@ -3210,8 +3249,8 @@ if STM32_TIM1_CHANNEL2 config STM32_TIM1_CH2MODE int "TIM1 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3221,6 +3260,12 @@ config STM32_TIM1_CH2OUT ---help--- Enables channel 2 output. +config STM32_TIM1_CH2NOUT + bool "TIM1 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + endif # STM32_TIM1_CHANNEL2 config STM32_TIM1_CHANNEL3 @@ -3234,8 +3279,8 @@ if STM32_TIM1_CHANNEL3 config STM32_TIM1_CH3MODE int "TIM1 Channel 3 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3245,6 +3290,12 @@ config STM32_TIM1_CH3OUT ---help--- Enables channel 3 output. +config STM32_TIM1_CH3NOUT + bool "TIM1 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + endif # STM32_TIM1_CHANNEL3 config STM32_TIM1_CHANNEL4 @@ -3258,8 +3309,8 @@ if STM32_TIM1_CHANNEL4 config STM32_TIM1_CH4MODE int "TIM1 Channel 4 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3283,11 +3334,69 @@ config STM32_TIM1_CHANNEL If TIM1 is enabled for PWM usage, you also need specifies the timer output channel {1,..,4} +if STM32_TIM1_CHANNEL = 1 + +config STM32_TIM1_CH1OUT + bool "TIM1 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32_TIM1_CH1NOUT + bool "TIM1 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32_TIM1_CHANNEL = 1 + +if STM32_TIM1_CHANNEL = 2 + +config STM32_TIM1_CH2OUT + bool "TIM1 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32_TIM1_CH2NOUT + bool "TIM1 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32_TIM1_CHANNEL = 2 + +if STM32_TIM1_CHANNEL = 3 + +config STM32_TIM1_CH3OUT + bool "TIM1 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32_TIM1_CH3NOUT + bool "TIM1 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + +endif # STM32_TIM1_CHANNEL = 3 + +if STM32_TIM1_CHANNEL = 4 + +config STM32_TIM1_CH4OUT + bool "TIM1 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM1_CHANNEL = 4 + config STM32_TIM1_CHMODE int "TIM1 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3330,8 +3439,8 @@ if STM32_TIM2_CHANNEL1 config STM32_TIM2_CH1MODE int "TIM2 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3354,8 +3463,8 @@ if STM32_TIM2_CHANNEL2 config STM32_TIM2_CH2MODE int "TIM2 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3378,8 +3487,8 @@ if STM32_TIM2_CHANNEL3 config STM32_TIM2_CH3MODE int "TIM2 Channel 3 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3402,8 +3511,8 @@ if STM32_TIM2_CHANNEL4 config STM32_TIM2_CH4MODE int "TIM2 Channel 4 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3427,11 +3536,51 @@ config STM32_TIM2_CHANNEL If TIM2 is enabled for PWM usage, you also need specifies the timer output channel {1,..,4} +if STM32_TIM2_CHANNEL = 1 + +config STM32_TIM2_CH1OUT + bool "TIM2 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM2_CHANNEL = 1 + +if STM32_TIM2_CHANNEL = 2 + +config STM32_TIM2_CH2OUT + bool "TIM2 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM2_CHANNEL = 2 + +if STM32_TIM2_CHANNEL = 3 + +config STM32_TIM2_CH3OUT + bool "TIM2 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM2_CHANNEL = 3 + +if STM32_TIM2_CHANNEL = 4 + +config STM32_TIM2_CH4OUT + bool "TIM2 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM2_CHANNEL = 4 + config STM32_TIM2_CHMODE int "TIM2 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3474,8 +3623,8 @@ if STM32_TIM3_CHANNEL1 config STM32_TIM3_CH1MODE int "TIM3 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3498,8 +3647,8 @@ if STM32_TIM3_CHANNEL2 config STM32_TIM3_CH2MODE int "TIM3 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3522,8 +3671,8 @@ if STM32_TIM3_CHANNEL3 config STM32_TIM3_CH3MODE int "TIM3 Channel 3 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3546,8 +3695,8 @@ if STM32_TIM3_CHANNEL4 config STM32_TIM3_CH4MODE int "TIM3 Channel 4 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3571,11 +3720,51 @@ config STM32_TIM3_CHANNEL If TIM3 is enabled for PWM usage, you also need specifies the timer output channel {1,..,4} +if STM32_TIM3_CHANNEL = 1 + +config STM32_TIM3_CH1OUT + bool "TIM3 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM3_CHANNEL = 1 + +if STM32_TIM3_CHANNEL = 2 + +config STM32_TIM3_CH2OUT + bool "TIM3 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM3_CHANNEL = 2 + +if STM32_TIM3_CHANNEL = 3 + +config STM32_TIM3_CH3OUT + bool "TIM3 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM3_CHANNEL = 3 + +if STM32_TIM3_CHANNEL = 4 + +config STM32_TIM3_CH4OUT + bool "TIM3 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM3_CHANNEL = 4 + config STM32_TIM3_CHMODE int "TIM3 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3618,8 +3807,8 @@ if STM32_TIM4_CHANNEL1 config STM32_TIM4_CH1MODE int "TIM4 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3642,8 +3831,8 @@ if STM32_TIM4_CHANNEL2 config STM32_TIM4_CH2MODE int "TIM4 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3666,8 +3855,8 @@ if STM32_TIM4_CHANNEL3 config STM32_TIM4_CH3MODE int "TIM4 Channel 3 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3690,8 +3879,8 @@ if STM32_TIM4_CHANNEL4 config STM32_TIM4_CH4MODE int "TIM4 Channel 4 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3715,11 +3904,51 @@ config STM32_TIM4_CHANNEL If TIM4 is enabled for PWM usage, you also need specifies the timer output channel {1,..,4} +if STM32_TIM4_CHANNEL = 1 + +config STM32_TIM4_CH1OUT + bool "TIM4 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM4_CHANNEL = 1 + +if STM32_TIM4_CHANNEL = 2 + +config STM32_TIM4_CH2OUT + bool "TIM4 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM4_CHANNEL = 2 + +if STM32_TIM4_CHANNEL = 3 + +config STM32_TIM4_CH3OUT + bool "TIM4 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM4_CHANNEL = 3 + +if STM32_TIM4_CHANNEL = 4 + +config STM32_TIM4_CH4OUT + bool "TIM4 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM4_CHANNEL = 4 + config STM32_TIM4_CHMODE int "TIM4 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3762,8 +3991,8 @@ if STM32_TIM5_CHANNEL1 config STM32_TIM5_CH1MODE int "TIM5 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3786,8 +4015,8 @@ if STM32_TIM5_CHANNEL2 config STM32_TIM5_CH2MODE int "TIM5 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3810,8 +4039,8 @@ if STM32_TIM5_CHANNEL3 config STM32_TIM5_CH3MODE int "TIM5 Channel 3 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3834,8 +4063,8 @@ if STM32_TIM5_CHANNEL4 config STM32_TIM5_CH4MODE int "TIM5 Channel 4 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3859,11 +4088,51 @@ config STM32_TIM5_CHANNEL If TIM5 is enabled for PWM usage, you also need specifies the timer output channel {1,..,4} +if STM32_TIM5_CHANNEL = 1 + +config STM32_TIM5_CH1OUT + bool "TIM5 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM5_CHANNEL = 1 + +if STM32_TIM5_CHANNEL = 2 + +config STM32_TIM5_CH2OUT + bool "TIM5 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM5_CHANNEL = 2 + +if STM32_TIM5_CHANNEL = 3 + +config STM32_TIM5_CH3OUT + bool "TIM5 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +endif # STM32_TIM5_CHANNEL = 3 + +if STM32_TIM5_CHANNEL = 4 + +config STM32_TIM5_CH4OUT + bool "TIM5 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM5_CHANNEL = 4 + config STM32_TIM5_CHMODE int "TIM5 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3893,6 +4162,27 @@ config STM32_TIM8_MODE ---help--- Specifies the timer mode. +config STM32_TIM8_LOCK + int "TIM8 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 8 lock level configuration + +config STM32_TIM8_DEADTIME + int "TIM8 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 8 initial dead-time + +config STM32_TIM8_TDTS + int "TIM8 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 8 dead-time and sampling clock (t_DTS) division + if STM32_PWM_MULTICHAN config STM32_TIM8_CHANNEL1 @@ -3906,16 +4196,16 @@ if STM32_TIM8_CHANNEL1 config STM32_TIM8_CH1MODE int "TIM8 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. -config STM32_TIM8_CH1OUT - bool "TIM8 Channel 1 Output" +config STM32_TIM8_CH1NOUT + bool "TIM8 Channel 1 Complementary Output" default n ---help--- - Enables channel 1 output. + Enables channel 1 Complementary Output. endif # STM32_TIM8_CHANNEL1 @@ -3930,8 +4220,8 @@ if STM32_TIM8_CHANNEL2 config STM32_TIM8_CH2MODE int "TIM8 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3941,6 +4231,12 @@ config STM32_TIM8_CH2OUT ---help--- Enables channel 2 output. +config STM32_TIM8_CH2NOUT + bool "TIM8 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + endif # STM32_TIM8_CHANNEL2 config STM32_TIM8_CHANNEL3 @@ -3954,8 +4250,8 @@ if STM32_TIM8_CHANNEL3 config STM32_TIM8_CH3MODE int "TIM8 Channel 3 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -3965,6 +4261,12 @@ config STM32_TIM8_CH3OUT ---help--- Enables channel 3 output. +config STM32_TIM8_CH3NOUT + bool "TIM8 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + endif # STM32_TIM8_CHANNEL3 config STM32_TIM8_CHANNEL4 @@ -3978,8 +4280,8 @@ if STM32_TIM8_CHANNEL4 config STM32_TIM8_CH4MODE int "TIM8 Channel 4 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4003,11 +4305,69 @@ config STM32_TIM8_CHANNEL If TIM8 is enabled for PWM usage, you also need specifies the timer output channel {1,..,4} +if STM32_TIM8_CHANNEL = 1 + +config STM32_TIM8_CH1OUT + bool "TIM8 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32_TIM8_CH1NOUT + bool "TIM8 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32_TIM8_CHANNEL = 1 + +if STM32_TIM8_CHANNEL = 2 + +config STM32_TIM8_CH2OUT + bool "TIM8 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32_TIM8_CH2NOUT + bool "TIM8 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32_TIM8_CHANNEL = 2 + +if STM32_TIM8_CHANNEL = 3 + +config STM32_TIM8_CH3OUT + bool "TIM8 Channel 3 Output" + default n + ---help--- + Enables channel 3 output. + +config STM32_TIM8_CH3NOUT + bool "TIM8 Channel 3 Complementary Output" + default n + ---help--- + Enables channel 3 Complementary Output. + +endif # STM32_TIM8_CHANNEL = 3 + +if STM32_TIM8_CHANNEL = 4 + +config STM32_TIM8_CH4OUT + bool "TIM8 Channel 4 Output" + default n + ---help--- + Enables channel 4 output. + +endif # STM32_TIM8_CHANNEL = 4 + config STM32_TIM8_CHMODE int "TIM8 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4043,8 +4403,8 @@ if STM32_TIM9_CHANNEL1 config STM32_TIM9_CH1MODE int "TIM9 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4067,8 +4427,8 @@ if STM32_TIM9_CHANNEL2 config STM32_TIM9_CH2MODE int "TIM9 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4080,54 +4440,6 @@ config STM32_TIM9_CH2OUT endif # STM32_TIM9_CHANNEL2 -config STM32_TIM9_CHANNEL3 - bool "TIM9 Channel 3" - default n - ---help--- - Enables channel 3. - -if STM32_TIM9_CHANNEL3 - -config STM32_TIM9_CH3MODE - int "TIM9 Channel 3 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM9_CH3OUT - bool "TIM9 Channel 3 Output" - default n - ---help--- - Enables channel 3 output. - -endif # STM32_TIM9_CHANNEL3 - -config STM32_TIM9_CHANNEL4 - bool "TIM9 Channel 4" - default n - ---help--- - Enables channel 4. - -if STM32_TIM9_CHANNEL4 - -config STM32_TIM9_CH4MODE - int "TIM9 Channel 4 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM9_CH4OUT - bool "TIM9 Channel 4 Output" - default n - ---help--- - Enables channel 4 output. - -endif # STM32_TIM9_CHANNEL4 - endif # STM32_PWM_MULTICHAN if !STM32_PWM_MULTICHAN @@ -4135,16 +4447,36 @@ if !STM32_PWM_MULTICHAN config STM32_TIM9_CHANNEL int "TIM9 PWM Output Channel" default 1 - range 1 4 + range 1 2 ---help--- If TIM9 is enabled for PWM usage, you also need specifies the timer output - channel {1,..,4} + channel {1,2} + +if STM32_TIM9_CHANNEL = 1 + +config STM32_TIM9_CH1OUT + bool "TIM9 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM9_CHANNEL = 1 + +if STM32_TIM9_CHANNEL = 2 + +config STM32_TIM9_CH2OUT + bool "TIM9 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM9_CHANNEL = 2 config STM32_TIM9_CHMODE int "TIM9 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4180,8 +4512,8 @@ if STM32_TIM10_CHANNEL1 config STM32_TIM10_CH1MODE int "TIM10 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4193,78 +4525,6 @@ config STM32_TIM10_CH1OUT endif # STM32_TIM10_CHANNEL1 -config STM32_TIM10_CHANNEL2 - bool "TIM10 Channel 2" - default n - ---help--- - Enables channel 2. - -if STM32_TIM10_CHANNEL2 - -config STM32_TIM10_CH2MODE - int "TIM10 Channel 2 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM10_CH2OUT - bool "TIM10 Channel 2 Output" - default n - ---help--- - Enables channel 2 output. - -endif # STM32_TIM10_CHANNEL2 - -config STM32_TIM10_CHANNEL3 - bool "TIM10 Channel 3" - default n - ---help--- - Enables channel 3. - -if STM32_TIM10_CHANNEL3 - -config STM32_TIM10_CH3MODE - int "TIM10 Channel 3 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM10_CH3OUT - bool "TIM10 Channel 3 Output" - default n - ---help--- - Enables channel 3 output. - -endif # STM32_TIM10_CHANNEL3 - -config STM32_TIM10_CHANNEL4 - bool "TIM10 Channel 4" - default n - ---help--- - Enables channel 4. - -if STM32_TIM10_CHANNEL4 - -config STM32_TIM10_CH4MODE - int "TIM10 Channel 4 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM10_CH4OUT - bool "TIM10 Channel 4 Output" - default n - ---help--- - Enables channel 4 output. - -endif # STM32_TIM10_CHANNEL4 - endif # STM32_PWM_MULTICHAN if !STM32_PWM_MULTICHAN @@ -4272,16 +4532,26 @@ if !STM32_PWM_MULTICHAN config STM32_TIM10_CHANNEL int "TIM10 PWM Output Channel" default 1 - range 1 4 + range 1 1 ---help--- If TIM10 is enabled for PWM usage, you also need specifies the timer output - channel {1,..,4} + channel {1} + +if STM32_TIM10_CHANNEL = 1 + +config STM32_TIM10_CH1OUT + bool "TIM10 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM10_CHANNEL = 1 config STM32_TIM10_CHMODE int "TIM10 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4317,8 +4587,8 @@ if STM32_TIM11_CHANNEL1 config STM32_TIM11_CH1MODE int "TIM11 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4330,78 +4600,6 @@ config STM32_TIM11_CH1OUT endif # STM32_TIM11_CHANNEL1 -config STM32_TIM11_CHANNEL2 - bool "TIM11 Channel 2" - default n - ---help--- - Enables channel 2. - -if STM32_TIM11_CHANNEL2 - -config STM32_TIM11_CH2MODE - int "TIM11 Channel 2 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM11_CH2OUT - bool "TIM11 Channel 2 Output" - default n - ---help--- - Enables channel 2 output. - -endif # STM32_TIM11_CHANNEL2 - -config STM32_TIM11_CHANNEL3 - bool "TIM11 Channel 3" - default n - ---help--- - Enables channel 3. - -if STM32_TIM11_CHANNEL3 - -config STM32_TIM11_CH3MODE - int "TIM11 Channel 3 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM11_CH3OUT - bool "TIM11 Channel 3 Output" - default n - ---help--- - Enables channel 3 output. - -endif # STM32_TIM11_CHANNEL3 - -config STM32_TIM11_CHANNEL4 - bool "TIM11 Channel 4" - default n - ---help--- - Enables channel 4. - -if STM32_TIM11_CHANNEL4 - -config STM32_TIM11_CH4MODE - int "TIM11 Channel 4 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM11_CH4OUT - bool "TIM11 Channel 4 Output" - default n - ---help--- - Enables channel 4 output. - -endif # STM32_TIM11_CHANNEL4 - endif # STM32_PWM_MULTICHAN if !STM32_PWM_MULTICHAN @@ -4409,16 +4607,26 @@ if !STM32_PWM_MULTICHAN config STM32_TIM11_CHANNEL int "TIM11 PWM Output Channel" default 1 - range 1 4 + range 1 1 ---help--- If TIM11 is enabled for PWM usage, you also need specifies the timer output - channel {1,..,4} + channel {1} + +if STM32_TIM11_CHANNEL = 1 + +config STM32_TIM11_CH1OUT + bool "TIM11 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM11_CHANNEL = 1 config STM32_TIM11_CHMODE int "TIM11 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4454,8 +4662,8 @@ if STM32_TIM12_CHANNEL1 config STM32_TIM12_CH1MODE int "TIM12 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4478,8 +4686,8 @@ if STM32_TIM12_CHANNEL2 config STM32_TIM12_CH2MODE int "TIM12 Channel 2 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4491,54 +4699,6 @@ config STM32_TIM12_CH2OUT endif # STM32_TIM12_CHANNEL2 -config STM32_TIM12_CHANNEL3 - bool "TIM12 Channel 3" - default n - ---help--- - Enables channel 3. - -if STM32_TIM12_CHANNEL3 - -config STM32_TIM12_CH3MODE - int "TIM12 Channel 3 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM12_CH3OUT - bool "TIM12 Channel 3 Output" - default n - ---help--- - Enables channel 3 output. - -endif # STM32_TIM12_CHANNEL3 - -config STM32_TIM12_CHANNEL4 - bool "TIM12 Channel 4" - default n - ---help--- - Enables channel 4. - -if STM32_TIM12_CHANNEL4 - -config STM32_TIM12_CH4MODE - int "TIM12 Channel 4 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM12_CH4OUT - bool "TIM12 Channel 4 Output" - default n - ---help--- - Enables channel 4 output. - -endif # STM32_TIM12_CHANNEL4 - endif # STM32_PWM_MULTICHAN if !STM32_PWM_MULTICHAN @@ -4546,16 +4706,36 @@ if !STM32_PWM_MULTICHAN config STM32_TIM12_CHANNEL int "TIM12 PWM Output Channel" default 1 - range 1 4 + range 1 2 ---help--- If TIM12 is enabled for PWM usage, you also need specifies the timer output - channel {1,..,4} + channel {1,2} + +if STM32_TIM9_CHANNEL = 1 + +config STM32_TIM12_CH1OUT + bool "TIM12 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM12_CHANNEL = 1 + +if STM32_TIM12_CHANNEL = 2 + +config STM32_TIM12_CH2OUT + bool "TIM12 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +endif # STM32_TIM12_CHANNEL = 2 config STM32_TIM12_CHMODE int "TIM12 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4591,8 +4771,8 @@ if STM32_TIM13_CHANNEL1 config STM32_TIM13_CH1MODE int "TIM13 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4604,78 +4784,6 @@ config STM32_TIM13_CH1OUT endif # STM32_TIM13_CHANNEL1 -config STM32_TIM13_CHANNEL2 - bool "TIM13 Channel 2" - default n - ---help--- - Enables channel 2. - -if STM32_TIM13_CHANNEL2 - -config STM32_TIM13_CH2MODE - int "TIM13 Channel 2 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM13_CH2OUT - bool "TIM13 Channel 2 Output" - default n - ---help--- - Enables channel 2 output. - -endif # STM32_TIM13_CHANNEL2 - -config STM32_TIM13_CHANNEL3 - bool "TIM13 Channel 3" - default n - ---help--- - Enables channel 3. - -if STM32_TIM13_CHANNEL3 - -config STM32_TIM13_CH3MODE - int "TIM13 Channel 3 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM13_CH3OUT - bool "TIM13 Channel 3 Output" - default n - ---help--- - Enables channel 3 output. - -endif # STM32_TIM13_CHANNEL3 - -config STM32_TIM13_CHANNEL4 - bool "TIM13 Channel 4" - default n - ---help--- - Enables channel 4. - -if STM32_TIM13_CHANNEL4 - -config STM32_TIM13_CH4MODE - int "TIM13 Channel 4 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM13_CH4OUT - bool "TIM13 Channel 4 Output" - default n - ---help--- - Enables channel 4 output. - -endif # STM32_TIM13_CHANNEL4 - endif # STM32_PWM_MULTICHAN if !STM32_PWM_MULTICHAN @@ -4683,16 +4791,26 @@ if !STM32_PWM_MULTICHAN config STM32_TIM13_CHANNEL int "TIM13 PWM Output Channel" default 1 - range 1 4 + range 1 1 ---help--- If TIM13 is enabled for PWM usage, you also need specifies the timer output - channel {1,..,4} + channel {1} + +if STM32_TIM14_CHANNEL = 1 + +config STM32_TIM13_CH1OUT + bool "TIM13 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM13_CHANNEL = 1 config STM32_TIM13_CHMODE int "TIM13 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4728,8 +4846,8 @@ if STM32_TIM14_CHANNEL1 config STM32_TIM14_CH1MODE int "TIM14 Channel 1 Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4741,78 +4859,6 @@ config STM32_TIM14_CH1OUT endif # STM32_TIM14_CHANNEL1 -config STM32_TIM14_CHANNEL2 - bool "TIM14 Channel 2" - default n - ---help--- - Enables channel 2. - -if STM32_TIM14_CHANNEL2 - -config STM32_TIM14_CH2MODE - int "TIM14 Channel 2 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM14_CH2OUT - bool "TIM14 Channel 2 Output" - default n - ---help--- - Enables channel 2 output. - -endif # STM32_TIM14_CHANNEL2 - -config STM32_TIM14_CHANNEL3 - bool "TIM14 Channel 3" - default n - ---help--- - Enables channel 3. - -if STM32_TIM14_CHANNEL3 - -config STM32_TIM14_CH3MODE - int "TIM14 Channel 3 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM14_CH3OUT - bool "TIM14 Channel 3 Output" - default n - ---help--- - Enables channel 3 output. - -endif # STM32_TIM14_CHANNEL3 - -config STM32_TIM14_CHANNEL4 - bool "TIM14 Channel 4" - default n - ---help--- - Enables channel 4. - -if STM32_TIM14_CHANNEL4 - -config STM32_TIM14_CH4MODE - int "TIM14 Channel 4 Mode" - default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX - ---help--- - Specifies the channel mode. - -config STM32_TIM14_CH4OUT - bool "TIM14 Channel 4 Output" - default n - ---help--- - Enables channel 4 output. - -endif # STM32_TIM14_CHANNEL4 - endif # STM32_PWM_MULTICHAN if !STM32_PWM_MULTICHAN @@ -4820,16 +4866,26 @@ if !STM32_PWM_MULTICHAN config STM32_TIM14_CHANNEL int "TIM14 PWM Output Channel" default 1 - range 1 4 + range 1 1 ---help--- If TIM14 is enabled for PWM usage, you also need specifies the timer output - channel {1,..,4} + channel {1} + +if STM32_TIM14_CHANNEL = 1 + +config STM32_TIM14_CH1OUT + bool "TIM14 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM14_CHANNEL = 1 config STM32_TIM14_CHMODE int "TIM14 Channel Mode" default 0 - range 0 5 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 5 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4851,6 +4907,27 @@ config STM32_TIM15_PWM if STM32_TIM15_PWM +config STM32_TIM15_LOCK + int "TIM15 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 15 lock level configuration + +config STM32_TIM15_TDTS + int "TIM15 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 15 dead-time and sampling clock (t_DTS) division + +config STM32_TIM15_DEADTIME + int "TIM15 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 15 initial dead-time + if STM32_PWM_MULTICHAN config STM32_TIM15_CHANNEL1 @@ -4864,8 +4941,8 @@ if STM32_TIM15_CHANNEL1 config STM32_TIM15_CH1MODE int "TIM15 Channel 1 Mode" default 0 - range 0 3 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 3 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4875,6 +4952,12 @@ config STM32_TIM15_CH1OUT ---help--- Enables channel 1 output. +config STM32_TIM15_CH1NOUT + bool "TIM15 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + endif # STM32_TIM15_CHANNEL1 config STM32_TIM15_CHANNEL2 @@ -4888,8 +4971,8 @@ if STM32_TIM15_CHANNEL2 config STM32_TIM15_CH2MODE int "TIM15 Channel 2 Mode" default 0 - range 0 3 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 3 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4913,11 +4996,43 @@ config STM32_TIM15_CHANNEL If TIM15 is enabled for PWM usage, you also need specifies the timer output channel {1,2} +if STM32_TIM15_CHANNEL = 1 + +config STM32_TIM15_CH1OUT + bool "TIM15 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +config STM32_TIM15_CH1NOUT + bool "TIM15 Channel 1 Complementary Output" + default n + ---help--- + Enables channel 1 Complementary Output. + +endif # STM32_TIM15_CHANNEL = 1 + +if STM32_TIM15_CHANNEL = 2 + +config STM32_TIM15_CH2OUT + bool "TIM15 Channel 2 Output" + default n + ---help--- + Enables channel 2 output. + +config STM32_TIM15_CH2NOUT + bool "TIM15 Channel 2 Complementary Output" + default n + ---help--- + Enables channel 2 Complementary Output. + +endif # STM32_TIM15_CHANNEL = 2 + config STM32_TIM15_CHMODE int "TIM15 Channel Mode" default 0 - range 0 3 if STM32_STM32F30XX - range 0 1 if !STM32_STM32F30XX + range 0 3 if STM32_HAVE_IP_TIMERS_V2 + range 0 1 if !STM32_HAVE_IP_TIMERS_V2 ---help--- Specifies the channel mode. @@ -4939,6 +5054,27 @@ config STM32_TIM16_PWM if STM32_TIM16_PWM +config STM32_TIM16_LOCK + int "TIM16 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 16 lock level configuration + +config STM32_TIM16_TDTS + int "TIM16 t_DTS division" + default 0 + range 0 2 + ---help--- + Timer 16 dead-time and sampling clock (t_DTS) division + +config STM32_TIM16_DEADTIME + int "TIM16 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 16 initial dead-time + if STM32_PWM_MULTICHAN config STM32_TIM16_CHANNEL1 @@ -4976,6 +5112,16 @@ config STM32_TIM16_CHANNEL If TIM16 is enabled for PWM usage, you also need specifies the timer output channel {1} +if STM32_TIM16_CHANNEL = 1 + +config STM32_TIM16_CH1OUT + bool "TIM16 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM16_CHANNEL = 1 + config STM32_TIM16_CHMODE int "TIM16 Channel Mode" default 0 @@ -5001,6 +5147,27 @@ config STM32_TIM17_PWM if STM32_TIM17_PWM +config STM32_TIM17_LOCK + int "TIM17 Lock Level Configuration" + default 0 + range 0 3 + ---help--- + Timer 17 lock level configuration + +config STM32_TIM17_TDTS + int "TIM17 t_DTS Division" + default 0 + range 0 2 + ---help--- + Timer 17 dead-time and sampling clock (t_DTS) division + +config STM32_TIM17_DEADTIME + int "TIM17 Initial Dead-time" + default 0 + range 0 255 + ---help--- + Timer 17 initial dead-time + if STM32_PWM_MULTICHAN config STM32_TIM17_CHANNEL1 @@ -5038,6 +5205,16 @@ config STM32_TIM17_CHANNEL If TIM17 is enabled for PWM usage, you also need specifies the timer output channel {1} +if STM32_TIM17_CHANNEL = 1 + +config STM32_TIM17_CH1OUT + bool "TIM17 Channel 1 Output" + default n + ---help--- + Enables channel 1 output. + +endif # STM32_TIM17_CHANNEL = 1 + config STM32_TIM17_CHMODE int "TIM17 Channel Mode" default 0 @@ -5058,6 +5235,45 @@ config STM32_PWM_MULTICHAN Specifies that the PWM driver supports multiple output channels per timer. +config STM32_TIM_PWM_TRGO + bool "TIM1 PWM TRGO" + default n + depends on STM32_TIM1 + ---help--- + Enable TRGO support for PWM TIM1 driver + +config STM32_TIM1_PWM_ADC + bool "TIM1 PWM ADC " + default n + depends on STM32_TIM1 && STM32_ADC && STM32_TIM1_PWM + ---help--- + ADC trigger with TIM1 configured as PWM source + +choice + prompt "Select TIM1 PWM ADC channel" + default STM32_TIM1_PWM_ADC1 + depends on STM32_TIM1_PWM_ADC + +config STM32_TIM1_PWM_ADC1 + bool "TIM1 PWM ADC1" + depends on STM32_ADC1 + ---help--- + Trigger ADC1 with PWM configured TIM1 + +config STM32_TIM1_PWM_ADC2 + bool "TIM1 PWM ADC2" + depends on STM32_ADC2 + ---help--- + Trigger ADC2 with PWM configured TIM1 + +config STM32_TIM1_PWM_ADC3 + bool "TIM1 PWM ADC3" + depends on STM32_ADC3 + ---help--- + Trigger ADC3 with PWM configured TIM1 + +endchoice + config STM32_TIM1_ADC bool "TIM1 ADC" default n @@ -5330,7 +5546,7 @@ config STM32_ADC1_TIMTRIG int "ADC1 Timer Trigger" default 0 range 0 4 - depends on STM32_HAVE_ADC1_TIMER + depends on STM32_HAVE_ADC1_TIMER || STM32_TIM1_PWM_ADC1 ---help--- Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO @@ -5345,7 +5561,7 @@ config STM32_ADC2_TIMTRIG int "ADC2 Timer Trigger" default 0 range 0 4 - depends on STM32_HAVE_ADC2_TIMER + depends on STM32_HAVE_ADC2_TIMER || STM32_TIM1_PWM_ADC2 ---help--- Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO @@ -5360,7 +5576,7 @@ config STM32_ADC3_TIMTRIG int "ADC3 Timer Trigger" default 0 range 0 4 - depends on STM32_HAVE_ADC3_TIMER + depends on STM32_HAVE_ADC3_TIMER || STM32_TIM1_PWM_ADC3 ---help--- Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO @@ -5801,7 +6017,7 @@ endchoice config STM32_TIM1_CAP bool "TIM1 Capture" default n - depends on STM32_HAVE_TIM1 + depends on STM32_TIM1 ---help--- Reserve timer 1 for use by Capture @@ -5811,7 +6027,7 @@ config STM32_TIM1_CAP config STM32_TIM2_CAP bool "TIM2 Capture" default n - depends on STM32_HAVE_TIM2 + depends on STM32_TIM2 ---help--- Reserve timer 2 for use by Capture @@ -5821,7 +6037,7 @@ config STM32_TIM2_CAP config STM32_TIM3_CAP bool "TIM3 Capture" default n - depends on STM32_HAVE_TIM3 + depends on STM32_TIM3 ---help--- Reserve timer 3 for use by Capture @@ -5831,7 +6047,7 @@ config STM32_TIM3_CAP config STM32_TIM4_CAP bool "TIM4 Capture" default n - depends on STM32_HAVE_TIM4 + depends on STM32_TIM4 ---help--- Reserve timer 4 for use by Capture @@ -5841,7 +6057,7 @@ config STM32_TIM4_CAP config STM32_TIM5_CAP bool "TIM5 Capture" default n - depends on STM32_HAVE_TIM5 + depends on STM32_TIM5 ---help--- Reserve timer 5 for use by Capture @@ -5851,7 +6067,7 @@ config STM32_TIM5_CAP config STM32_TIM8_CAP bool "TIM8 Capture" default n - depends on STM32_HAVE_TIM8 + depends on STM32_TIM8 ---help--- Reserve timer 8 for use by Capture @@ -5861,7 +6077,7 @@ config STM32_TIM8_CAP config STM32_TIM9_CAP bool "TIM9 Capture" default n - depends on STM32_HAVE_TIM9 + depends on STM32_TIM9 ---help--- Reserve timer 9 for use by Capture @@ -5871,7 +6087,7 @@ config STM32_TIM9_CAP config STM32_TIM10_CAP bool "TIM10 Capture" default n - depends on STM32_HAVE_TIM10 + depends on STM32_TIM10 ---help--- Reserve timer 10 for use by Capture @@ -5881,7 +6097,7 @@ config STM32_TIM10_CAP config STM32_TIM11_CAP bool "TIM11 Capture" default n - depends on STM32_HAVE_TIM11 + depends on STM32_TIM11 ---help--- Reserve timer 11 for use by Capture @@ -5891,7 +6107,7 @@ config STM32_TIM11_CAP config STM32_TIM12_CAP bool "TIM12 Capture" default n - depends on STM32_HAVE_TIM12 + depends on STM32_TIM12 ---help--- Reserve timer 12 for use by Capture @@ -5901,7 +6117,7 @@ config STM32_TIM12_CAP config STM32_TIM13_CAP bool "TIM13 Capture" default n - depends on STM32_HAVE_TIM13 + depends on STM32_TIM13 ---help--- Reserve timer 13 for use by Capture @@ -5911,13 +6127,721 @@ config STM32_TIM13_CAP config STM32_TIM14_CAP bool "TIM14 Capture" default n - depends on STM32_HAVE_TIM14 + depends on STM32_TIM14 ---help--- Reserve timer 14 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 STM32_TIM1_CH1POL + int "TIM1 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH1OUT + ---help--- + TIM1 Channel 1 output polarity + +config STM32_TIM1_CH1IDLE + int "TIM1 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH1OUT + ---help--- + TIM1 Channel 1 output IDLE + +config STM32_TIM1_CH1NPOL + int "TIM1 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH1NOUT + ---help--- + TIM1 Channel 1 Complementary Output polarity + +config STM32_TIM1_CH1NIDLE + int "TIM1 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH1NOUT + ---help--- + TIM1 Channel 1 Complementary Output IDLE + +config STM32_TIM1_CH2POL + int "TIM1 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH2OUT + ---help--- + TIM1 Channel 2 output polarity + +config STM32_TIM1_CH2IDLE + int "TIM1 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH2OUT + ---help--- + TIM1 Channel 2 output IDLE + +config STM32_TIM1_CH2NPOL + int "TIM1 Channel 2 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH2NOUT + ---help--- + TIM1 Channel 2 Complementary Output polarity + +config STM32_TIM1_CH2NIDLE + int "TIM1 Channel 2 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH2NOUT + ---help--- + TIM1 Channel 2 Complementary Output IDLE + +config STM32_TIM1_CH3POL + int "TIM1 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH3OUT + ---help--- + TIM1 Channel 3 output polarity + +config STM32_TIM1_CH3IDLE + int "TIM1 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH3OUT + ---help--- + TIM1 Channel 3 output IDLE + +config STM32_TIM1_CH3NPOL + int "TIM1 Channel 3 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH3NOUT + ---help--- + TIM1 Channel 3 Complementary Output polarity + +config STM32_TIM1_CH3NIDLE + int "TIM1 Channel 3 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH3NOUT + ---help--- + TIM1 Channel 3 Complementary Output IDLE + +config STM32_TIM1_CH4POL + int "TIM1 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM1_CH4OUT + ---help--- + TIM1 Channel 4 output polarity + +config STM32_TIM1_CH4IDLE + int "TIM1 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM1_CH4OUT + ---help--- + TIM1 Channel 4 output IDLE + +config STM32_TIM2_CH1POL + int "TIM2 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM2_CH1OUT + ---help--- + TIM2 Channel 1 output polarity + +config STM32_TIM2_CH1IDLE + int "TIM2 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM2_CH1OUT + ---help--- + TIM2 Channel 1 output IDLE + +config STM32_TIM2_CH2POL + int "TIM2 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM2_CH2OUT + ---help--- + TIM2 Channel 2 output polarity + +config STM32_TIM2_CH2IDLE + int "TIM2 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM2_CH2OUT + ---help--- + TIM2 Channel 2 output IDLE + +config STM32_TIM2_CH3POL + int "TIM2 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM2_CH3OUT + ---help--- + TIM2 Channel 3 output polarity + +config STM32_TIM2_CH3IDLE + int "TIM2 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM2_CH3OUT + ---help--- + TIM2 Channel 3 output IDLE + +config STM32_TIM2_CH4POL + int "TIM2 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM2_CH4OUT + ---help--- + TIM2 Channel 4 output polarity + +config STM32_TIM2_CH4IDLE + int "TIM2 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM2_CH4OUT + ---help--- + TIM2 Channel 4 output IDLE + +config STM32_TIM3_CH1POL + int "TIM3 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM3_CH1OUT + ---help--- + TIM3 Channel 1 output polarity + +config STM32_TIM3_CH1IDLE + int "TIM3 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM3_CH1OUT + ---help--- + TIM3 Channel 1 output IDLE + +config STM32_TIM3_CH2POL + int "TIM3 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM3_CH2OUT + ---help--- + TIM3 Channel 2 output polarity + +config STM32_TIM3_CH2IDLE + int "TIM3 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM3_CH2OUT + ---help--- + TIM3 Channel 2 output IDLE + +config STM32_TIM3_CH3POL + int "TIM3 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM3_CH3OUT + ---help--- + TIM3 Channel 3 output polarity + +config STM32_TIM3_CH3IDLE + int "TIM3 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM3_CH3OUT + ---help--- + TIM3 Channel 3 output IDLE + +config STM32_TIM3_CH4POL + int "TIM3 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM3_CH4OUT + ---help--- + TIM3 Channel 4 output polarity + +config STM32_TIM3_CH4IDLE + int "TIM3 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM3_CH4OUT + ---help--- + TIM3 Channel 4 output IDLE + +config STM32_TIM4_CH1POL + int "TIM4 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM4_CH1OUT + ---help--- + TIM4 Channel 1 output polarity + +config STM32_TIM4_CH1IDLE + int "TIM4 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM4_CH1OUT + ---help--- + TIM4 Channel 1 output IDLE + +config STM32_TIM4_CH2POL + int "TIM4 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM4_CH2OUT + ---help--- + TIM4 Channel 2 output polarity + +config STM32_TIM4_CH2IDLE + int "TIM4 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM4_CH2OUT + ---help--- + TIM4 Channel 2 output IDLE + +config STM32_TIM4_CH3POL + int "TIM4 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM4_CH3OUT + ---help--- + TIM4 Channel 3 output polarity + +config STM32_TIM4_CH3IDLE + int "TIM4 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM4_CH3OUT + ---help--- + TIM4 Channel 3 output IDLE + +config STM32_TIM4_CH4POL + int "TIM4 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM4_CH4OUT + ---help--- + TIM4 Channel 4 output polarity + +config STM32_TIM4_CH4IDLE + int "TIM4 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM4_CH4OUT + ---help--- + TIM4 Channel 4 output IDLE + +config STM32_TIM5_CH1POL + int "TIM5 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM5_CH1OUT + ---help--- + TIM5 Channel 1 output polarity + +config STM32_TIM5_CH1IDLE + int "TIM5 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM5_CH1OUT + ---help--- + TIM5 Channel 1 output IDLE + +config STM32_TIM5_CH2POL + int "TIM5 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM5_CH2OUT + ---help--- + TIM5 Channel 2 output polarity + +config STM32_TIM5_CH2IDLE + int "TIM5 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM5_CH2OUT + ---help--- + TIM5 Channel 2 output IDLE + +config STM32_TIM5_CH3POL + int "TIM5 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM5_CH3OUT + ---help--- + TIM5 Channel 3 output polarity + +config STM32_TIM5_CH3IDLE + int "TIM5 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM5_CH3OUT + ---help--- + TIM5 Channel 3 output IDLE + +config STM32_TIM5_CH4POL + int "TIM5 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM5_CH4OUT + ---help--- + TIM5 Channel 4 output polarity + +config STM32_TIM5_CH4IDLE + int "TIM5 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM5_CH4OUT + ---help--- + TIM5 Channel 4 output IDLE + +config STM32_TIM8_CH1POL + int "TIM8 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH1OUT + ---help--- + TIM8 Channel 1 output polarity + +config STM32_TIM8_CH1IDLE + int "TIM8 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH1OUT + ---help--- + TIM8 Channel 1 output IDLE + +config STM32_TIM8_CH1NPOL + int "TIM8 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH1NOUT + ---help--- + TIM8 Channel 1 Complementary Output polarity + +config STM32_TIM8_CH1NIDLE + int "TIM8 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH1NOUT + ---help--- + TIM8 Channel 1 Complementary Output IDLE + +config STM32_TIM8_CH2POL + int "TIM8 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH2OUT + ---help--- + TIM8 Channel 2 output polarity + +config STM32_TIM8_CH2IDLE + int "TIM8 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH2OUT + ---help--- + TIM8 Channel 2 output IDLE + +config STM32_TIM8_CH2NPOL + int "TIM8 Channel 2 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH2NOUT + ---help--- + TIM8 Channel 2 Complementary Output polarity + +config STM32_TIM8_CH2NIDLE + int "TIM8 Channel 2 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH2NOUT + ---help--- + TIM8 Channel 2 Complementary Output IDLE + +config STM32_TIM8_CH3POL + int "TIM8 Channel 3 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH3OUT + ---help--- + TIM8 Channel 3 output polarity + +config STM32_TIM8_CH3IDLE + int "TIM8 Channel 3 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH3OUT + ---help--- + TIM8 Channel 3 output IDLE + +config STM32_TIM8_CH3NPOL + int "TIM8 Channel 3 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH3NOUT + ---help--- + TIM8 Channel 3 Complementary Output polarity + +config STM32_TIM8_CH3NIDLE + int "TIM8 Channel 3 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH3NOUT + ---help--- + TIM8 Channel 3 Complementary Output IDLE + +config STM32_TIM8_CH4POL + int "TIM8 Channel 4 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM8_CH4OUT + ---help--- + TIM8 Channel 4 output polarity + +config STM32_TIM8_CH4IDLE + int "TIM8 Channel 4 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM8_CH4OUT + ---help--- + TIM8 Channel 4 output IDLE + +config STM32_TIM9_CH1POL + int "TIM9 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM9_CH1OUT + ---help--- + TIM9 Channel 1 output polarity + +config STM32_TIM9_CH1IDLE + int "TIM9 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM9_CH1OUT + ---help--- + TIM9 Channel 1 output IDLE + +config STM32_TIM9_CH2POL + int "TIM9 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM9_CH2OUT + ---help--- + TIM9 Channel 2 output polarity + +config STM32_TIM9_CH2IDLE + int "TIM9 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM9_CH2OUT + ---help--- + TIM9 Channel 2 output IDLE + +config STM32_TIM10_CH1POL + int "TIM10 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM10_CH1OUT + ---help--- + TIM10 Channel 1 output polarity + +config STM32_TIM10_CH1IDLE + int "TIM10 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM10_CH1OUT + ---help--- + TIM10 Channel 1 output IDLE + +config STM32_TIM11_CH1POL + int "TIM11 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM11_CH1OUT + ---help--- + TIM11 Channel 1 output polarity + +config STM32_TIM11_CH1IDLE + int "TIM11 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM11_CH1OUT + ---help--- + TIM11 Channel 1 output IDLE + +config STM32_TIM12_CH1POL + int "TIM12 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM12_CH1OUT + ---help--- + TIM12 Channel 1 output polarity + +config STM32_TIM12_CH1IDLE + int "TIM12 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM12_CH1OUT + ---help--- + TIM12 Channel 1 output IDLE + +config STM32_TIM12_CH2POL + int "TIM12 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM12_CH2OUT + ---help--- + TIM12 Channel 2 output polarity + +config STM32_TIM12_CH2IDLE + int "TIM12 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM12_CH2OUT + ---help--- + TIM12 Channel 2 output IDLE + +config STM32_TIM13_CH1POL + int "TIM13 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM13_CH1OUT + ---help--- + TIM13 Channel 1 output polarity + +config STM32_TIM13_CH1IDLE + int "TIM13 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM13_CH1OUT + ---help--- + TIM13 Channel 1 output IDLE + +config STM32_TIM14_CH1POL + int "TIM14 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM14_CH1OUT + ---help--- + TIM14 Channel 1 output polarity + +config STM32_TIM14_CH1IDLE + int "TIM14 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM14_CH1OUT + ---help--- + TIM14 Channel 1 output IDLE + +config STM32_TIM15_CH1POL + int "TIM15 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM15_CH1OUT + ---help--- + TIM15 Channel 1 output polarity + +config STM32_TIM15_CH1IDLE + int "TIM15 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM15_CH1OUT + ---help--- + TIM15 Channel 1 output IDLE + +config STM32_TIM15_CH1NPOL + int "TIM15 Channel 1 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM15_CH1NOUT + ---help--- + TIM15 Channel 1 Complementary Output polarity + +config STM32_TIM15_CH1NIDLE + int "TIM15 Channel 1 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM15_CH1NOUT + ---help--- + TIM15 Channel 1 Complementary Output IDLE + +config STM32_TIM15_CH2POL + int "TIM15 Channel 2 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM15_CH2OUT + ---help--- + TIM15 Channel 2 output polarity + +config STM32_TIM15_CH2IDLE + int "TIM15 Channel 2 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM15_CH2OUT + ---help--- + TIM15 Channel 2 output IDLE + +config STM32_TIM15_CH2NPOL + int "TIM15 Channel 2 Complementary Output polarity" + default 0 + range 0 1 + depends on STM32_TIM15_CH2NOUT + ---help--- + TIM15 Channel 2 Complementary Output polarity + +config STM32_TIM15_CH2NIDLE + int "TIM15 Channel 2 Complementary Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM15_CH2NOUT + ---help--- + TIM15 Channel 2 Complementary Output IDLE + +config STM32_TIM16_CH1POL + int "TIM16 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM16_CH1OUT + ---help--- + TIM16 Channel 1 output polarity + +config STM32_TIM16_CH1IDLE + int "TIM16 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM16_CH1OUT + ---help--- + TIM16 Channel 1 output IDLE + +config STM32_TIM17_CH1POL + int "TIM17 Channel 1 Output polarity" + default 0 + range 0 1 + depends on STM32_TIM17_CH1OUT + ---help--- + TIM17 Channel 1 output polarity + +config STM32_TIM17_CH1IDLE + int "TIM17 Channel 1 Output IDLE" + default 0 + range 0 1 + depends on STM32_TIM17_CH1OUT + ---help--- + TIM17 Channel 1 output IDLE + +endmenu #STM32 TIMx Outputs Configuration + endmenu # Timer Configuration menu "HRTIM Configuration" diff --git a/arch/arm/src/stm32/chip/stm32_tim.h b/arch/arm/src/stm32/chip/stm32_tim.h index c115dbb43a..4b1c9abbf8 100644 --- a/arch/arm/src/stm32/chip/stm32_tim.h +++ b/arch/arm/src/stm32/chip/stm32_tim.h @@ -44,6 +44,39 @@ * Pre-processor Definitions ****************************************************************************************************/ +/* TIM version **************************************************************************************/ + +/* Chip has extended version of ADV Timers (F3/F7/H7/L4/L4+): + - CCMR3, CCR5 and CCR6 registers + - OC5 and OC6 + - 32-bit CCMR register + - UIFREMAP bit in CR1 register + - TRGO2 configuration in CR2 register + - OCCS bit and 4-bit SMS in SMCR register + + Chip has extended version of General Timers 2-5 (F3/F7/H7/L4/L4+): + - UIFREMAP bit in CR1 register + - 4-bit SMS in SMCR register +*/ + +#ifdef CONFIG_STM32_HAVE_IP_TIMERS_V2 +# define HAVE_IP_TIMERS_V2 +#endif + +/* TIM16 has OR register (F3/L4) */ + +#ifdef CONFIG_STM32_STM32F30XX +# define HAVE_TIM16_OR +#endif + +/* General Timers have CCxNP bits (not in F1) */ + +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F33XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F4XXX) +# define HAVE_GTIM_CCXNP +#endif + /* Register Offsets *********************************************************************************/ /* Basic Timers - TIM6 and TIM7 */ @@ -96,7 +129,7 @@ * Only available in the STM32 F1 Value Line and the STM32 F3 family. */ -#define STM32_GTIM_RCR_OFFSET 0x002c /* Repetition counter register (TIM16/TIM17) */ +#define STM32_GTIM_RCR_OFFSET 0x0030 /* Repetition counter register (TIM16/TIM17) */ #define STM32_GTIM_BDTR_OFFSET 0x0044 /* Break and dead-time register (TIM16/TIM17) */ /* Advanced Timers - TIM1 and TIM8 */ @@ -124,7 +157,7 @@ /* *Note that many of the above registers are 32-bits wide on the F3 */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define STM32_ATIM_CCMR3_OFFSET 0x0054 /* Capture/compare mode register 3 (32-bit) */ # define STM32_ATIM_CCR5_OFFSET 0x0058 /* Capture/compare register 4 (16-bit) */ # define STM32_ATIM_CCR6_OFFSET 0x005c /* Capture/compare register 4 (32-bit) */ @@ -155,7 +188,7 @@ # define STM32_TIM1_BDTR (STM32_TIM1_BASE+STM32_ATIM_BDTR_OFFSET) # define STM32_TIM1_DCR (STM32_TIM1_BASE+STM32_ATIM_DCR_OFFSET) # define STM32_TIM1_DMAR (STM32_TIM1_BASE+STM32_ATIM_DMAR_OFFSET) -# ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define STM32_TIM1_CCMR3 (STM32_TIM1_BASE+STM32_ATIM_CCMR3_OFFSET) # define STM32_TIM1_CCR5 (STM32_TIM1_BASE+STM32_ATIM_CCR5_OFFSET) # define STM32_TIM1_CCR6 (STM32_TIM1_BASE+STM32_ATIM_CCR6_OFFSET) @@ -183,7 +216,7 @@ # define STM32_TIM8_BDTR (STM32_TIM8_BASE+STM32_ATIM_BDTR_OFFSET) # define STM32_TIM8_DCR (STM32_TIM8_BASE+STM32_ATIM_DCR_OFFSET) # define STM32_TIM8_DMAR (STM32_TIM8_BASE+STM32_ATIM_DMAR_OFFSET) -# ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define STM32_TIM8_CCMR3 (STM32_TIM8_BASE+STM32_ATIM_CCMR3_OFFSET) # define STM32_TIM8_CCR5 (STM32_TIM8_BASE+STM32_ATIM_CCR5_OFFSET) # define STM32_TIM8_CCR6 (STM32_TIM8_BASE+STM32_ATIM_CCR6_OFFSET) @@ -471,8 +504,7 @@ # define ATIM_CR1_TCKINT (0 << ATIM_CR1_CKD_SHIFT) /* 00: tDTS=tCK_INT */ # define ATIM_CR1_2TCKINT (1 << ATIM_CR1_CKD_SHIFT) /* 01: tDTS=2*tCK_INT */ # define ATIM_CR1_4TCKINT (2 << ATIM_CR1_CKD_SHIFT) /* 10: tDTS=4*tCK_INT */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ #endif @@ -499,8 +531,7 @@ #define ATIM_CR2_OIS3 (1 << 12) /* Bit 12: Output Idle state 3 (OC3 output) */ #define ATIM_CR2_OIS3N (1 << 13) /* Bit 13: Output Idle state 3 (OC3N output) */ #define ATIM_CR2_OIS4 (1 << 14) /* Bit 14: Output Idle state 4 (OC4 output) */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CR2_OIS5 (1 << 16) /* Bit 16: OOutput Idle state 5 (OC5 output) */ # define ATIM_CR2_OIS6 (1 << 18) /* Bit 18: Output Idle state 6 (OC6 output) */ # define ATIM_CR2_MMS2_SHIFT (20) /* Bits 20-23: Master Mode Selection 2 */ @@ -535,7 +566,7 @@ # define ATIM_SMCR_GATED (5 << ATIM_SMCR_SMS_SHIFT) /* 101: Gated Mode */ # define ATIM_SMCR_TRIGGER (6 << ATIM_SMCR_SMS_SHIFT) /* 110: Trigger Mode */ # define ATIM_SMCR_EXTCLK1 (7 << ATIM_SMCR_SMS_SHIFT) /* 111: External Clock Mode 1 */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_SMCR_OCCS (1 << 3) /* Bit 3: OCREF clear selection */ #endif #define ATIM_SMCR_TS_SHIFT (4) /* Bits 4-6: Trigger selection */ @@ -575,7 +606,7 @@ # define ATIM_SMCR_ETRPd8 (3 << ATIM_SMCR_ETPS_SHIFT) /* 11: ETRP frequency divided by 8 */ #define ATIM_SMCR_ECE (1 << 14) /* Bit 14: External clock enable */ #define ATIM_SMCR_ETP (1 << 15) /* Bit 15: External trigger polarity */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_SMCR_SMS (1 << 16) /* Bit 16: Slave mode selection - bit 3 */ #endif @@ -586,27 +617,15 @@ #define ATIM_DIER_CC2IE (1 << 2) /* Bit 2: Capture/Compare 2 interrupt enable */ #define ATIM_DIER_CC3IE (1 << 3) /* Bit 3: Capture/Compare 3 interrupt enable */ #define ATIM_DIER_CC4IE (1 << 4) /* Bit 4: Capture/Compare 4 interrupt enable */ - -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) -# define ATIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable */ -#endif - +#define ATIM_DIER_COMIE (1 << 5) /* Bit 5: COM interrupt enable */ #define ATIM_DIER_TIE (1 << 6) /* Bit 6: Trigger interrupt enable */ - -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) -# define ATIM_DIER_BIE (1 << 7) /* Bit 7: Break interrupt enable */ -#endif - +#define ATIM_DIER_BIE (1 << 7) /* Bit 7: Break interrupt enable */ #define ATIM_DIER_UDE (1 << 8) /* Bit 8: Update DMA request enable */ #define ATIM_DIER_CC1DE (1 << 9) /* Bit 9: Capture/Compare 1 DMA request enable */ #define ATIM_DIER_CC2DE (1 << 10) /* Bit 10: Capture/Compare 2 DMA request enable */ #define ATIM_DIER_CC3DE (1 << 11) /* Bit 11: Capture/Compare 3 DMA request enable */ #define ATIM_DIER_CC4DE (1 << 12) /* Bit 12: Capture/Compare 4 DMA request enable */ - -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) -# define ATIM_DIER_COMDE (1 << 13) /* Bit 13: COM DMA request enable */ -#endif - +#define ATIM_DIER_COMDE (1 << 13) /* Bit 13: COM DMA request enable */ #define ATIM_DIER_TDE (1 << 14) /* Bit 14: Trigger DMA request enable */ /* Status register */ @@ -618,20 +637,15 @@ #define ATIM_SR_CC4IF (1 << 4) /* Bit 4: Capture/Compare 4 interrupt Flag */ #define ATIM_SR_COMIF (1 << 5) /* Bit 5: COM interrupt Flag */ #define ATIM_SR_TIF (1 << 6) /* Bit 6: Trigger interrupt Flag */ - -#if defined(CONFIG_STM32_STM32F10XX) -# define ATIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt Flag */ -#elif defined(CONFIG_STM32_STM32F30XX) -# define ATIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt Flag */ +#define ATIM_SR_BIF (1 << 7) /* Bit 7: Break interrupt Flag */ +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_SR_B2IF (1 << 8) /* Bit 8: Break 2 interrupt Flag */ #endif - #define ATIM_SR_CC1OF (1 << 9) /* Bit 9: Capture/Compare 1 Overcapture Flag */ #define ATIM_SR_CC2OF (1 << 10) /* Bit 10: Capture/Compare 2 Overcapture Flag */ #define ATIM_SR_CC3OF (1 << 11) /* Bit 11: Capture/Compare 3 Overcapture Flag */ #define ATIM_SR_CC4OF (1 << 12) /* Bit 12: Capture/Compare 4 Overcapture Flag */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_SR_CC5IF (1 << 16) /* Bit 16: Compare 5 interrupt flag */ # define ATIM_SR_CC6IF (1 << 17) /* Bit 17: Compare 6 interrupt flag */ #endif @@ -643,17 +657,10 @@ #define ATIM_EGR_CC2G (1 << 2) /* Bit 2: Capture/Compare 2 Generation */ #define ATIM_EGR_CC3G (1 << 3) /* Bit 3: Capture/Compare 3 Generation */ #define ATIM_EGR_CC4G (1 << 4) /* Bit 4: Capture/Compare 4 Generation */ - -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) -# define ATIM_EGR_COMG (1 << 5) /* Bit 5: Capture/Compare Control Update Generation */ -#endif - +#define ATIM_EGR_COMG (1 << 5) /* Bit 5: Capture/Compare Control Update Generation */ #define ATIM_EGR_TG (1 << 6) /* Bit 6: Trigger Generation */ - -#if defined(CONFIG_STM32_STM32F10XX) -# define ATIM_EGR_BG (1 << 7) /* Bit 7: Break Generation */ -#elif defined(CONFIG_STM32_STM32F30XX) -# define ATIM_EGR_BG (1 << 7) /* Bit 7: Break Generation */ +#define ATIM_EGR_BG (1 << 7) /* Bit 7: Break Generation */ +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_EGR_B2G (1 << 8) /* Bit 8: Break 2 Generation */ #endif @@ -677,8 +684,7 @@ #define ATIM_CCMR1_OC2M_MASK (7 << ATIM_CCMR1_OC2M_SHIFT) /* (See common (unshifted) bit field definitions below) */ #define ATIM_CCMR1_OC2CE (1 << 15) /* Bit 15: Output Compare 2 Clear Enable */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CCMR1_OC1M (1 << 16) /* Bit 16: Output Compare 1 mode - bit 3 */ # define ATIM_CCMR1_OC2M (1 << 24) /* Bit 24: Output Compare 2 mode - bit 3 */ #endif @@ -768,8 +774,7 @@ #define ATIM_CCMR2_OC4M_MASK (7 << ATIM_CCMR2_OC4M_SHIFT) /* (See common (unshifted) bit field definitions above) */ #define ATIM_CCMR2_OC4CE (1 << 15) /* Bit 15: Output Compare 4 Clear Enable */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CCMR2_OC3M (1 << 16) /* Bit 16: Output Compare 3 mode - bit 3 */ # define ATIM_CCMR2_OC4M (1 << 24) /* Bit 24: Output Compare 4 mode - bit 3 */ #endif @@ -793,7 +798,7 @@ /* Capture/compare mode register 3 -- Output compare mode */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CCMR3_OC5FE (1 << 2) /* Bit 2: Output Compare 5 Fast enable */ # define ATIM_CCMR3_OC5PE (1 << 3) /* Bit 3: Output Compare 5 Preload enable */ # define ATIM_CCMR3_OC5M_SHIFT (4) /* Bits 6-4: Output Compare 5 Mode */ @@ -806,7 +811,6 @@ # define ATIM_CCMR3_OC6M_MASK (7 << ATIM_CCMR3_OC6M_SHIFT) /* (See common (unshifted) bit field definitions below) */ # define ATIM_CCMR3_OC6CE (1 << 15) /* Bit 15: Output Compare 7 Clear Enable */ - # define ATIM_CCMR3_OC5M (1 << 16) /* Bit 16: Output Compare 5 mode - bit 3 */ # define ATIM_CCMR3_OC6M (1 << 24) /* Bit 24: Output Compare 6 mode - bit 3 */ #endif @@ -827,13 +831,11 @@ #define ATIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 Complementary output polarity */ #define ATIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable */ #define ATIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity */ - -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F4XXX) || \ - defined(CONFIG_STM32_STM32L15XX) -# define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ -#elif defined(CONFIG_STM32_STM32F30XX) -# define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ +#define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity + * NOTE: Some ST documents show CC4NP bit but there is + * no CC4N output, so it does not make sense! + */ +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CCER_CC5E (1 << 16) /* Bit 16: Capture/Compare 5 output enable */ # define ATIM_CCER_CC5P (1 << 17) /* Bit 17: Capture/Compare 5 output Polarity */ # define ATIM_CCER_CC6E (1 << 20) /* Bit 20: Capture/Compare 6 output enable */ @@ -844,28 +846,25 @@ #define ATIM_CNT_SHIFT (0) /* Bits 0-15: Timer counter value */ #define ATIM_CNT_MASK (0xffff << ATIM_CNT_SHIFT) - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CCER_UIFCPY (1 << 31) /* Bit 31: UIF copy */ #endif /* Repetition counter register */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_RCR_REP_SHIFT (0) /* Bits 0-15: Repetition Counter Value */ # define ATIM_RCR_REP_MASK (0xffff << ATIM_RCR_REP_SHIFT) - # define ATIM_RCR_REP_MAX 32768 /* REVISIT */ #else # define ATIM_RCR_REP_SHIFT (0) /* Bits 0-7: Repetition Counter Value */ # define ATIM_RCR_REP_MASK (0xff << ATIM_RCR_REP_SHIFT) - # define ATIM_RCR_REP_MAX 128 #endif /* Capture/compare registers (CCR) */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_CCR5_GC5C1 (1 << 29) /* Bit 29: Group Channel 5 and Channel 1 */ # define ATIM_CCR5_GC5C2 (1 << 30) /* Bit 30: Group Channel 5 and Channel 2 */ # define ATIM_CCR5_GC5C3 (1 << 31) /* Bit 31: Group Channel 5 and Channel 3 */ @@ -889,8 +888,7 @@ #define ATIM_BDTR_BKP (1 << 13) /* Bit 13: Break Polarity */ #define ATIM_BDTR_AOE (1 << 14) /* Bit 14: Automatic Output enable */ #define ATIM_BDTR_MOE (1 << 15) /* Bit 15: Main Output enable */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define ATIM_BDTR_BKF_SHIFT (16) /* Bits 16-19: Break filter */ # define ATIM_BDTR_BKF_MASK (15 << ATIM_BDTR_BKF_SHIFT) # define ATIM_BDTR_BKF_NOFILT (0 << ATIM_BDTR_BKF_SHIFT) /* 0000: No filter, BRK acts asynchronously */ @@ -958,8 +956,7 @@ # define GTIM_CR1_TCKINT (0 << GTIM_CR1_CKD_SHIFT) /* 00: tDTS = tCK_INT */ # define GTIM_CR1_2TCKINT (1 << GTIM_CR1_CKD_SHIFT) /* 01: tDTS = 2 x tCK_INT */ # define GTIM_CR1_4TCKINT (2 << GTIM_CR1_CKD_SHIFT) /* 10: tDTS = 4 x tCK_INT */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define GTIM_CR1_UIFREMAP (1 << 11) /* Bit 11: UIF status bit remapping */ #endif @@ -1032,7 +1029,7 @@ # define GTIM_SMCR_ETRPd8 (3 << GTIM_SMCR_ETPS_SHIFT) /* 11: ETRP frequency divided by 8 */ #define GTIM_SMCR_ECE (1 << 14) /* Bit 14: External Clock enable */ #define GTIM_SMCR_ETP (1 << 15) /* Bit 15: External Trigger Polarity */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define GTIM_SMCR_SMS (1 << 16) /* Bit 16: Slave mode selection - bit 3 */ #endif @@ -1100,8 +1097,7 @@ #define GTIM_CCMR1_OC2M_MASK (7 << GTIM_CCMR1_OC2M_SHIFT) /* (See common CCMR Output Compare Mode definitions below) */ #define GTIM_CCMR1_OC2CE (1 << 15) /* Bit 15: Output Compare 2 Clear Enable */ - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define GTIM_CCMR1_OC1M (1 << 16) /* Bit 16: Output Compare 1 mode - bit 3 */ # define GTIM_CCMR1_OC2M (1 << 24) /* Bit 24: Output Compare 2 mode - bit 3 */ #endif @@ -1205,30 +1201,40 @@ #define GTIM_CCMR2_IC4F_MASK (0x0f << GTIM_CCMR2_IC4F_SHIFT) /* (See common CCMR Input Capture Filter definitions below) */ -/* Capture/compare enable register (TIM1 and TIM8, TIM2-5 and TIM9-14) */ +/* Capture/compare enable register (TIM2-5 and TIM9-14) */ #define GTIM_CCER_CC1E (1 << 0) /* Bit 0: Capture/Compare 1 output enable */ #define GTIM_CCER_CC1P (1 << 1) /* Bit 1: Capture/Compare 1 output polarity */ #define GTIM_CCER_CC1NE (1 << 2) /* Bit 2: Capture/Compare 1 complementary output enable (TIM1 and TIM8 only) */ -#define GTIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 output Polarity (F2,F3,F4 and TIM15-17) */ +#ifdef HAVE_GTIM_CCXNP +# define GTIM_CCER_CC1NP (1 << 3) /* Bit 3: Capture/Compare 1 output Polarity (F2,F3,F4 and TIM15-17) */ +#endif #define GTIM_CCER_CC2E (1 << 4) /* Bit 4: Capture/Compare 2 output enable (TIM2-5,9&12 only) */ #define GTIM_CCER_CC2P (1 << 5) /* Bit 5: Capture/Compare 2 output polarity (TIM2-5,9&12 only) */ #define GTIM_CCER_CC2NE (1 << 6) /* Bit 6: Capture/Compare 2 complementary output enable (TIM1 and TIM8 only) */ -#define GTIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 output Polarity (F2,F3,F4 and TIM2-5,9,12&15 only) */ +#ifdef HAVE_GTIM_CCXNP +# define GTIM_CCER_CC2NP (1 << 7) /* Bit 7: Capture/Compare 2 output Polarity (F2,F3,F4 and TIM2-5,9,12&15 only) */ +#endif #define GTIM_CCER_CC3E (1 << 8) /* Bit 8: Capture/Compare 3 output enable (TIM2-5 only) */ #define GTIM_CCER_CC3P (1 << 9) /* Bit 9: Capture/Compare 3 output Polarity (TIM2-5 only) */ #define GTIM_CCER_CC3NE (1 << 10) /* Bit 10: Capture/Compare 3 complementary output enable (TIM1 and TIM8 only) */ -#define GTIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 output Polarity (F2,F4 and TIM2-5 only) */ +#ifdef HAVE_GTIM_CCXNP +# define GTIM_CCER_CC3NP (1 << 11) /* Bit 11: Capture/Compare 3 output Polarity (F2,F4 and TIM2-5 only) */ +#endif #define GTIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable (TIM2-5 only) */ #define GTIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity (TIM2-5 only) */ -#define GTIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 output Polarity */ +#ifdef HAVE_GTIM_CCXNP +# define GTIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 output Polarity + * NOTE: Some ST documents show CC4NP bit but there is + * no CC4N output, so it does not make sense! + */ +#endif /* 16-bit counter register */ #define GTIM_CNT_SHIFT (0) /* Bits 0-15: Timer counter value */ #define GTIM_CNT_MASK (0xffff << ATIM_CNT_SHIFT) - -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_IP_TIMERS_V2 # define GTIM_CCER_UIFCPY (1 << 31) /* Bit 31: UIF copy */ #endif @@ -1306,7 +1312,7 @@ /* Timer 16 Option Register */ -#ifdef CONFIG_STM32_STM32F30XX +#ifdef HAVE_TIM16_OR # define TIM16_OR_RMP_SHIFT (0) /* Bits 0-1: Timer 16 input 1 connection */ # define TIM16_OR_RMP_MASK (3 << TIM16_OR_RMP_SHIFT) # define TIM16_OR_RMP_GPRIO (3 << TIM16_OR_RMP_SHIFT) /* TIM16 TI1 is connected to GPIO */ diff --git a/arch/arm/src/stm32/stm32_pwm.c b/arch/arm/src/stm32/stm32_pwm.c index 7aadb98ae7..16d4632839 100644 --- a/arch/arm/src/stm32/stm32_pwm.c +++ b/arch/arm/src/stm32/stm32_pwm.c @@ -5,6 +5,7 @@ * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. * Authors: Gregory Nutt * Paul Alexander Patience + * Mateusz Szafoni * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -75,13 +76,21 @@ * Pre-processor Definitions ****************************************************************************/ /* PWM/Timer Definitions ****************************************************/ -/* The following definitions are used to identify the various time types */ -#define TIMTYPE_BASIC 0 /* Basic timers: TIM6-7 */ -#define TIMTYPE_GENERAL16 1 /* General 16-bit timers: TIM2-5 on F1 */ -#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers: TIM9-14 on F4, TIM15-17 on F3 */ -#define TIMTYPE_GENERAL32 3 /* General 32-bit timers: TIM2-5 on F4 */ -#define TIMTYPE_ADVANCED 4 /* Advanced timers: TIM1-8 */ +/* The following definitions are used to identify the various time types. + * There are some differences in timer types accross STM32 families: + * - TIM2 is 16-bit timer for F1, L1 and L0 + * - TIM5 is 16-bit timer for F1 + */ + +#define TIMTYPE_BASIC 0 /* Basic timers (no outputs) */ +#define TIMTYPE_GENERAL16 1 /* General 16-bit timers (up, down, up/down)*/ +#define TIMTYPE_COUNTUP16 2 /* General 16-bit count-up timers */ +#define TIMTYPE_COUNTUP16_N 3 /* General 16-bit count-up timers with + * complementary outptus + */ +#define TIMTYPE_GENERAL32 4 /* General 32-bit timers (up, down, up/down)*/ +#define TIMTYPE_ADVANCED 5 /* Advanced timers */ #define TIMTYPE_TIM1 TIMTYPE_ADVANCED #if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) @@ -89,14 +98,9 @@ #else # define TIMTYPE_TIM2 TIMTYPE_GENERAL32 #endif -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX) -# define TIMTYPE_TIM3 TIMTYPE_GENERAL32 -# define TIMTYPE_TIM4 TIMTYPE_GENERAL32 -#else -# define TIMTYPE_TIM3 TIMTYPE_GENERAL16 -# define TIMTYPE_TIM4 TIMTYPE_GENERAL16 -#endif -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) +#define TIMTYPE_TIM3 TIMTYPE_GENERAL16 +#define TIMTYPE_TIM4 TIMTYPE_GENERAL16 +#if defined(CONFIG_STM32_STM32F10XX) # define TIMTYPE_TIM5 TIMTYPE_GENERAL16 #else # define TIMTYPE_TIM5 TIMTYPE_GENERAL32 @@ -110,12 +114,14 @@ #define TIMTYPE_TIM12 TIMTYPE_COUNTUP16 #define TIMTYPE_TIM13 TIMTYPE_COUNTUP16 #define TIMTYPE_TIM14 TIMTYPE_COUNTUP16 -#define TIMTYPE_TIM15 TIMTYPE_COUNTUP16 -#define TIMTYPE_TIM16 TIMTYPE_COUNTUP16 -#define TIMTYPE_TIM17 TIMTYPE_COUNTUP16 +#define TIMTYPE_TIM15 TIMTYPE_COUNTUP16_N +#define TIMTYPE_TIM16 TIMTYPE_COUNTUP16_N +#define TIMTYPE_TIM17 TIMTYPE_COUNTUP16_N /* Timer clock source, RCC EN offset, enable bit, * RCC RST offset, reset bit to use + * + * TODO: simplify this and move somewhere else. */ #if defined(CONFIG_STM32_STM32F37XX) @@ -267,6 +273,76 @@ # define TIMRST_TIM17 RCC_APB1RSTR_TIM17RST #endif +/* Default GPIO pins state */ + +#if defined(CONFIG_STM32_STM32F10XX) +# define PINCFG_DEFAULT (GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT) +#elif defined(CONFIG_STM32_STM32F20XX) || \ + defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F33XX) || \ + defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F4XXX) || \ + defined(CONFIG_STM32_STM32L15XX) +# define PINCFG_DEFAULT (GPIO_INPUT | GPIO_FLOAT) +#else +# error "Unrecognized STM32 chip" +#endif + +/* Advanced Timer support + * NOTE: TIM15-17 are not ADVTIM but they support most of the ADVTIM functionality. + * The main difference is the number of supported capture/compare. + */ + +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ + defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ + defined(CONFIG_STM32_TIM17_PWM) +# define HAVE_ADVTIM +#else +# undef HAVE_ADVTIM +#endif + +/* Pulsecount support */ + +#ifdef CONFIG_PWM_PULSECOUNT +# ifndef HAVE_ADVTIM +# error "PWM_PULSECOUNT requires HAVE_ADVTIM" +# endif +# if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) +# define HAVE_PWM_INTERRUPT +# endif +#endif + +/* Synchronisation support */ + +#ifdef CONFIG_STM32_PWM_TRGO +# define HAVE_TRGO +#endif + +/* Complementary outputs support */ + +#if defined(CONFIG_STM32_TIM1_CH1NOUT) || defined(CONFIG_STM32_TIM1_CH2NOUT) || \ + defined(CONFIG_STM32_TIM1_CH3NOUT) +# define HAVE_TIM1_COMPLEMENTARY +#endif +#if defined(CONFIG_STM32_TIM8_CH1NOUT) || defined(CONFIG_STM32_TIM8_CH2NOUT) || \ + defined(CONFIG_STM32_TIM8_CH3NOUT) +# define HAVE_TIM8_COMPLEMENTARY +#endif +#if defined(CONFIG_STM32_TIM15_CH1NOUT) +# define HAVE_TIM15_COMPLEMENTARY +#endif +#if defined(CONFIG_STM32_TIM16_CH1NOUT) +# define HAVE_TIM16_COMPLEMENTARY +#endif +#if defined(CONFIG_STM32_TIM17_CH1NOUT) +# define HAVE_TIM17_COMPLEMENTARY +#endif +#if defined(HAVE_TIM1_COMPLEMENTARY) || defined(HAVE_TIM8_COMPLEMENTARY) || \ + defined(HAVE_TIM15_COMPLEMENTARY) || defined(HAVE_TIM16_COMPLEMENTARY) || \ + defined(HAVE_TIM17_COMPLEMENTARY) +# define HAVE_COMPLEMENTARY +#endif + /* Debug ********************************************************************/ #ifdef CONFIG_DEBUG_PWM_INFO @@ -279,54 +355,74 @@ * Private Types ****************************************************************************/ -enum stm32_timmode_e +/* PWM output configuration */ + +struct stm32_pwm_out_s { - STM32_TIMMODE_COUNTUP = 0, - STM32_TIMMODE_COUNTDOWN = 1, - STM32_TIMMODE_CENTER1 = 2, - STM32_TIMMODE_CENTER2 = 3, - STM32_TIMMODE_CENTER3 = 4, + uint8_t in_use:1; /* Output in use */ + uint8_t pol:1; /* Polarity. Default: positive */ + uint8_t idle:1; /* Idle state. Default: inactive */ + uint8_t _res:5; /* Reserved */ + uint32_t pincfg; /* Output pin configuration */ }; -enum stm32_chanmode_e +/* PWM break configuration */ + +struct stm32_pwm_break_s { - STM32_CHANMODE_PWM1 = 0, - STM32_CHANMODE_PWM2 = 1, - STM32_CHANMODE_COMBINED1 = 2, - STM32_CHANMODE_COMBINED2 = 3, - STM32_CHANMODE_ASYMMETRIC1 = 4, - STM32_CHANMODE_ASYMMETRIC2 = 5, + uint32_t _res; /* Reserved */ }; +/* PWM channel configuration */ struct stm32_pwmchan_s { - uint8_t channel; /* Timer output channel: {1,..4} */ - uint32_t pincfg; /* Output pin configuration */ - enum stm32_chanmode_e mode; + uint8_t channel:4; /* Timer output channel: {1,..4} */ + uint8_t mode:4; /* PWM channel mode (see stm32_chan_mode_e) */ + struct stm32_pwm_out_s out1; /* PWM output configuration */ + struct stm32_pwm_break_s brk; /* PWM break configuration */ +#ifdef HAVE_COMPLEMENTARY + struct stm32_pwm_out_s out2; /* PWM complementary output configuration */ +#endif }; /* This structure represents the state of one PWM timer */ struct stm32_pwmtimer_s { - FAR const struct pwm_ops_s *ops; /* PWM operations */ - uint8_t timid; /* Timer ID {1,...,17} */ - struct stm32_pwmchan_s channels[PWM_NCHANNELS]; - uint8_t timtype; /* See the TIMTYPE_* definitions */ - enum stm32_timmode_e mode; -#ifdef CONFIG_PWM_PULSECOUNT - uint8_t irq; /* Timer update IRQ */ - uint8_t prev; /* The previous value of the RCR (pre-loaded) */ - uint8_t curr; /* The current value of the RCR (pre-loaded) */ - uint32_t count; /* Remaining pluse count */ -#else - uint32_t frequency; /* Current frequency setting */ + FAR const struct pwm_ops_s *ops; /* PWM operations */ +#ifdef CONFIG_STM32_PWM_LL_OPS + FAR const struct stm32_pwm_ops_s *llops; /* Low-level PWM ops */ +#endif + FAR struct stm32_pwmchan_s *channels; /* Channels configuration */ + uint8_t timid:5; /* Timer ID {1,...,17} */ + uint8_t chan_num:3; /* Number of configured channels */ + uint8_t timtype:3; /* See the TIMTYPE_* definitions */ + uint8_t mode:3; /* Timer mode (see stm32_pwm_tim_mode_e) */ + uint8_t lock:2; /* TODO: Lock configuration */ + uint8_t t_dts:3; /* Clock division for t_DTS */ + uint8_t _res:5; /* Reserved */ +#ifdef HAVE_COMPLEMENTARY + uint8_t deadtime; /* Dead-time value */ +#endif +#ifdef HAVE_TRGO + uint8_t trgo; /* TRGO configuration: + * 4 LSB = TRGO, 4 MSB = TRGO2 + */ #endif - uint32_t base; /* The base address of the timer */ - uint32_t pclk; /* The frequency of the peripheral clock - * that drives the timer module. */ #ifdef CONFIG_PWM_PULSECOUNT - FAR void *handle; /* Handle used for upper-half callback */ + uint8_t irq; /* Timer update IRQ */ + uint8_t prev; /* The previous value of the RCR (pre-loaded) */ + uint8_t curr; /* The current value of the RCR (pre-loaded) */ + uint32_t count; /* Remaining pluse count */ +#else + uint32_t frequency; /* Current frequency setting */ +#endif + uint32_t base; /* The base address of the timer */ + uint32_t pclk; /* The frequency of the peripheral clock + * that drives the timer module. + */ +#ifdef CONFIG_PWM_PULSECOUNT + FAR void *handle; /* Handle used for upper-half callback */ #endif }; @@ -335,8 +431,10 @@ struct stm32_pwmtimer_s ****************************************************************************/ /* Register access */ -static uint16_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset); -static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint16_t value); +static uint32_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset); +static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint32_t value); +static void pwm_modifyreg(struct stm32_pwmtimer_s *priv, uint32_t offset, + uint32_t clearbits, uint32_t setbits); #ifdef CONFIG_DEBUG_PWM_INFO static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg); @@ -346,17 +444,52 @@ static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg); /* Timer management */ -static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, - FAR const struct pwm_info_s *info); +static int pwm_frequency_update(FAR struct pwm_lowerhalf_s *dev, + uint32_t frequency); +static int pwm_mode_configure(FAR struct stm32_pwmtimer_s *priv, uint8_t channel, + uint32_t mode); +static int pwm_timer_configure(FAR struct stm32_pwmtimer_s *priv); +static int pwm_output_configure(FAR struct stm32_pwmtimer_s *priv, + uint8_t channel); +static int pwm_outputs_enable(FAR struct pwm_lowerhalf_s *dev, uint16_t outputs, + bool state); +static int pwm_soft_update(FAR struct pwm_lowerhalf_s *dev); +static int pwm_configure(FAR struct pwm_lowerhalf_s *dev); +static int pwm_ccr_update(FAR struct pwm_lowerhalf_s *dev, uint8_t index, + uint32_t ccr); +static int pwm_arr_update(FAR struct pwm_lowerhalf_s *dev, uint32_t arr); +static uint32_t pwm_arr_get(FAR struct pwm_lowerhalf_s *dev); +static int pwm_duty_update(FAR struct pwm_lowerhalf_s *dev, uint8_t channel, + ub16_t duty); -#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM)) -static int pwm_interrupt(struct stm32_pwmtimer_s *priv); -#if defined(CONFIG_STM32_TIM1_PWM) +#ifdef HAVE_ADVTIM +static int pwm_break_configure(FAR struct stm32_pwmtimer_s *priv); +#endif +#ifdef HAVE_TRGO +static int pwm_sync_configure(FAR struct stm32_pwmtimer_s *priv, uint8_t trgo); +#endif +#ifdef HAVE_COMPLEMENTARY +static int pwm_deadtime_configure(FAR struct stm32_pwmtimer_s *priv); +static int pwm_deadtime_update(FAR struct stm32_pwmtimer_s *priv, uint8_t dt); +#endif +#ifdef CONFIG_STM32_PWM_LL_OPS +static uint32_t pwm_ccr_get(FAR struct pwm_lowerhalf_s *dev, uint8_t index); +#endif +#ifdef CONFIG_PWM_PULSECOUNT +static int pwm_pulsecount_timer(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); +#else +static int pwm_timer(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info); +#endif +#ifdef HAVE_PWM_INTERRUPT +static int pwm_interrupt(FAR struct pwm_lowerhalf_s *dev); +# ifdef CONFIG_STM32_TIM1_PWM static int pwm_tim1interrupt(int irq, void *context, FAR void *arg); -#endif -#if defined(CONFIG_STM32_TIM8_PWM) +# endif +# ifdef CONFIG_STM32_TIM8_PWM static int pwm_tim8interrupt(int irq, void *context, FAR void *arg); -#endif +# endif static uint8_t pwm_pulsecount(uint32_t count); #endif @@ -381,6 +514,7 @@ static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, /**************************************************************************** * Private Data ****************************************************************************/ + /* This is the list of lower half PWM driver methods used by the upper half driver */ static const struct pwm_ops_s g_pwmops = @@ -392,652 +526,1241 @@ static const struct pwm_ops_s g_pwmops = .ioctl = pwm_ioctl, }; +#ifdef CONFIG_STM32_PWM_LL_OPS +static const struct stm32_pwm_ops_s g_llpwmops = +{ + .configure = pwm_configure, + .ccr_update = pwm_ccr_update, + .ccr_get = pwm_ccr_get, + .arr_update = pwm_arr_update, + .arr_get = pwm_arr_get, + .outputs_enable = pwm_outputs_enable, + .soft_update = pwm_soft_update, +}; +#endif + #ifdef CONFIG_STM32_TIM1_PWM + +static struct stm32_pwmchan_s g_pwm1channels[] = +{ + /* TIM1 has 4 channels, 4 complementary */ + +#ifdef CONFIG_STM32_TIM1_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM1_CH1MODE, +#ifdef CONFIG_STM32_TIM1_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH1POL, + .idle = CONFIG_STM32_TIM1_CH1IDLE, + .pincfg = PWM_TIM1_CH1CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM1_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH1NPOL, + .idle = CONFIG_STM32_TIM1_CH1NIDLE, + .pincfg = PWM_TIM1_CH1NCFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM1_CH2MODE, +#ifdef CONFIG_STM32_TIM1_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH2POL, + .idle = CONFIG_STM32_TIM1_CH2IDLE, + .pincfg = PWM_TIM1_CH2CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM1_CH2NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH2NPOL, + .idle = CONFIG_STM32_TIM1_CH2NIDLE, + .pincfg = PWM_TIM1_CH2NCFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_STM32_TIM1_CH3MODE, +#ifdef CONFIG_STM32_TIM1_CH3OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH3POL, + .idle = CONFIG_STM32_TIM1_CH3IDLE, + .pincfg = PWM_TIM1_CH3CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM1_CH3NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH3NPOL, + .idle = CONFIG_STM32_TIM1_CH3NIDLE, + .pincfg = PWM_TIM1_CH3NCFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM1_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_STM32_TIM1_CH4MODE, +#ifdef CONFIG_STM32_TIM1_CH4OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM1_CH4POL, + .idle = CONFIG_STM32_TIM1_CH4IDLE, + .pincfg = PWM_TIM1_CH4CFG, + } +#endif + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm1dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 1, - .channels = - { -#ifdef CONFIG_STM32_TIM1_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM1_CH1CFG, - .mode = CONFIG_STM32_TIM1_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM1_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM1_CH2CFG, - .mode = CONFIG_STM32_TIM1_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM1_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM1_CH3CFG, - .mode = CONFIG_STM32_TIM1_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM1_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM1_CH4CFG, - .mode = CONFIG_STM32_TIM1_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM1_NCHANNELS, + .channels = g_pwm1channels, .timtype = TIMTYPE_TIM1, .mode = CONFIG_STM32_TIM1_MODE, + .lock = CONFIG_STM32_TIM1_LOCK, + .t_dts = CONFIG_STM32_TIM1_TDTS, +#ifdef HAVE_COMPLEMENTARY + .deadtime = CONFIG_STM32_TIM1_DEADTIME, +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM1_TRGO) + .trgo = STM32_TIM1_TRGO, +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM1UP, #endif .base = STM32_TIM1_BASE, .pclk = TIMCLK_TIM1, }; -#endif +#endif /* CONFIG_STM32_TIM1_PWM */ #ifdef CONFIG_STM32_TIM2_PWM + +static struct stm32_pwmchan_s g_pwm2channels[] = +{ + /* TIM2 has 4 channels */ + +#ifdef CONFIG_STM32_TIM2_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM2_CH1MODE, +#ifdef CONFIG_STM32_TIM2_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM2_CH1POL, + .idle = CONFIG_STM32_TIM2_CH1IDLE, + .pincfg = PWM_TIM2_CH1CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM2_CH2MODE, +#ifdef CONFIG_STM32_TIM2_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM2_CH2POL, + .idle = CONFIG_STM32_TIM2_CH2IDLE, + .pincfg = PWM_TIM2_CH2CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_STM32_TIM2_CH3MODE, +#ifdef CONFIG_STM32_TIM2_CH3OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM2_CH3POL, + .idle = CONFIG_STM32_TIM2_CH3IDLE, + .pincfg = PWM_TIM2_CH3CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM2_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_STM32_TIM2_CH4MODE, +#ifdef CONFIG_STM32_TIM2_CH4OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM2_CH4POL, + .idle = CONFIG_STM32_TIM2_CH4IDLE, + .pincfg = PWM_TIM2_CH4CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm2dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 2, - .channels = - { -#ifdef CONFIG_STM32_TIM2_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM2_CH1CFG, - .mode = CONFIG_STM32_TIM2_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM2_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM2_CH2CFG, - .mode = CONFIG_STM32_TIM2_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM2_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM2_CH3CFG, - .mode = CONFIG_STM32_TIM2_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM2_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM2_CH4CFG, - .mode = CONFIG_STM32_TIM2_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM2_NCHANNELS, + .channels = g_pwm2channels, .timtype = TIMTYPE_TIM2, .mode = CONFIG_STM32_TIM2_MODE, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM2_TRGO) + .trgo = STM32_TIM2_TRGO, +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM2, #endif .base = STM32_TIM2_BASE, .pclk = TIMCLK_TIM2, }; -#endif +#endif /* CONFIG_STM32_TIM2_PWM */ #ifdef CONFIG_STM32_TIM3_PWM + +static struct stm32_pwmchan_s g_pwm3channels[] = +{ + /* TIM3 has 4 channels */ + +#ifdef CONFIG_STM32_TIM3_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM3_CH1MODE, +#ifdef CONFIG_STM32_TIM3_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM3_CH1POL, + .idle = CONFIG_STM32_TIM3_CH1IDLE, + .pincfg = PWM_TIM3_CH1CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM3_CH2MODE, +#ifdef CONFIG_STM32_TIM3_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM3_CH2POL, + .idle = CONFIG_STM32_TIM3_CH2IDLE, + .pincfg = PWM_TIM3_CH2CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_STM32_TIM3_CH3MODE, +#ifdef CONFIG_STM32_TIM3_CH3OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM3_CH3POL, + .idle = CONFIG_STM32_TIM3_CH3IDLE, + .pincfg = PWM_TIM3_CH3CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM3_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_STM32_TIM3_CH4MODE, +#ifdef CONFIG_STM32_TIM3_CH4OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM3_CH4POL, + .idle = CONFIG_STM32_TIM3_CH4IDLE, + .pincfg = PWM_TIM3_CH4CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm3dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 3, - .channels = - { -#ifdef CONFIG_STM32_TIM3_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM3_CH1CFG, - .mode = CONFIG_STM32_TIM3_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM3_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM3_CH2CFG, - .mode = CONFIG_STM32_TIM3_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM3_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM3_CH3CFG, - .mode = CONFIG_STM32_TIM3_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM3_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM3_CH4CFG, - .mode = CONFIG_STM32_TIM3_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM3_NCHANNELS, + .channels = g_pwm3channels, .timtype = TIMTYPE_TIM3, .mode = CONFIG_STM32_TIM3_MODE, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM3_TRGO) + .trgo = STM32_TIM3_TRGO, +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM3, #endif .base = STM32_TIM3_BASE, .pclk = TIMCLK_TIM3, }; -#endif +#endif /* CONFIG_STM32_TIM3_PWM */ #ifdef CONFIG_STM32_TIM4_PWM + +static struct stm32_pwmchan_s g_pwm4channels[] = +{ + /* TIM4 has 4 channels */ + +#ifdef CONFIG_STM32_TIM4_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM4_CH1MODE, +#ifdef CONFIG_STM32_TIM4_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM4_CH1POL, + .idle = CONFIG_STM32_TIM4_CH1IDLE, + .pincfg = PWM_TIM4_CH1CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM4_CH2MODE, +#ifdef CONFIG_STM32_TIM4_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM4_CH2POL, + .idle = CONFIG_STM32_TIM4_CH2IDLE, + .pincfg = PWM_TIM4_CH2CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_STM32_TIM4_CH3MODE, +#ifdef CONFIG_STM32_TIM4_CH3OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM4_CH3POL, + .idle = CONFIG_STM32_TIM4_CH3IDLE, + .pincfg = PWM_TIM4_CH3CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM4_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_STM32_TIM4_CH4MODE, +#ifdef CONFIG_STM32_TIM4_CH4OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM4_CH4POL, + .idle = CONFIG_STM32_TIM4_CH4IDLE, + .pincfg = PWM_TIM4_CH4CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm4dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 4, - .channels = - { -#ifdef CONFIG_STM32_TIM4_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM4_CH1CFG, - .mode = CONFIG_STM32_TIM4_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM4_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM4_CH2CFG, - .mode = CONFIG_STM32_TIM4_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM4_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM4_CH3CFG, - .mode = CONFIG_STM32_TIM4_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM4_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM4_CH4CFG, - .mode = CONFIG_STM32_TIM4_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM4_NCHANNELS, + .channels = g_pwm4channels, .timtype = TIMTYPE_TIM4, .mode = CONFIG_STM32_TIM4_MODE, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM4_TRGO) + .trgo = STM32_TIM4_TRGO, +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM4, #endif .base = STM32_TIM4_BASE, .pclk = TIMCLK_TIM4, }; -#endif +#endif /* CONFIG_STM32_TIM4_PWM */ #ifdef CONFIG_STM32_TIM5_PWM + +static struct stm32_pwmchan_s g_pwm5channels[] = +{ + /* TIM5 has 4 channels */ + +#ifdef CONFIG_STM32_TIM5_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM5_CH1MODE, +#ifdef CONFIG_STM32_TIM5_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM5_CH1POL, + .idle = CONFIG_STM32_TIM5_CH1IDLE, + .pincfg = PWM_TIM5_CH1CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM5_CH2MODE, +#ifdef CONFIG_STM32_TIM5_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM5_CH2POL, + .idle = CONFIG_STM32_TIM5_CH2IDLE, + .pincfg = PWM_TIM5_CH2CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_STM32_TIM5_CH3MODE, +#ifdef CONFIG_STM32_TIM5_CH3OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM5_CH3POL, + .idle = CONFIG_STM32_TIM5_CH3IDLE, + .pincfg = PWM_TIM5_CH3CFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM5_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_STM32_TIM5_CH4MODE, +#ifdef CONFIG_STM32_TIM5_CH4OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM5_CH4POL, + .idle = CONFIG_STM32_TIM5_CH4IDLE, + .pincfg = PWM_TIM5_CH4CFG, + } +#endif + }, +#endif +}; + static struct stm32_pwmtimer_s g_pwm5dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 5, - .channels = - { -#ifdef CONFIG_STM32_TIM5_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM5_CH1CFG, - .mode = CONFIG_STM32_TIM5_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM5_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM5_CH2CFG, - .mode = CONFIG_STM32_TIM5_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM5_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM5_CH3CFG, - .mode = CONFIG_STM32_TIM5_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM5_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM5_CH4CFG, - .mode = CONFIG_STM32_TIM5_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM5_NCHANNELS, + .channels = g_pwm5channels, .timtype = TIMTYPE_TIM5, .mode = CONFIG_STM32_TIM5_MODE, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM5_TRGO) + .trgo = STM32_TIM5_TRGO +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM5, #endif .base = STM32_TIM5_BASE, .pclk = TIMCLK_TIM5, }; -#endif +#endif /* CONFIG_STM32_TIM5_PWM */ #ifdef CONFIG_STM32_TIM8_PWM + +static struct stm32_pwmchan_s g_pwm8channels[] = +{ + /* TIM8 has 4 channels, 4 complementary */ + +#ifdef CONFIG_STM32_TIM8_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM8_CH1MODE, +#ifdef CONFIG_STM32_TIM8_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH1POL, + .idle = CONFIG_STM32_TIM8_CH1IDLE, + .pincfg = PWM_TIM8_CH1CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM8_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH1NPOL, + .idle = CONFIG_STM32_TIM8_CH1NIDLE, + .pincfg = PWM_TIM8_CH1NCFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM8_CH2MODE, +#ifdef CONFIG_STM32_TIM8_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH2POL, + .idle = CONFIG_STM32_TIM8_CH2IDLE, + .pincfg = PWM_TIM8_CH2CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM8_CH2NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH2NPOL, + .idle = CONFIG_STM32_TIM8_CH2NIDLE, + .pincfg = PWM_TIM8_CH2NCFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL3 + { + .channel = 3, + .mode = CONFIG_STM32_TIM8_CH3MODE, +#ifdef CONFIG_STM32_TIM8_CH3OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH3POL, + .idle = CONFIG_STM32_TIM8_CH3IDLE, + .pincfg = PWM_TIM8_CH3CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM8_CH3NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH3NPOL, + .idle = CONFIG_STM32_TIM8_CH3NIDLE, + .pincfg = PWM_TIM8_CH3NCFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM8_CHANNEL4 + { + .channel = 4, + .mode = CONFIG_STM32_TIM8_CH4MODE, +#ifdef CONFIG_STM32_TIM8_CH4OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM8_CH4POL, + .idle = CONFIG_STM32_TIM8_CH4IDLE, + .pincfg = PWM_TIM8_CH4CFG, + } +#endif + }, +#endif +}; + static struct stm32_pwmtimer_s g_pwm8dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 8, - .channels = - { -#ifdef CONFIG_STM32_TIM8_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM8_CH1CFG, - .mode = CONFIG_STM32_TIM8_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM8_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM8_CH2CFG, - .mode = CONFIG_STM32_TIM8_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM8_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM8_CH3CFG, - .mode = CONFIG_STM32_TIM8_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM8_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM8_CH4CFG, - .mode = CONFIG_STM32_TIM8_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM8_NCHANNELS, + .channels = g_pwm8channels, .timtype = TIMTYPE_TIM8, .mode = CONFIG_STM32_TIM8_MODE, + .lock = CONFIG_STM32_TIM8_LOCK, + .t_dts = CONFIG_STM32_TIM8_TDTS, +#ifdef HAVE_COMPLEMENTARY + .deadtime = CONFIG_STM32_TIM8_DEADTIME, +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM8_TRGO) + .trgo = STM32_TIM8_TRGO, +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM8UP, #endif .base = STM32_TIM8_BASE, .pclk = TIMCLK_TIM8, }; -#endif +#endif /* CONFIG_STM32_TIM8_PWM */ #ifdef CONFIG_STM32_TIM9_PWM + +static struct stm32_pwmchan_s g_pwm9channels[] = +{ + /* TIM9 has 2 channels */ + +#ifdef CONFIG_STM32_TIM9_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM9_CH1MODE, +#ifdef CONFIG_STM32_TIM9_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM9_CH1POL, + .idle = CONFIG_STM32_TIM9_CH1IDLE, + .pincfg = PWM_TIM9_CH1CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM9_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM9_CH2MODE, +#ifdef CONFIG_STM32_TIM9_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM9_CH2POL, + .idle = CONFIG_STM32_TIM9_CH2IDLE, + .pincfg = PWM_TIM9_CH2CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm9dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 9, - .channels = - { -#ifdef CONFIG_STM32_TIM9_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM9_CH1CFG, - .mode = CONFIG_STM32_TIM9_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM9_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM9_CH2CFG, - .mode = CONFIG_STM32_TIM9_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM9_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM9_CH3CFG, - .mode = CONFIG_STM32_TIM9_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM9_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM9_CH4CFG, - .mode = CONFIG_STM32_TIM9_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM9_NCHANNELS, + .channels = g_pwm9channels, .timtype = TIMTYPE_TIM9, .mode = STM32_TIMMODE_COUNTUP, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM9 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM9, #endif .base = STM32_TIM9_BASE, .pclk = TIMCLK_TIM9, }; -#endif +#endif /* CONFIG_STM32_TIM9_PWM */ #ifdef CONFIG_STM32_TIM10_PWM + +static struct stm32_pwmchan_s g_pwm10channels[] = +{ + /* TIM10 has 1 channel */ + +#ifdef CONFIG_STM32_TIM10_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM10_CH1MODE, +#ifdef CONFIG_STM32_TIM10_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM10_CH1POL, + .idle = CONFIG_STM32_TIM10_CH1IDLE, + .pincfg = PWM_TIM10_CH1CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm10dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 10, - .channels = - { -#ifdef CONFIG_STM32_TIM10_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM10_CH1CFG, - .mode = CONFIG_STM32_TIM10_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM10_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM10_CH2CFG, - .mode = CONFIG_STM32_TIM10_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM10_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM10_CH3CFG, - .mode = CONFIG_STM32_TIM10_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM10_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM10_CH4CFG, - .mode = CONFIG_STM32_TIM10_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM10_NCHANNELS, + .channels = g_pwm10channels, .timtype = TIMTYPE_TIM10, .mode = STM32_TIMMODE_COUNTUP, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM10 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM10, #endif .base = STM32_TIM10_BASE, .pclk = TIMCLK_TIM10, }; -#endif +#endif /* CONFIG_STM32_TIM10_PWM */ #ifdef CONFIG_STM32_TIM11_PWM + +static struct stm32_pwmchan_s g_pwm11channels[] = +{ + /* TIM11 has 1 channel */ + +#ifdef CONFIG_STM32_TIM11_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM11_CH1MODE, +#ifdef CONFIG_STM32_TIM11_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM11_CH1POL, + .idle = CONFIG_STM32_TIM11_CH1IDLE, + .pincfg = PWM_TIM11_CH1CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm11dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 11, - .channels = - { -#ifdef CONFIG_STM32_TIM11_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM11_CH1CFG, - .mode = CONFIG_STM32_TIM11_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM11_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM11_CH2CFG, - .mode = CONFIG_STM32_TIM11_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM11_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM11_CH3CFG, - .mode = CONFIG_STM32_TIM11_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM11_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM11_CH4CFG, - .mode = CONFIG_STM32_TIM11_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM11_NCHANNELS, + .channels = g_pwm11channels, .timtype = TIMTYPE_TIM11, .mode = STM32_TIMMODE_COUNTUP, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM11 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM11, #endif .base = STM32_TIM11_BASE, .pclk = TIMCLK_TIM11, }; -#endif +#endif /* CONFIG_STM32_TIM11_PWM */ #ifdef CONFIG_STM32_TIM12_PWM + +static struct stm32_pwmchan_s g_pwm12channels[] = +{ + /* TIM12 has 2 channels */ + +#ifdef CONFIG_STM32_TIM12_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM12_CH1MODE, +#ifdef CONFIG_STM32_TIM12_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM12_CH1POL, + .idle = CONFIG_STM32_TIM12_CH1IDLE, + .pincfg = PWM_TIM12_CH1CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +#ifdef CONFIG_STM32_TIM12_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM12_CH2MODE, +#ifdef CONFIG_STM32_TIM12_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM12_CH2POL, + .idle = CONFIG_STM32_TIM12_CH2IDLE, + .pincfg = PWM_TIM12_CH2CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm12dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 12, - .channels = - { -#ifdef CONFIG_STM32_TIM12_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM12_CH1CFG, - .mode = CONFIG_STM32_TIM12_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM12_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM12_CH2CFG, - .mode = CONFIG_STM32_TIM12_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM12_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM12_CH3CFG, - .mode = CONFIG_STM32_TIM12_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM12_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM12_CH4CFG, - .mode = CONFIG_STM32_TIM12_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM12_NCHANNELS, + .channels = g_pwm12channels, .timtype = TIMTYPE_TIM12, .mode = STM32_TIMMODE_COUNTUP, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM12 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM12, #endif .base = STM32_TIM12_BASE, .pclk = TIMCLK_TIM12, }; -#endif +#endif /* CONFIG_STM32_TIM12_PWM */ #ifdef CONFIG_STM32_TIM13_PWM + +static struct stm32_pwmchan_s g_pwm13channels[] = +{ + /* TIM13 has 1 channel */ + +#ifdef CONFIG_STM32_TIM13_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM13_CH1MODE, +#ifdef CONFIG_STM32_TIM13_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM13_CH1POL, + .idle = CONFIG_STM32_TIM13_CH1IDLE, + .pincfg = PWM_TIM13_CH1CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm13dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 13, - .channels = - { -#ifdef CONFIG_STM32_TIM13_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM13_CH1CFG, - .mode = CONFIG_STM32_TIM13_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM13_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM13_CH2CFG, - .mode = CONFIG_STM32_TIM13_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM13_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM13_CH3CFG, - .mode = CONFIG_STM32_TIM13_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM13_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM13_CH4CFG, - .mode = CONFIG_STM32_TIM13_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM13_NCHANNELS, + .channels = g_pwm13channels, .timtype = TIMTYPE_TIM13, .mode = STM32_TIMMODE_COUNTUP, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM13 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM13, #endif .base = STM32_TIM13_BASE, .pclk = TIMCLK_TIM13, }; -#endif +#endif /* CONFIG_STM32_TIM13_PWM */ #ifdef CONFIG_STM32_TIM14_PWM + +static struct stm32_pwmchan_s g_pwm14channels[] = +{ + /* TIM14 has 1 channel */ + +#ifdef CONFIG_STM32_TIM14_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM14_CH1MODE, +#ifdef CONFIG_STM32_TIM14_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM14_CH1POL, + .idle = CONFIG_STM32_TIM14_CH1IDLE, + .pincfg = PWM_TIM14_CH1CFG, + } +#endif + /* No complementary outputs */ + } +#endif +}; + static struct stm32_pwmtimer_s g_pwm14dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 14, - .channels = - { -#ifdef CONFIG_STM32_TIM14_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM14_CH1CFG, - .mode = CONFIG_STM32_TIM14_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM14_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM14_CH2CFG, - .mode = CONFIG_STM32_TIM14_CH2MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM14_CHANNEL3 - { - .channel = 3, - .pincfg = PWM_TIM14_CH3CFG, - .mode = CONFIG_STM32_TIM14_CH3MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM14_CHANNEL4 - { - .channel = 4, - .pincfg = PWM_TIM14_CH4CFG, - .mode = CONFIG_STM32_TIM14_CH4MODE, - }, -#endif - }, + .chan_num = PWM_TIM14_NCHANNELS, + .channels = g_pwm14channels, .timtype = TIMTYPE_TIM14, .mode = STM32_TIMMODE_COUNTUP, + .lock = 0, /* No lock */ + .t_dts = 0, /* No t_dts */ +#ifdef HAVE_COMPLEMENTARY + .deadtime = 0, /* No deadtime */ +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM14 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM14, #endif .base = STM32_TIM14_BASE, .pclk = TIMCLK_TIM14, }; -#endif +#endif /* CONFIG_STM32_TIM14_PWM */ #ifdef CONFIG_STM32_TIM15_PWM + +static struct stm32_pwmchan_s g_pwm15channels[] = +{ + /* TIM15 has 2 channels, 1 complementary */ + +#ifdef CONFIG_STM32_TIM15_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM15_CH1MODE, +#ifdef CONFIG_STM32_TIM15_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM15_CH1POL, + .idle = CONFIG_STM32_TIM15_CH1IDLE, + .pincfg = PWM_TIM15_CH1CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM15_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM15_CH1NPOL, + .idle = CONFIG_STM32_TIM15_CH1NIDLE, + .pincfg = PWM_TIM15_CH2CFG, + } +#endif + }, +#endif +#ifdef CONFIG_STM32_TIM15_CHANNEL2 + { + .channel = 2, + .mode = CONFIG_STM32_TIM15_CH2MODE, +#ifdef CONFIG_STM32_TIM12_CH2OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM15_CH2POL, + .idle = CONFIG_STM32_TIM15_CH2IDLE, + .pincfg = PWM_TIM15_CH2CFG, + } +#endif + /* No complementary outputs */ + }, +#endif +}; + static struct stm32_pwmtimer_s g_pwm15dev = { .ops = &g_pwmops, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, +#endif .timid = 15, - .channels = - { -#ifdef CONFIG_STM32_TIM15_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM15_CH1CFG, - .mode = CONFIG_STM32_TIM15_CH1MODE, - }, -#endif -#ifdef CONFIG_STM32_TIM15_CHANNEL2 - { - .channel = 2, - .pincfg = PWM_TIM15_CH2CFG, - .mode = CONFIG_STM32_TIM15_CH2MODE, - }, -#endif - }, + .chan_num = PWM_TIM15_NCHANNELS, + .channels = g_pwm15channels, .timtype = TIMTYPE_TIM15, .mode = STM32_TIMMODE_COUNTUP, + .lock = CONFIG_STM32_TIM15_LOCK, + .t_dts = CONFIG_STM32_TIM15_TDTS, +#ifdef HAVE_COMPLEMENTARY + .deadtime = CONFIG_STM32_TIM15_DEADTIME, +#endif +#if defined(HAVE_TRGO) && defined(STM32_TIM15_TRGO) + .trgo = STM32_TIM15_TRGO, +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM15, #endif .base = STM32_TIM15_BASE, .pclk = TIMCLK_TIM15, }; -#endif +#endif /* CONFIG_STM32_TIM15_PWM */ #ifdef CONFIG_STM32_TIM16_PWM + +static struct stm32_pwmchan_s g_pwm16channels[] = +{ + /* TIM16 has 1 channel, 1 complementary */ + +#ifdef CONFIG_STM32_TIM16_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM16_CH1MODE, +#ifdef CONFIG_STM32_TIM16_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM16_CH1POL, + .idle = CONFIG_STM32_TIM16_CH1IDLE, + .pincfg = PWM_TIM16_CH1CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM16_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM16_CH1NPOL, + .idle = CONFIG_STM32_TIM16_CH1NIDLE, + .pincfg = PWM_TIM16_CH2CFG, + } +#endif + }, +#endif +}; + static struct stm32_pwmtimer_s g_pwm16dev = { .ops = &g_pwmops, - .timid = 16, - .channels = - { -#ifdef CONFIG_STM32_TIM16_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM16_CH1CFG, - .mode = CONFIG_STM32_TIM16_CH1MODE, - }, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, #endif - }, + .timid = 16, + .chan_num = PWM_TIM16_NCHANNELS, + .channels = g_pwm16channels, .timtype = TIMTYPE_TIM16, .mode = STM32_TIMMODE_COUNTUP, + .lock = CONFIG_STM32_TIM16_LOCK, + .t_dts = CONFIG_STM32_TIM16_TDTS, +#ifdef HAVE_COMPLEMENTARY + .deadtime = CONFIG_STM32_TIM16_DEADTIME, +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM16 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM16, #endif .base = STM32_TIM16_BASE, .pclk = TIMCLK_TIM16, }; -#endif +#endif /* CONFIG_STM32_TIM16_PWM */ #ifdef CONFIG_STM32_TIM17_PWM + +static struct stm32_pwmchan_s g_pwm17channels[] = +{ + /* TIM17 has 1 channel, 1 complementary */ + +#ifdef CONFIG_STM32_TIM17_CHANNEL1 + { + .channel = 1, + .mode = CONFIG_STM32_TIM17_CH1MODE, +#ifdef CONFIG_STM32_TIM17_CH1OUT + .out1 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM17_CH1POL, + .idle = CONFIG_STM32_TIM17_CH1IDLE, + .pincfg = PWM_TIM17_CH1CFG, + }, +#endif +#ifdef CONFIG_STM32_TIM17_CH1NOUT + .out2 = + { + .in_use = 1, + .pol = CONFIG_STM32_TIM17_CH1NPOL, + .idle = CONFIG_STM32_TIM17_CH1NIDLE, + .pincfg = PWM_TIM17_CH2CFG, + } +#endif + }, +#endif +}; + static struct stm32_pwmtimer_s g_pwm17dev = { .ops = &g_pwmops, - .timid = 17, - .channels = - { -#ifdef CONFIG_STM32_TIM17_CHANNEL1 - { - .channel = 1, - .pincfg = PWM_TIM17_CH1CFG, - .mode = CONFIG_STM32_TIM17_CH1MODE, - }, +#ifdef CONFIG_STM32_PWM_LL_OPS + .llops = &g_llpwmops, #endif - }, + .timid = 17, + .chan_num = PWM_TIM17_NCHANNELS, + .channels = g_pwm17channels, .timtype = TIMTYPE_TIM17, .mode = STM32_TIMMODE_COUNTUP, + .lock = CONFIG_STM32_TIM17_LOCK, + .t_dts = CONFIG_STM32_TIM17_TDTS, +#ifdef HAVE_COMPLEMENTARY + .deadtime = CONFIG_STM32_TIM17_DEADTIME, +#endif +#if defined(HAVE_TRGO) + .trgo = 0, /* TRGO not supported for TIM17 */ +#endif #ifdef CONFIG_PWM_PULSECOUNT .irq = STM32_IRQ_TIM17, #endif .base = STM32_TIM17_BASE, .pclk = TIMCLK_TIM17, }; -#endif +#endif /* CONFIG_STM32_TIM17_PWM */ + +/* TODO: support for TIM19,20,21,22 */ /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: pwm_reg_is_32bit + ****************************************************************************/ + +static bool pwm_reg_is_32bit(uint8_t timtype, uint32_t offset) +{ + bool ret = false; + + if (timtype == TIMTYPE_GENERAL32) + { + if (offset == STM32_GTIM_CNT_OFFSET || + offset == STM32_GTIM_ARR_OFFSET || + offset == STM32_GTIM_CCR1_OFFSET || + offset == STM32_GTIM_CCR2_OFFSET || + offset == STM32_GTIM_CCR3_OFFSET || + offset == STM32_GTIM_CCR4_OFFSET) + { + ret = true; + } + } +#ifdef HAVE_IP_TIMERS_V2 + else if (timtype == TIMTYPE_ADVANCED) + { + if (offset == STM32_ATIM_CR2_OFFSET || + offset == STM32_ATIM_CCMR1_OFFSET || + offset == STM32_ATIM_CCMR2_OFFSET || + offset == STM32_ATIM_CCER_OFFSET || + offset == STM32_ATIM_BDTR_OFFSET || + offset == STM32_ATIM_CCMR3_OFFSET || + offset == STM32_ATIM_CCR5_OFFSET) + { + ret = true; + } + } +#endif + + return ret; +} + /**************************************************************************** * Name: pwm_getreg * * Description: - * Read the value of an PWM timer register. + * Read the value of an PWM timer register * * Input Parameters: - * priv - A reference to the PWM block status + * priv - A reference to the PWM block status * offset - The offset to the register to read * * Returned Value: @@ -1045,19 +1768,36 @@ static struct stm32_pwmtimer_s g_pwm17dev = * ****************************************************************************/ -static uint16_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset) +static uint32_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset) { - return getreg16(priv->base + offset); + uint32_t retval = 0; + + if (pwm_reg_is_32bit(priv->timtype, offset) == true) + { + /* 32-bit register */ + + retval = getreg32(priv->base + offset); + } + else + { + /* 16-bit register */ + + retval = getreg16(priv->base + offset); + } + + /* Return 32-bit value */ + + return retval; } /**************************************************************************** * Name: pwm_putreg * * Description: - * Read the value of an PWM timer register. + * Read the value of an PWM timer register * * Input Parameters: - * priv - A reference to the PWM block status + * priv - A reference to the PWM block status * offset - The offset to the register to read * * Returned Value: @@ -1065,27 +1805,54 @@ static uint16_t pwm_getreg(struct stm32_pwmtimer_s *priv, int offset) * ****************************************************************************/ -static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint16_t value) +static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint32_t value) { - if (priv->timtype == TIMTYPE_GENERAL32 && - (offset == STM32_GTIM_CNT_OFFSET || - offset == STM32_GTIM_ARR_OFFSET || - offset == STM32_GTIM_CCR1_OFFSET || - offset == STM32_GTIM_CCR2_OFFSET || - offset == STM32_GTIM_CCR3_OFFSET || - offset == STM32_GTIM_CCR4_OFFSET)) + if (pwm_reg_is_32bit(priv->timtype, offset) == true) { - /* a 32 bit access is required for a 32 bit register: - * if only a 16 bit write would be performed, then the - * upper 16 bits of the 32 bit register will be a copy of - * the lower 16 bits. - */ + /* 32-bit register */ putreg32(value, priv->base + offset); } else { - putreg16(value, priv->base + offset); + /* 16-bit register */ + + putreg16((uint16_t)value, priv->base + offset); + } +} + +/**************************************************************************** + * Name: pwm_modifyreg + * + * Description: + * Modify PWM register (32-bit or 16-bit) + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pwm_modifyreg(struct stm32_pwmtimer_s *priv, uint32_t offset, + uint32_t clearbits, uint32_t setbits) +{ + + if (pwm_reg_is_32bit(priv->timtype, offset) == true) + { + /* 32-bit register */ + + modifyreg32(priv->base + offset, clearbits, setbits); + } + else + { + /* 16-bit register */ + + modifyreg16(priv->base + offset, (uint16_t)clearbits, (uint16_t)setbits); } } @@ -1123,7 +1890,7 @@ static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg) pwm_getreg(priv, STM32_GTIM_DIER_OFFSET)); } - if (priv->timid >= 15 || priv->timid <= 17) + if (priv->timid >= 15 && priv->timid <= 17) { pwminfo(" SR: %04x EGR: %04x CCMR1: %04x\n", pwm_getreg(priv, STM32_GTIM_SR_OFFSET), @@ -1147,7 +1914,7 @@ static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg) pwm_getreg(priv, STM32_GTIM_PSC_OFFSET), pwm_getreg(priv, STM32_GTIM_ARR_OFFSET)); - if (priv->timid >= 15 || priv->timid <= 17) + if (priv->timid == 1 || priv->timid == 8 || (priv->timid >= 15 && priv->timid <= 17)) { pwminfo(" RCR: %04x BDTR: %04x\n", pwm_getreg(priv, STM32_ATIM_RCR_OFFSET), @@ -1161,6 +1928,12 @@ static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg) pwminfo(" CCR1: %04x\n", pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET)); } + else if (priv->timid == 15) + { + pwminfo(" CCR1: %04x CCR2: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR2_OFFSET)); + } else { pwminfo(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", @@ -1177,83 +1950,241 @@ static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg) #endif /**************************************************************************** - * Name: pwm_timer + * Name: pwm_ccr_update + ****************************************************************************/ + +static int pwm_ccr_update(FAR struct pwm_lowerhalf_s *dev, uint8_t index, + uint32_t ccr) + +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint32_t offset; + + /* Only ADV timers have CC5 and CC6 */ + +#ifdef HAVE_IP_TIMERS_V2 + if (priv->timtype != TIMTYPE_ADVANCED && (index == 5 || index == 6)) + { + pwmerr("ERROR: No such CCR: %u\n", index); + return -EINVAL; + } +#endif + + switch (index) + { + case 1: + { + offset = STM32_GTIM_CCR1_OFFSET; + break; + } + + case 2: + { + offset = STM32_GTIM_CCR2_OFFSET; + break; + } + + case 3: + { + offset = STM32_GTIM_CCR3_OFFSET; + break; + } + + case 4: + { + offset = STM32_GTIM_CCR4_OFFSET; + break; + } + +#ifdef HAVE_IP_TIMERS_V2 + case 5: + { + offset = STM32_ATIM_CCR5_OFFSET; + break; + } + + case 6: + { + offset = STM32_ATIM_CCR6_OFFSET; + break; + } +#endif + + default: + { + pwmerr("ERROR: No such CCR: %u\n", index); + return -EINVAL; + } + } + + /* Update CCR register */ + + pwm_putreg(priv, offset, ccr); + + return OK; +} + +/**************************************************************************** + * Name: pwm_ccr_get + ****************************************************************************/ + +#ifdef CONFIG_STM32_PWM_LL_OPS +static uint32_t pwm_ccr_get(FAR struct pwm_lowerhalf_s *dev, uint8_t index) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint32_t offset; + + switch (index) + { + case 1: + { + offset = STM32_GTIM_CCR1_OFFSET; + break; + } + + case 2: + { + offset = STM32_GTIM_CCR2_OFFSET; + break; + } + + case 3: + { + offset = STM32_GTIM_CCR3_OFFSET; + break; + } + + case 4: + { + offset = STM32_GTIM_CCR4_OFFSET; + break; + } + +#ifdef HAVE_IP_TIMERS_V2 + case 5: + { + offset = STM32_ATIM_CCR5_OFFSET; + break; + } + + case 6: + { + offset = STM32_ATIM_CCR6_OFFSET; + break; + } +#endif + + default: + { + pwmerr("ERROR: No such CCR: %u\n", index); + return -EINVAL; + } + } + + /* Return CCR register */ + + return pwm_getreg(priv, offset); +} +#endif /* CONFIG_STM32_PWM_LL_OPS */ + +/**************************************************************************** + * Name: pwm_arr_update + ****************************************************************************/ + +static int pwm_arr_update(FAR struct pwm_lowerhalf_s *dev, uint32_t arr) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + /* Update ARR register */ + + pwm_putreg(priv, STM32_GTIM_ARR_OFFSET, arr); + + return OK; +} + +/**************************************************************************** + * Name: pwm_arr_get + ****************************************************************************/ + +static uint32_t pwm_arr_get(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + return pwm_getreg(priv, STM32_GTIM_ARR_OFFSET); +} + +/**************************************************************************** + * Name: pwm_duty_update * * Description: - * (Re-)initialize the timer resources and start the pulsed output + * Try to change only channel duty * * Input Parameters: - * priv - A reference to the lower half PWM driver state structure - * info - A reference to the characteristics of the pulsed output + * dev - A reference to the lower half PWM driver state structure + * channel - Channel to by updated + * duty - New duty * * Returned Value: * Zero on success; a negated errno value on failure * ****************************************************************************/ -static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, - FAR const struct pwm_info_s *info) +static int pwm_duty_update(FAR struct pwm_lowerhalf_s *dev, uint8_t channel, + ub16_t duty) { -#ifdef CONFIG_PWM_MULTICHAN - int i; -#endif - - /* Calculated values */ - - uint32_t prescaler; - uint32_t timclk; + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; uint32_t reload; uint32_t ccr; - /* Register contents */ + /* We don't want compilation warnings if no DEBUGASSERT */ - uint16_t cr1; - uint16_t ccer; - uint16_t cr2; -#ifdef CONFIG_STM32_STM32F30XX - uint32_t ccmr1; - uint32_t ccmr2; -#else - uint16_t ccmr1; - uint16_t ccmr2; -#endif + UNUSED(priv); - /* New timer regiser bit settings */ + DEBUGASSERT(priv != NULL); - uint16_t ccenable; -#ifdef CONFIG_STM32_STM32F30XX - uint32_t ocmode1; - uint32_t ocmode2; -#else - uint16_t ocmode1; - uint16_t ocmode2; -#endif + pwminfo("TIM%u channel: %u duty: %08x\n", + priv->timid, channel, duty); - DEBUGASSERT(priv != NULL && info != NULL); - -#if defined(CONFIG_PWM_MULTICHAN) - pwminfo("TIM%u frequency: %u\n", - priv->timid, info->frequency); -#elif defined(CONFIG_PWM_PULSECOUNT) - pwminfo("TIM%u channel: %u frequency: %u duty: %08x count: %u\n", - priv->timid, priv->channels[0].channel, info->frequency, - info->duty, info->count); -#else - pwminfo("TIM%u channel: %u frequency: %u duty: %08x\n", - priv->timid, priv->channels[0].channel, info->frequency, info->duty); -#endif - - DEBUGASSERT(info->frequency > 0); #ifndef CONFIG_PWM_MULTICHAN - DEBUGASSERT(info->duty >= 0 && info->duty < uitoub16(100)); + DEBUGASSERT(channel == priv->channels[0].channel); + DEBUGASSERT(duty >= 0 && duty < uitoub16(100)); #endif - /* Disable all interrupts and DMA requests, clear all pending status */ + /* Get the reload values */ -#ifdef CONFIG_PWM_PULSECOUNT - pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, 0); - pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0); -#endif + reload = pwm_arr_get(dev); + + /* Duty cycle: + * + * duty cycle = ccr / reload (fractional value) + */ + + ccr = b16toi(duty * reload + b16HALF); + + pwminfo("ccr: %u\n", ccr); + + /* Write coresponding CCR register */ + + pwm_ccr_update(dev, channel, ccr); + + return OK; +} + +/**************************************************************************** + * Name: pwm_frequency_update + * + * Description: + * Update a PWM timer frequency + * + ****************************************************************************/ + +static int pwm_frequency_update(FAR struct pwm_lowerhalf_s *dev, + uint32_t frequency) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint32_t reload = 0; + uint32_t timclk = 0; + uint32_t prescaler = 0; /* Calculate optimal values for the timer prescaler and for the timer reload * register. If 'frequency' is the desired frequency, then @@ -1288,7 +2219,7 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, * = 60,000 */ - prescaler = (priv->pclk / info->frequency + 65534) / 65535; + prescaler = (priv->pclk / frequency + 65534) / 65535; if (prescaler < 1) { prescaler = 1; @@ -1300,7 +2231,7 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, timclk = priv->pclk / prescaler; - reload = timclk / info->frequency; + reload = timclk / frequency; if (reload < 2) { reload = 1; @@ -1315,7 +2246,28 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, } pwminfo("TIM%u PCLK: %u frequency: %u TIMCLK: %u prescaler: %u reload: %u\n", - priv->timid, priv->pclk, info->frequency, timclk, prescaler, reload); + priv->timid, priv->pclk, frequency, timclk, prescaler, reload); + + /* Set the reload and prescaler values */ + + pwm_arr_update(dev, reload); + pwm_putreg(priv, STM32_GTIM_PSC_OFFSET, (uint16_t)(prescaler - 1)); + + return OK; +} + +/**************************************************************************** + * Name: pwm_timer_configure + * + * Description: + * Initial configuration for PWM timer + * + ****************************************************************************/ + +static int pwm_timer_configure(FAR struct stm32_pwmtimer_s *priv) +{ + uint16_t cr1 = 0; + int ret = OK; /* Set up the timer CR1 register: * @@ -1328,19 +2280,11 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, cr1 = pwm_getreg(priv, STM32_GTIM_CR1_OFFSET); - /* Disable the timer until we get it configured */ - - cr1 &= ~GTIM_CR1_CEN; - /* Set the counter mode for the advanced timers (1,8) and most general * purpose timers (all 2-5, but not 9-17), i.e., all but TIMTYPE_COUNTUP16 * and TIMTYPE_BASIC */ -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ - defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ - defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM8_PWM) - if (priv->timtype != TIMTYPE_BASIC && priv->timtype != TIMTYPE_COUNTUP16) { /* Select the Counter Mode: @@ -1357,428 +2301,841 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, switch (priv->mode) { case STM32_TIMMODE_COUNTUP: - cr1 |= GTIM_CR1_EDGE; - break; + { + cr1 |= GTIM_CR1_EDGE; + break; + } case STM32_TIMMODE_COUNTDOWN: - cr1 |= GTIM_CR1_EDGE | GTIM_CR1_DIR; - break; + { + cr1 |= GTIM_CR1_EDGE | GTIM_CR1_DIR; + break; + } case STM32_TIMMODE_CENTER1: - cr1 |= GTIM_CR1_CENTER1; - break; + { + cr1 |= GTIM_CR1_CENTER1; + break; + } case STM32_TIMMODE_CENTER2: - cr1 |= GTIM_CR1_CENTER2; - break; + { + cr1 |= GTIM_CR1_CENTER2; + break; + } case STM32_TIMMODE_CENTER3: - cr1 |= GTIM_CR1_CENTER3; - break; + { + cr1 |= GTIM_CR1_CENTER3; + break; + } default: - pwmerr("ERROR: No such timer mode: %u\n", (unsigned int)priv->mode); - return -EINVAL; + { + pwmerr("ERROR: No such timer mode: %u\n", + (unsigned int)priv->mode); + ret = -EINVAL; + goto errout; + } } } + + /* Enable ARR Preload + * TODO: this should be configurable + */ + + cr1 |= GTIM_CR1_ARPE; + + /* Write CR1 */ + + pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + +errout: + return ret; +} + +/**************************************************************************** + * Name: pwm_mode_configure + * + * Description: + * Configure a PWM mode for given channel + * + ****************************************************************************/ + +static int pwm_mode_configure(FAR struct stm32_pwmtimer_s *priv, uint8_t channel, + uint32_t mode) +{ + uint32_t chanmode = 0; + uint32_t ocmode1 = 0; + uint32_t ocmode2 = 0; + uint32_t ccmr1 = 0; + uint32_t ccmr2 = 0; + int ret = OK; +#ifdef HAVE_IP_TIMERS_V2 + bool ocmbit = false; #endif + /* Get channel mode + * TODO: configurable preload for CCxR + */ + + switch (mode) + { + case STM32_CHANMODE_PWM1: + { + chanmode = ATIM_CCMR_MODE_PWM1; + break; + } + + case STM32_CHANMODE_PWM2: + { + chanmode = ATIM_CCMR_MODE_PWM2; + break; + } + +#ifdef HAVE_IP_TIMERS_V2 + case STM32_CHANMODE_COMBINED1: + { + chanmode = ATIM_CCMR_MODE_COMBINED1; + ocmbit = true; + break; + } + + case STM32_CHANMODE_COMBINED2: + { + chanmode = ATIM_CCMR_MODE_COMBINED2; + ocmbit = true; + break; + } + + case STM32_CHANMODE_ASYMMETRIC1: + { + chanmode = ATIM_CCMR_MODE_ASYMMETRIC1; + ocmbit = true; + break; + } + + case STM32_CHANMODE_ASYMMETRIC2: + { + chanmode = ATIM_CCMR_MODE_ASYMMETRIC2; + ocmbit = true; + break; + } +#endif + + default: + { + pwmerr("ERROR: No such mode: %u\n", (unsigned int)mode); + ret = -EINVAL; + goto errout; + } + } + + /* Get current registers */ + + ccmr1 = pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET); + ccmr2 = pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET); + + switch (channel) + { + case 1: /* PWM Mode configuration: Channel 1 */ + { + /* Reset current channel 1 mode configuration */ + + ccmr1 &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK | ATIM_CCMR1_OC1PE); + + /* Set the CCMR1 mode values (leave CCMR2 zero) */ + + ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) + | (chanmode << ATIM_CCMR1_OC1M_SHIFT) | ATIM_CCMR1_OC1PE; + +#ifdef HAVE_IP_TIMERS_V2 + /* Reset current OC bit */ + + ccmr1 &= ~(ATIM_CCMR1_OC1M); + + if (ocmbit) + { + ocmode1 |= ATIM_CCMR1_OC1M; + } +#endif + break; + } + + case 2: /* PWM Mode configuration: Channel 2 */ + { + /* Reset current channel 2 mode configuration */ + + ccmr1 &= ~(ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK | ATIM_CCMR1_OC2PE); + + /* Set the CCMR1 mode values (leave CCMR2 zero) */ + + ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) + | (chanmode << ATIM_CCMR1_OC2M_SHIFT) | ATIM_CCMR1_OC2PE; + +#ifdef HAVE_IP_TIMERS_V2 + /* Reset current OC bit */ + + ccmr1 &= ~(ATIM_CCMR1_OC2M); + + if (ocmbit) + { + ocmode1 |= ATIM_CCMR1_OC2M; + } +#endif + break; + } + + case 3: /* PWM Mode configuration: Channel 3 */ + { + /* Reset current channel 3 mode configuration */ + + ccmr2 &= ~(ATIM_CCMR2_CC3S_MASK | ATIM_CCMR2_OC3M_MASK | ATIM_CCMR2_OC3PE); + + /* Set the CCMR2 mode values (leave CCMR1 zero) */ + + ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) + | (chanmode << ATIM_CCMR2_OC3M_SHIFT) | ATIM_CCMR2_OC3PE; + +#ifdef HAVE_IP_TIMERS_V2 + /* Reset current OC bit */ + + ccmr2 &= ~(ATIM_CCMR2_OC3M); + + if (ocmbit) + { + ocmode2 |= ATIM_CCMR2_OC3M; + } +#endif + break; + } + + case 4: /* PWM Mode configuration: Channel 4 */ + { + /* Reset current channel 4 mode configuration */ + + ccmr2 &= ~(ATIM_CCMR2_CC4S_MASK | ATIM_CCMR2_OC4M_MASK | ATIM_CCMR2_OC4PE); + + /* Set the CCMR2 mode values (leave CCMR1 zero) */ + + ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC4S_SHIFT) + | (chanmode << ATIM_CCMR2_OC4M_SHIFT) | ATIM_CCMR2_OC4PE; + +#ifdef HAVE_IP_TIMERS_V2 + /* Reset current OC bit */ + + ccmr2 &= ~(ATIM_CCMR2_OC4M); + + if (ocmbit) + { + ocmode2 |= ATIM_CCMR2_OC4M; + } +#endif + break; + } + + default: + { + pwmerr("ERROR: No such channel: %u\n", channel); + ret = -EINVAL; + goto errout; + } + } + + /* Set the selected output compare mode */ + + ccmr1 |= ocmode1; + ccmr2 |= ocmode2; + + /* Write CCMR1 and CCMR2 registers */ + + pwm_putreg(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); + pwm_putreg(priv, STM32_GTIM_CCMR2_OFFSET, ccmr2); + +errout: + return ret; +} + +/**************************************************************************** + * Name: pwm_output_configure + * + * Description: + * Configure PWM output for given channel + * + ****************************************************************************/ + +static int pwm_output_configure(FAR struct stm32_pwmtimer_s *priv, uint8_t channel) +{ + uint32_t cr2 = 0; + uint32_t ccer = 0; + + /* Get current registers state */ + + cr2 = pwm_getreg(priv, STM32_GTIM_CR2_OFFSET); + ccer = pwm_getreg(priv, STM32_GTIM_CCER_OFFSET); + + /* | OISx/OISxN | IDLE | for ADVANCED and COUNTUP16 | CR2 register + * | CCxP/CCxNP | POL | all PWM timers | CCER register + */ + + /* Configure output polarity (all PWM timers) */ + + if (priv->channels[channel-1].out1.pol & STM32_POL_POS) + { + ccer |= (GTIM_CCER_CC1P << ((channel-1)*4)); + } + else + { + ccer &= ~(GTIM_CCER_CC1P << ((channel-1)*4)); + } + +#ifdef HAVE_ADVTIM + if (priv->timtype == TIMTYPE_ADVANCED || priv->timtype == TIMTYPE_COUNTUP16_N) + { + /* Configure output IDLE State */ + + if (priv->channels[channel-1].out1.idle & STM32_IDLE_ACTIVE) + { + cr2 |= (ATIM_CR2_OIS1 << ((channel-1)*2)); + } + else + { + cr2 &= ~(ATIM_CR2_OIS1 << ((channel-1)*2)); + } + +#ifdef HAVE_COMPLEMENTARY + /* Configure complementary output IDLE state */ + + if (priv->channels[channel-1].out2.idle & STM32_IDLE_ACTIVE) + { + cr2 |= (ATIM_CR2_OIS1N << ((channel-1)*2)); + } + else + { + cr2 &= ~(ATIM_CR2_OIS1N << ((channel-1)*2)); + } + + /* Configure complementary output polarity */ + + if (priv->channels[channel-1].out2.pol & STM32_POL_POS) + { + ccer |= (ATIM_CCER_CC1NP << ((channel-1)*4)); + } + else + { + ccer &= ~(ATIM_CCER_CC1NP << ((channel-1)*4)); + } +#endif /* HAVE_COMPLEMENTARY */ + +#ifdef HAVE_IP_TIMERS_V2 + /* TODO: OIS5 and OIS6 */ + + cr2 &= ~(ATIM_CR2_OIS5 | ATIM_CR2_OIS6); + + /* TODO: CC5P and CC6P */ + + ccer &= ~(ATIM_CCER_CC5P | ATIM_CCER_CC6P); +#endif /* HAVE_IP_TIMERS_V2 */ + } +#ifdef HAVE_GTIM_CCXNP + else +#endif /* HAVE_GTIM_CCXNP */ +#endif /* HAVE_ADVTIM */ +#ifdef HAVE_GTIM_CCXNP + { + /* CCxNP must be cleared if not ADVANCED timer. + * + * REVISIT: not all families have CCxNP bits for GTIM, + * which causes an ugly condition above + */ + + ccer &= ~(GTIM_CCER_CC1NP << ((channel-1)*4)); + } +#endif /* HAVE_GTIM_CCXNP */ + + /* Write registers */ + + pwm_modifyreg(priv, STM32_GTIM_CR2_OFFSET, 0, cr2); + pwm_modifyreg(priv, STM32_GTIM_CCER_OFFSET, 0, ccer); + + return OK; +} + +/**************************************************************************** + * Name: pwm_outputs_enable + * + * Description: + * Enable/disable given timer PWM outputs. + * + * NOTE: This is bulk operation - we can enable/disable many outputs + * at one time + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * outputs - outputs to set (look at enum stm32_chan_e in stm32_pwm.h) + * state - Enable/disable operation + * +****************************************************************************/ + +static int pwm_outputs_enable(FAR struct pwm_lowerhalf_s *dev, uint16_t outputs, + bool state) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + uint32_t ccer = 0; + uint32_t regval = 0; + + /* Get curren register state */ + + ccer = pwm_getreg(priv, STM32_GTIM_CCER_OFFSET); + + /* Get outputs configuration */ + + regval |= ((outputs & STM32_CHAN1) ? ATIM_CCER_CC1E : 0); + regval |= ((outputs & STM32_CHAN1N) ? ATIM_CCER_CC1NE : 0); + regval |= ((outputs & STM32_CHAN2) ? ATIM_CCER_CC2E : 0); + regval |= ((outputs & STM32_CHAN2N) ? ATIM_CCER_CC2NE : 0); + regval |= ((outputs & STM32_CHAN3) ? ATIM_CCER_CC3E : 0); + regval |= ((outputs & STM32_CHAN3N) ? ATIM_CCER_CC3NE : 0); + regval |= ((outputs & STM32_CHAN4) ? ATIM_CCER_CC4E : 0); + /* NOTE: CC4N does not exist, but some docs show configuration bits for it */ +#ifdef HAVE_IP_TIMERS_V2 + regval |= ((outputs & STM32_CHAN5) ? ATIM_CCER_CC5E : 0); + regval |= ((outputs & STM32_CHAN6) ? ATIM_CCER_CC6E : 0); +#endif + + if (state == true) + { + /* Enable outpus - set bits */ + + ccer |= regval; + } + else + { + /* Disable outputs - reset bits */ + + ccer &= ~regval; + } + + /* Write register */ + + pwm_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); + + return OK; +} + +#ifdef HAVE_COMPLEMENTARY +/**************************************************************************** + * Name: pwm_deadtime_configure + * + * Description: + * Configure a PWM deadtime for given timer + * + ****************************************************************************/ + +static int pwm_deadtime_configure(FAR struct stm32_pwmtimer_s *priv) +{ /* Set the clock division to zero for all (but the basic timers, but there * should be no basic timers in this context */ - cr1 &= ~GTIM_CR1_CKD_MASK; - pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CKD_MASK, + priv->t_dts<deadtime); - /* Set the advanced timer's repetition counter */ + return OK; +} -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) - if (priv->timtype == TIMTYPE_ADVANCED) +/**************************************************************************** + * Name: pwm_deadtime_update + ****************************************************************************/ + +static int pwm_deadtime_update(FAR struct stm32_pwmtimer_s *priv, uint8_t dt) +{ + uint32_t bdtr = 0; + + /* Get current register state */ + + bdtr = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); + + /* TODO: check if BDTR not locked */ + + /* Update deadtime */ + + bdtr &= ~(ATIM_BDTR_DTG_MASK); + bdtr |= (dt << ATIM_BDTR_DTG_SHIFT); + + /* Write BDTR register */ + + pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, bdtr); + + return OK; +} +#endif + +/**************************************************************************** + * Name: pwm_break_configure + * + * Description: + * Configure a PWM break function for a given timer + * + ****************************************************************************/ + +#ifdef HAVE_ADVTIM +static int pwm_break_configure(FAR struct stm32_pwmtimer_s *priv) +{ + uint32_t bdtr = 0; + + /* Get current register state */ + + bdtr = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); + + /* TODO: Configure BRK */ + +#ifdef HAVE_IP_TIMERS_V2 + /* TODO: Configure BRK2 */ + + /* TODO: Configure BRK and BRK2 filters */ +#endif + + /* Set the main output enable (MOE) bit and clear the OSSI and OSSR + * bits in the BDTR register. + * + * REVISIT: not sure if it belongs here + */ + + bdtr |= ATIM_BDTR_MOE; + bdtr &= ~(ATIM_BDTR_OSSI | ATIM_BDTR_OSSR); + + /* Write BDTR register */ + + pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, bdtr); + + return OK; +} +#endif + +/**************************************************************************** + * Name: pwm_sync_configure + * + * Description: + * Confiugre an output synchronisation event for PWM timer (TRGO/TRGO2) + * + ****************************************************************************/ + +#ifdef HAVE_TRGO +static int pwm_sync_configure(FAR struct stm32_pwmtimer_s *priv, uint8_t trgo) +{ + uint32_t cr2 = 0; + + /* Configure TRGO (4 LSB in trgo) */ + + cr2 |= (trgo & ATIM_CR2_MMS_MASK) << ATIM_CR2_MMS_SHIFT; + +#ifdef HAVE_IP_TIMERS_V2 + /* Configure TRGO2 (4 MSB in trgo)*/ + + cr2 |= ((trgo>>4) & ATIM_CR2_MMS2_MASK) << ATIM_CR2_MMS2_SHIFT; +#endif + + /* Write register */ + + pwm_modifyreg(priv, STM32_GTIM_CR2_OFFSET, 0, cr2); + + return OK; +} +#endif + +/**************************************************************************** + * Name: pwm_soft_update + * + * Description: + * Generate an software update event + * + ****************************************************************************/ + +static int pwm_soft_update(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + + return OK; +} + +/**************************************************************************** + * Name: pwm_outputs_from_channels + * + * Description: + * Get enabled outputs configuration from the PWM timer state + * + ****************************************************************************/ + +static uint16_t pwm_outputs_from_channels(FAR struct stm32_pwmtimer_s *priv) +{ + uint16_t outputs = 0; + uint8_t channel = 0; + uint8_t i = 0; + + for(i = 0; i < priv->chan_num; i += 1) { - /* If a non-zero repetition count has been selected, then set the - * repitition counter to the count-1 (pwm_start() has already - * assured us that the count value is within range). - */ + /* Get channel */ + + channel = priv->channels[i].channel; + + /* Set outputs if channel configured */ + + if (channel != 0) + { + /* Enable output if confiugred */ + + if (priv->channels[i].out1.in_use == 1) + { + outputs |= (STM32_CHAN1 << ((channel-1)*2)); + } + +#ifdef HAVE_COMPLEMENTARY + /* Enable complementary output if configured */ + + if (priv->channels[i].out2.in_use == 1) + { + outputs |= (STM32_CHAN1N << ((channel-1)*2)); + } +#endif + } + } + + return outputs; +} #ifdef CONFIG_PWM_PULSECOUNT - if (info->count > 0) - { - /* Save the remaining count and the number of counts that will have - * elapsed on the first interrupt. - */ - /* If the first interrupt occurs at the end end of the first - * repetition count, then the count will be the same as the RCR - * value. - */ +/**************************************************************************** + * Name: pwm_pulsecount_configure + * + * Description: + * Configure PWM timer in PULSECOUNT mode + * + ****************************************************************************/ - priv->prev = pwm_pulsecount(info->count); - pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->prev - 1); +static int pwm_pulsecount_configure(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint16_t outputs = 0; + uint8_t j = 0; + int ret = OK; - /* Generate an update event to reload the prescaler. This should - * preload the RCR into active repetition counter. - */ + UNUSED(priv); - pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + /* NOTE: leave timer counter disabled and all outputs disabled! */ - /* Now set the value of the RCR that will be loaded on the next - * update event. - */ + /* Disable the timer until we get it configured */ - priv->count = info->count; - priv->curr = pwm_pulsecount(info->count - priv->prev); - pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->curr - 1); - } + pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0); - /* Otherwise, just clear the repetition counter */ + /* Get configured outputs */ - else + outputs = pwm_outputs_from_channels(priv); + + /* REVISIT: Disable outputs */ + + ret = pwm_outputs_enable(dev, outputs, false); + if (ret < 0) + { + goto errout; + } + + /* Initial timer configuration */ + + ret = pwm_timer_configure(priv); + if (ret < 0) + { + goto errout; + } + +#ifdef HAVE_COMPLEMENTARY + /* Configure deadtime */ + + ret = pwm_deadtime_configure(priv); + if (ret < 0) + { + goto errout; + } #endif + + /* Configure break */ + + ret = pwm_break_configure(priv); + if (ret < 0) + { + goto errout; + } + + /* Configure TRGO/TRGO2 */ +#ifdef HAVE_TRGO + ret = pwm_sync_configure(priv, trgo); + if (ret < 0) + { + goto errout; + } +#endif + + /* Configure timer channels */ + + for (j = 0; j < priv->chan_num; j++) + { + /* Skip channle if not in use */ + + if (priv->channels[j].channel != 0) { - /* Set the repetition counter to zero */ + /* Update PWM mode */ - pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, 0); + pwm_mode_configure(priv, priv->channels[j].channel, priv->channels[j].mode); - /* Generate an update event to reload the prescaler */ + /* PWM outputs configuration */ - pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + pwm_output_configure(priv, priv->channels[j].channel); } } + +errout: + return ret; +} + +/**************************************************************************** + * Name: pwm_pulsecount_timer + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * TODO: PWM_PULSECOUNT should be configurable for each timer instance + * TODO: PULSECOUNT doesnt work with MULTICHAN at this moment + * + ****************************************************************************/ + +static int pwm_pulsecount_timer(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + ub16_t duty = 0; + uint8_t channel = 0; + uint32_t mode = 0; + uint16_t outputs = 0; + int ret = OK; + + /* If we got here it means that timer instance support pulsecount mode! */ + + DEBUGASSERT(priv != NULL && info != NULL); + + pwminfo("TIM%u channel: %u frequency: %u duty: %08x count: %u\n", + priv->timid, priv->channels[0].channel, info->frequency, + info->duty, info->count); + + DEBUGASSERT(info->frequency > 0); + + /* Channel specific setup */ + + duty = info->duty; + channel = priv->channels[0].channel; + mode = priv->channels[0].mode; + + /* Disable all interrupts and DMA requests, clear all pending status */ + + pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, 0); + pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0); + + /* Set timer frequency */ + + ret = pwm_frequency_update(dev, info->frequency); + if (ret < 0) + { + goto errout; + } + + /* Update duty cycle */ + + ret = pwm_duty_update(dev, channel, duty); + if (ret < 0) + { + goto errout; + } + + /* If a non-zero repetition count has been selected, then set the + * repitition counter to the count-1 (pwm_pulsecount_start() has already + * assured us that the count value is within range). + */ + + if (info->count > 0) + { + /* Save the remaining count and the number of counts that will have + * elapsed on the first interrupt. + */ + + /* If the first interrupt occurs at the end end of the first + * repetition count, then the count will be the same as the RCR + * value. + */ + + priv->prev = pwm_pulsecount(info->count); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->prev - 1); + + /* Generate an update event to reload the prescaler. This should + * preload the RCR into active repetition counter. + */ + + pwm_soft_update(dev); + +#if 0 + /* Now set the value of the RCR that will be loaded on the next + * update event. + */ + + priv->count = info->count; + priv->curr = pwm_pulsecount(info->count - priv->prev); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->curr - 1); +#endif + } + + /* Otherwise, just clear the repetition counter */ + else -#endif { - /* Generate an update event to reload the prescaler (all timers) */ + /* Set the repetition counter to zero */ - pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG); + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, 0); + + /* Generate an update event to reload the prescaler */ + + pwm_soft_update(dev); } - /* Handle channel specific setup */ + /* Get configured outputs */ - ccenable = 0; - ocmode1 = 0; - ocmode2 = 0; + outputs = pwm_outputs_from_channels(priv); -#ifdef CONFIG_PWM_MULTICHAN - for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) -#endif + /* Enable output */ + + ret = pwm_outputs_enable(dev, outputs, true); + if (ret < 0) { - ub16_t duty; -#ifdef CONFIG_STM32_STM32F30XX - uint32_t chanmode; - bool ocmbit = false; -#else - uint16_t chanmode; -#endif - uint8_t channel; -#ifdef CONFIG_PWM_MULTICHAN - int j; -#endif - enum stm32_chanmode_e mode; - -#ifdef CONFIG_PWM_MULTICHAN - duty = info->channels[i].duty; - channel = info->channels[i].channel; - - /* A value of zero means to skip this channel */ - - if (channel == 0) - { - continue; - } - - /* Find the channel */ - - for (j = 0; j < PWM_NCHANNELS; j++) - { - if (priv->channels[j].channel == channel) - { - mode = priv->channels[j].mode; - break; - } - } - - if (j >= PWM_NCHANNELS) - { - pwmerr("ERROR: No such channel: %u\n", channel); - return -EINVAL; - } -#else - duty = info->duty; - channel = priv->channels[0].channel; - mode = priv->channels[0].mode; -#endif - - /* Duty cycle: - * - * duty cycle = ccr / reload (fractional value) - */ - - ccr = b16toi(duty * reload + b16HALF); - - pwminfo("ccr: %u\n", ccr); - - switch (mode) - { - case STM32_CHANMODE_PWM1: - chanmode = ATIM_CCMR_MODE_PWM1; - break; - - case STM32_CHANMODE_PWM2: - chanmode = ATIM_CCMR_MODE_PWM2; - break; - -#ifdef CONFIG_STM32_STM32F30XX - case STM32_CHANMODE_COMBINED1: - chanmode = ATIM_CCMR_MODE_COMBINED1; - ocmbit = true; - break; - - case STM32_CHANMODE_COMBINED2: - chanmode = ATIM_CCMR_MODE_COMBINED2; - ocmbit = true; - break; - - case STM32_CHANMODE_ASYMMETRIC1: - chanmode = ATIM_CCMR_MODE_ASYMMETRIC1; - ocmbit = true; - break; - - case STM32_CHANMODE_ASYMMETRIC2: - chanmode = ATIM_CCMR_MODE_ASYMMETRIC2; - ocmbit = true; - break; -#endif - - default: - pwmerr("ERROR: No such mode: %u\n", (unsigned int)mode); - return -EINVAL; - } - - switch (channel) - { - case 1: /* PWM Mode configuration: Channel 1 */ - { - /* Select the CCER enable bit for this channel */ - - ccenable |= ATIM_CCER_CC1E; - - /* Set the CCMR1 mode values (leave CCMR2 zero) */ - - ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) | - (chanmode << ATIM_CCMR1_OC1M_SHIFT) | - ATIM_CCMR1_OC1PE; - -#ifdef CONFIG_STM32_STM32F30XX - if (ocmbit) - { - ocmode1 |= ATIM_CCMR1_OC1M; - } -#endif - - /* Set the duty cycle by writing to the CCR register for this channel */ - - pwm_putreg(priv, STM32_GTIM_CCR1_OFFSET, (uint16_t)ccr); - } - break; - - case 2: /* PWM Mode configuration: Channel 2 */ - { - /* Select the CCER enable bit for this channel */ - - ccenable |= ATIM_CCER_CC2E; - - /* Set the CCMR1 mode values (leave CCMR2 zero) */ - - ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) | - (chanmode << ATIM_CCMR1_OC2M_SHIFT) | - ATIM_CCMR1_OC2PE; - -#ifdef CONFIG_STM32_STM32F30XX - if (ocmbit) - { - ocmode1 |= ATIM_CCMR1_OC2M; - } -#endif - - /* Set the duty cycle by writing to the CCR register for this channel */ - - pwm_putreg(priv, STM32_GTIM_CCR2_OFFSET, (uint16_t)ccr); - } - break; - - case 3: /* PWM Mode configuration: Channel 3 */ - { - /* Select the CCER enable bit for this channel */ - - ccenable |= ATIM_CCER_CC3E; - - /* Set the CCMR2 mode values (leave CCMR1 zero) */ - - ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) | - (chanmode << ATIM_CCMR2_OC3M_SHIFT) | - ATIM_CCMR2_OC3PE; - -#ifdef CONFIG_STM32_STM32F30XX - if (ocmbit) - { - ocmode2 |= ATIM_CCMR2_OC3M; - } -#endif - - /* Set the duty cycle by writing to the CCR register for this channel */ - - pwm_putreg(priv, STM32_GTIM_CCR3_OFFSET, (uint16_t)ccr); - } - break; - - case 4: /* PWM Mode configuration: Channel 4 */ - { - /* Select the CCER enable bit for this channel */ - - ccenable |= ATIM_CCER_CC4E; - - /* Set the CCMR2 mode values (leave CCMR1 zero) */ - - ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC4S_SHIFT) | - (chanmode << ATIM_CCMR2_OC4M_SHIFT) | - ATIM_CCMR2_OC4PE; - -#ifdef CONFIG_STM32_STM32F30XX - if (ocmbit) - { - ocmode2 |= ATIM_CCMR2_OC4M; - } -#endif - - /* Set the duty cycle by writing to the CCR register for this channel */ - - pwm_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)ccr); - } - break; - - default: - pwmerr("ERROR: No such channel: %u\n", channel); - return -EINVAL; - } + goto errout; } - /* Disable the Channel by resetting the CCxE Bit in the CCER register */ - - ccer = pwm_getreg(priv, STM32_GTIM_CCER_OFFSET); - ccer &= ~ccenable; - pwm_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); - - /* Fetch the CR2, CCMR1, and CCMR2 register (already have cr1 and ccer) */ - - cr2 = pwm_getreg(priv, STM32_GTIM_CR2_OFFSET); - ccmr1 = pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET); - ccmr2 = pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET); - - /* Reset the Output Compare Mode Bits and set the select output compare mode */ - - ccmr1 &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK | ATIM_CCMR1_OC1PE | - ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK | ATIM_CCMR1_OC2PE -#ifdef CONFIG_STM32_STM32F30XX - | ATIM_CCMR1_OC1M | ATIM_CCMR1_OC2M -#endif - ); - ccmr2 &= ~(ATIM_CCMR2_CC3S_MASK | ATIM_CCMR2_OC3M_MASK | ATIM_CCMR2_OC3PE | - ATIM_CCMR2_CC4S_MASK | ATIM_CCMR2_OC4M_MASK | ATIM_CCMR2_OC4PE -#ifdef CONFIG_STM32_STM32F30XX - | ATIM_CCMR2_OC3M | ATIM_CCMR2_OC4M -#endif - ); - ccmr1 |= ocmode1; - ccmr2 |= ocmode2; - - /* Reset the output polarity level of all channels (selects high polarity)*/ - - ccer &= ~(ATIM_CCER_CC1P | ATIM_CCER_CC2P | ATIM_CCER_CC3P | ATIM_CCER_CC4P); - - /* Enable the output state of the selected channels */ - - ccer &= ~(ATIM_CCER_CC1E | ATIM_CCER_CC2E | ATIM_CCER_CC3E | ATIM_CCER_CC4E); - ccer |= ccenable; - - /* Some special setup for advanced timers */ - -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ - defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ - defined(CONFIG_STM32_TIM17_PWM) - if (priv->timtype == TIMTYPE_ADVANCED || priv->timtype == TIMTYPE_COUNTUP16) - { - uint16_t bdtr; - - /* Reset output N polarity level, output N state, output compare state, - * output compare N idle state. - */ - -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F4XXX) - ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | - ATIM_CCER_CC3NE | ATIM_CCER_CC3NP | ATIM_CCER_CC4NP); -#else - ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | - ATIM_CCER_CC3NE | ATIM_CCER_CC3NP); -#endif - - /* Reset the output compare and output compare N IDLE State */ - - cr2 &= ~(ATIM_CR2_OIS1 | ATIM_CR2_OIS1N | ATIM_CR2_OIS2 | ATIM_CR2_OIS2N | - ATIM_CR2_OIS3 | ATIM_CR2_OIS3N | ATIM_CR2_OIS4); - - /* Set the main output enable (MOE) bit and clear the OSSI and OSSR - * bits in the BDTR register. - */ - - bdtr = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); - bdtr &= ~(ATIM_BDTR_OSSI | ATIM_BDTR_OSSR); - bdtr |= ATIM_BDTR_MOE; - pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, bdtr); - } -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F4XXX) - else -#endif -#endif -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F4XXX) - { - /* CCxNP must be cleared in any case */ - - ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP | GTIM_CCER_CC4NP); - } -#endif - - /* Save the modified register values */ - - pwm_putreg(priv, STM32_GTIM_CR2_OFFSET, cr2); -#ifdef CONFIG_STM32_STM32F30XX - putreg32(ccmr1, priv->base + STM32_GTIM_CCMR1_OFFSET); - putreg32(ccmr2, priv->base + STM32_GTIM_CCMR2_OFFSET); -#else - pwm_putreg(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1); - pwm_putreg(priv, STM32_GTIM_CCMR2_OFFSET, ccmr2); -#endif - pwm_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer); - - /* Set the ARR Preload Bit */ - - cr1 = pwm_getreg(priv, STM32_GTIM_CR1_OFFSET); - cr1 |= GTIM_CR1_ARPE; - pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); - /* Setup update interrupt. If info->count is > 0, then we can be - * assured that pwm_start() has already verified: (1) that this is an + * assured that pwm_pulsecount_start() has already verified: (1) that this is an * advanced timer, and that (2) the repetition count is within range. */ -#ifdef CONFIG_PWM_PULSECOUNT if (info->count > 0) { /* Clear all pending interrupts and enable the update interrupt. */ @@ -1788,108 +3145,301 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, /* Enable the timer */ - cr1 |= GTIM_CR1_CEN; - pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); + pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN); /* And enable timer interrupts at the NVIC */ up_enable_irq(priv->irq); } - else -#endif - { - /* Just enable the timer, leaving all interrupts disabled */ - - cr1 |= GTIM_CR1_CEN; - pwm_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1); - } pwm_dumpregs(priv, "After starting"); + +errout: + return ret; +} + +#else /* !CONFIG_PWM_PULSECOUNT */ + +/**************************************************************************** + * Name: pwm_configure + * + * Description: + * Configure PWM timer in normal mode (no PULSECOUNT) + * + ****************************************************************************/ + +static int pwm_configure(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint16_t outputs = 0; + uint8_t j = 0; + int ret = OK; + + /* NOTE: leave timer counter disabled and all outputs disabled! */ + + /* Get configured outputs */ + + outputs = pwm_outputs_from_channels(priv); + + /* Disable outputs */ + + ret = pwm_outputs_enable(dev, outputs, false); + if (ret < 0) + { + goto errout; + } + + /* Disable the timer until we get it configured */ + + pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0); + + /* Initial timer configuration */ + + ret = pwm_timer_configure(priv); + if (ret < 0) + { + goto errout; + } + + /* Some special setup for advanced timers */ + +#ifdef HAVE_ADVTIM + if (priv->timtype == TIMTYPE_ADVANCED || priv->timtype == TIMTYPE_COUNTUP16_N) + { +#ifdef HAVE_COMPLEMENTARY + /* Configure deadtime */ + + ret = pwm_deadtime_configure(priv); + if (ret < 0) + { + goto errout; + } +#endif + + /* Configure break */ + + ret = pwm_break_configure(priv); + if (ret < 0) + { + goto errout; + } + + /* Configure TRGO/TRGO2 */ +#ifdef HAVE_TRGO + ret = pwm_sync_configure(priv, trgo); + if (ret < 0) + { + goto errout; + } +#endif + } +#endif + + /* Configure timer channels */ + + for (j = 0; j < priv->chan_num; j++) + { + /* Skip channle if not in use */ + + if (priv->channels[j].channel != 0) + { + + /* Update PWM mode */ + + ret = pwm_mode_configure(priv, priv->channels[j].channel, priv->channels[j].mode); + if (ret < 0) + { + goto errout; + } + + /* PWM outputs configuration */ + + ret = pwm_output_configure(priv, priv->channels[j].channel); + if (ret < 0) + { + goto errout; + } + } + } + +errout: + return ret; +} + +/**************************************************************************** + * Name: pwm_duty_channels_update + * + * Description: + * Update duty cycle for given channels + * + ****************************************************************************/ + +static int pwm_duty_channels_update(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint8_t channel = 0; + ub16_t duty = 0; + int ret = OK; +#ifdef CONFIG_PWM_MULTICHAN + int i = 0; + int j = 0; +#endif + +#ifdef CONFIG_PWM_MULTICHAN + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) +#endif + { +#ifdef CONFIG_PWM_MULTICHAN + duty = info->channels[i].duty; + channel = info->channels[i].channel; + + /* A value of zero means to skip this channel */ + + if (channel != 0) + { + /* Find the channel */ + + for (j = 0; j < priv->chan_num; j++) + { + if (priv->channels[j].channel == channel) + { + break; + } + } + + /* Check range */ + + if (j >= priv->chan_num) + { + pwmerr("ERROR: No such channel: %u\n", channel); + ret = -EINVAL; + goto errout; + } +#else + duty = info->duty; + channel = priv->channels[0].channel; +#endif + + /* Update duty cycle */ + + ret = pwm_duty_update(dev, channel, duty); + if (ret < 0) + { + goto errout; + } + } + } + +errout: return OK; } -#ifndef CONFIG_PWM_PULSECOUNT /**************************************************************************** - * Name: pwm_update_duty + * Name: pwm_timer * * Description: - * Try to change only channel duty. + * (Re-)initialize the timer resources and start the pulsed output * * Input Parameters: - * priv - A reference to the lower half PWM driver state structure - * channel - Channel to by updated - * duty - New duty. + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output * * Returned Value: * Zero on success; a negated errno value on failure * ****************************************************************************/ -static int pwm_update_duty(FAR struct stm32_pwmtimer_s *priv, uint8_t channel, - ub16_t duty) +static int pwm_timer(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) { - /* Register offset */ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + uint16_t outputs = 0; + int ret = OK; - int ccr_offset; + DEBUGASSERT(priv != NULL && info != NULL); - /* Calculated values */ - - uint32_t reload; - uint32_t ccr; - - DEBUGASSERT(priv != NULL); - - pwminfo("TIM%u channel: %u duty: %08x\n", - priv->timid, channel, duty); - -#ifndef CONFIG_PWM_MULTICHAN - DEBUGASSERT(channel == priv->channels[0].channel); - DEBUGASSERT(duty >= 0 && duty < uitoub16(100)); +#if defined(CONFIG_PWM_MULTICHAN) + pwminfo("TIM%u frequency: %u\n", + priv->timid, info->frequency); +#else + pwminfo("TIM%u channel: %u frequency: %u duty: %08x\n", + priv->timid, priv->channels[0].channel, info->frequency, info->duty); #endif - /* Get the reload values */ + DEBUGASSERT(info->frequency > 0); +#ifndef CONFIG_PWM_MULTICHAN + DEBUGASSERT(info->duty >= 0 && info->duty < uitoub16(100)); +#endif - reload = pwm_getreg(priv, STM32_GTIM_ARR_OFFSET); + /* TODO: what if we have pwm running and we want disable some channels ? */ - /* Duty cycle: - * - * duty cycle = ccr / reload (fractional value) - */ + /* Set timer frequency */ - ccr = b16toi(duty * reload + b16HALF); - - pwminfo("ccr: %u\n", ccr); - - switch (channel) + ret = pwm_frequency_update(dev, info->frequency); + if (ret < 0) { - case 1: /* Register offset for Channel 1 */ - ccr_offset = STM32_GTIM_CCR1_OFFSET; - break; - - case 2: /* Register offset for Channel 2 */ - ccr_offset = STM32_GTIM_CCR2_OFFSET; - break; - - case 3: /* Register offset for Channel 3 */ - ccr_offset = STM32_GTIM_CCR3_OFFSET; - break; - - case 4: /* Register offset for Channel 4 */ - ccr_offset = STM32_GTIM_CCR4_OFFSET; - break; - - default: - pwmerr("ERROR: No such channel: %u\n", channel); - return -EINVAL; + goto errout; } - /* Set the duty cycle by writing to the CCR register for this channel */ + /* Channel specific configuration */ - pwm_putreg(priv, ccr_offset, (uint16_t)ccr); + ret = pwm_duty_channels_update(dev, info); + if (ret < 0) + { + goto errout; + } - return OK; -} + /* Set the advanced timer's repetition counter */ + +#ifdef HAVE_ADVTIM + if (priv->timtype == TIMTYPE_ADVANCED || priv->timtype == TIMTYPE_COUNTUP16_N) + { + /* If a non-zero repetition count has been selected, then set the + * repitition counter to the count-1 (pwm_start() has already + * assured us that the count value is within range). + */ + + /* Set the repetition counter to zero */ + + pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, 0); + + /* Generate an update event to reload the prescaler */ + + pwm_soft_update(dev); + } + else #endif + { + /* Generate an update event to reload the prescaler (all timers) */ + + pwm_soft_update(dev); + } + + /* Get configured outputs */ + + outputs = pwm_outputs_from_channels(priv); + + /* Enable outputs */ + + ret = pwm_outputs_enable(dev, outputs, true); + if (ret < 0) + { + goto errout; + } + + /* Just enable the timer, leaving all interrupts disabled */ + + pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN); + + pwm_dumpregs(priv, "After starting"); + +errout: + return ret; +} +#endif /* CONFIG_PWM_PULSECOUNT */ + +#ifdef HAVE_PWM_INTERRUPT /**************************************************************************** * Name: pwm_interrupt @@ -1898,16 +3448,16 @@ static int pwm_update_duty(FAR struct stm32_pwmtimer_s *priv, uint8_t channel, * Handle timer interrupts. * * Input Parameters: - * priv - A reference to the lower half PWM driver state structure + * dev - A reference to the lower half PWM driver state structure * * Returned Value: * Zero on success; a negated errno value on failure * ****************************************************************************/ -#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM)) -static int pwm_interrupt(struct stm32_pwmtimer_s *priv) +static int pwm_interrupt(FAR struct pwm_lowerhalf_s *dev) { + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; uint16_t regval; /* Verify that this is an update interrupt. Nothing else is expected. */ @@ -1917,7 +3467,7 @@ static int pwm_interrupt(struct stm32_pwmtimer_s *priv) /* Clear the UIF interrupt bit */ - pwm_putreg(priv, STM32_ATIM_SR_OFFSET, regval & ~ATIM_SR_UIF); + pwm_putreg(priv, STM32_ATIM_SR_OFFSET, (regval & ~ATIM_SR_UIF)); /* Calculate the new count by subtracting the number of pulses * since the last interrupt. @@ -1925,17 +3475,17 @@ static int pwm_interrupt(struct stm32_pwmtimer_s *priv) if (priv->count <= priv->prev) { - /* We are finished. Turn off the mast output to stop the output as + /* We are finished. Turn off the master output to stop the output as * quickly as possible. */ - regval = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); + regval = pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET); regval &= ~ATIM_BDTR_MOE; pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, regval); /* Disable first interrtups, stop and reset the timer */ - (void)pwm_stop((FAR struct pwm_lowerhalf_s *)priv); + (void)pwm_stop(dev); /* Then perform the callback into the upper half driver */ @@ -1972,7 +3522,6 @@ static int pwm_interrupt(struct stm32_pwmtimer_s *priv) return OK; } -#endif /**************************************************************************** * Name: pwm_tim1/8interrupt @@ -1988,19 +3537,19 @@ static int pwm_interrupt(struct stm32_pwmtimer_s *priv) * ****************************************************************************/ -#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_STM32_TIM1_PWM) +#ifdef CONFIG_STM32_TIM1_PWM static int pwm_tim1interrupt(int irq, void *context, FAR void *arg) { - return pwm_interrupt(&g_pwm1dev); + return pwm_interrupt((FAR struct pwm_lowerhalf_s *)&g_pwm1dev); } -#endif +#endif /* CONFIG_STM32_TIM1_PWM */ -#if defined(CONFIG_PWM_PULSECOUNT) && defined(CONFIG_STM32_TIM8_PWM) +#ifdef CONFIG_STM32_TIM8_PWM static int pwm_tim8interrupt(int irq, void *context, FAR void *arg) { - return pwm_interrupt(&g_pwm8dev); + return pwm_interrupt((FAR struct pwm_lowerhalf_s *)&g_pwm8dev); } -#endif +#endif /* CONFIG_STM32_TIM8_PWM */ /**************************************************************************** * Name: pwm_pulsecount @@ -2016,16 +3565,17 @@ static int pwm_tim8interrupt(int irq, void *context, FAR void *arg) * ****************************************************************************/ -#if defined(CONFIG_PWM_PULSECOUNT) && (defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM)) static uint8_t pwm_pulsecount(uint32_t count) { + /* REVISIT: RCR_REP_MAX for GTIM or ATIM ? */ + /* The the remaining pulse count is less than or equal to the maximum, the * just return the count. */ - if (count <= ATIM_RCR_REP_MAX) + if (count <= GTIM_RCR_REP_MAX) { - return count; + return (uint8_t)count; } /* Otherwise, we have to be careful. We do not want a small number of @@ -2035,19 +3585,19 @@ static uint8_t pwm_pulsecount(uint32_t count) * and 128. */ - else if (count < (3 * ATIM_RCR_REP_MAX / 2)) + else if (count < (3 * GTIM_RCR_REP_MAX / 2)) { - return (ATIM_RCR_REP_MAX + 1) >> 1; + return (uint8_t)((GTIM_RCR_REP_MAX + 1) >> 1); } /* Otherwise, return the maximum. The final count will be 64 or more */ else { - return ATIM_RCR_REP_MAX; + return (uint8_t)GTIM_RCR_REP_MAX; } } -#endif +#endif /* HAVE_PWM_INTERRUPT */ /**************************************************************************** * Name: pwm_set_apb_clock @@ -2056,15 +3606,16 @@ static uint8_t pwm_pulsecount(uint32_t count) * Enable or disable APB clock for the timer peripheral * * Input Parameters: - * dev - A reference to the lower half PWM driver state structure - * on - Enable clock if 'on' is 'true' and disable if 'false' + * priv - A reference to the PWM block status + * on - Enable clock if 'on' is 'true' and disable if 'false' * ****************************************************************************/ -static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) +static int pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) { - uint32_t en_bit; - uint32_t regaddr; + uint32_t en_bit = 0; + uint32_t regaddr = 0; + int ret = OK; pwminfo("timer %d clock enable: %d\n", priv->timid, on ? 1 : 0); @@ -2074,96 +3625,145 @@ static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) { #ifdef CONFIG_STM32_TIM1_PWM case 1: - regaddr = TIMRCCEN_TIM1; - en_bit = TIMEN_TIM1; - break; + { + regaddr = TIMRCCEN_TIM1; + en_bit = TIMEN_TIM1; + break; + } #endif + #ifdef CONFIG_STM32_TIM2_PWM case 2: - regaddr = TIMRCCEN_TIM2; - en_bit = TIMEN_TIM2; - break; + { + regaddr = TIMRCCEN_TIM2; + en_bit = TIMEN_TIM2; + break; + } #endif + #ifdef CONFIG_STM32_TIM3_PWM case 3: - regaddr = TIMRCCEN_TIM3; - en_bit = TIMEN_TIM3; - break; + { + regaddr = TIMRCCEN_TIM3; + en_bit = TIMEN_TIM3; + break; + } #endif + #ifdef CONFIG_STM32_TIM4_PWM case 4: - regaddr = TIMRCCEN_TIM4; - en_bit = TIMEN_TIM4; - break; + { + regaddr = TIMRCCEN_TIM4; + en_bit = TIMEN_TIM4; + break; + } #endif + #ifdef CONFIG_STM32_TIM5_PWM case 5: - regaddr = TIMRCCEN_TIM5; - en_bit = TIMEN_TIM5; - break; + { + regaddr = TIMRCCEN_TIM5; + en_bit = TIMEN_TIM5; + break; + } #endif + #ifdef CONFIG_STM32_TIM8_PWM case 8: - regaddr = TIMRCCEN_TIM8; - en_bit = TIMEN_TIM8; - break; + { + regaddr = TIMRCCEN_TIM8; + en_bit = TIMEN_TIM8; + break; + } #endif + #ifdef CONFIG_STM32_TIM9_PWM case 9: - regaddr = TIMRCCEN_TIM9; - en_bit = TIMEN_TIM9; - break; + { + regaddr = TIMRCCEN_TIM9; + en_bit = TIMEN_TIM9; + break; + } #endif + #ifdef CONFIG_STM32_TIM10_PWM case 10: - regaddr = TIMRCCEN_TIM10; - en_bit = TIMEN_TIM10; - break; + { + regaddr = TIMRCCEN_TIM10; + en_bit = TIMEN_TIM10; + break; + } #endif + #ifdef CONFIG_STM32_TIM11_PWM case 11: - regaddr = TIMRCCEN_TIM11; - en_bit = TIMEN_TIM11; - break; + { + regaddr = TIMRCCEN_TIM11; + en_bit = TIMEN_TIM11; + break; + } #endif + #ifdef CONFIG_STM32_TIM12_PWM case 12: - regaddr = TIMRCCEN_TIM12; - en_bit = TIMEN_TIM12; - break; + { + regaddr = TIMRCCEN_TIM12; + en_bit = TIMEN_TIM12; + break; + } #endif + #ifdef CONFIG_STM32_TIM13_PWM case 13: - regaddr = TIMRCCEN_TIM13; - en_bit = TIMEN_TIM13; - break; + { + regaddr = TIMRCCEN_TIM13; + en_bit = TIMEN_TIM13; + break; + } #endif + #ifdef CONFIG_STM32_TIM14_PWM case 14: - regaddr = TIMRCCEN_TIM14; - en_bit = TIMEN_TIM14; - break; + { + regaddr = TIMRCCEN_TIM14; + en_bit = TIMEN_TIM14; + break; + } #endif + #ifdef CONFIG_STM32_TIM15_PWM case 15: - regaddr = TIMRCCEN_TIM15; - en_bit = TIMEN_TIM15; - break; + { + regaddr = TIMRCCEN_TIM15; + en_bit = TIMEN_TIM15; + break; + } #endif + #ifdef CONFIG_STM32_TIM16_PWM case 16: - regaddr = TIMRCCEN_TIM16; - en_bit = TIMEN_TIM16; - break; + { + regaddr = TIMRCCEN_TIM16; + en_bit = TIMEN_TIM16; + break; + } #endif + #ifdef CONFIG_STM32_TIM17_PWM case 17: - regaddr = TIMRCCEN_TIM17; - en_bit = TIMEN_TIM17; - break; + { + regaddr = TIMRCCEN_TIM17; + en_bit = TIMEN_TIM17; + break; + } #endif + default: - return; + { + pwmerr("ERROR: No such timer configured %d\n", priv->timid); + ret = -EINVAL; + goto errout; + } } /* Enable/disable APB 1/2 clock for timer */ @@ -2178,6 +3778,9 @@ static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) { modifyreg32(regaddr, en_bit, 0); } + +errout: + return ret; } /**************************************************************************** @@ -2203,34 +3806,67 @@ static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) { FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; - uint32_t pincfg; - int i; + uint32_t pincfg = 0; + int ret = OK; + int i = 0; pwminfo("TIM%u\n", priv->timid); /* Enable APB1/2 clocking for timer. */ - pwm_set_apb_clock(priv, true); + ret = pwm_set_apb_clock(priv, true); + if (ret < 0) + { + goto errout; + } pwm_dumpregs(priv, "Initially"); /* Configure the PWM output pins, but do not start the timer yet */ - for (i = 0; i < PWM_NCHANNELS; i++) + for (i = 0; i < priv->chan_num; i++) { - pincfg = priv->channels[i].pincfg; - if (pincfg == 0) + if (priv->channels[i].out1.in_use == 1) { - continue; + pincfg = priv->channels[i].out1.pincfg; + pwminfo("pincfg: %08x\n", pincfg); + + stm32_configgpio(pincfg); + pwm_dumpgpio(pincfg, "PWM setup"); } - pwminfo("pincfg: %08x\n", pincfg); +#ifdef HAVE_COMPLEMENTARY + if (priv->channels[i].out2.in_use == 1) + { + pincfg = priv->channels[i].out2.pincfg; + pwminfo("pincfg: %08x\n", pincfg); - stm32_configgpio(pincfg); - pwm_dumpgpio(pincfg, "PWM setup"); + stm32_configgpio(pincfg); + pwm_dumpgpio(pincfg, "PWM setup"); + } +#endif } - return OK; + /* Configure PWM timer with the selected configuration. + * + * NOTE: We configure PWM here during setup, but leave timer with disabled + * counter, disabled outputs, not configured frequency and duty cycle + */ + +#ifdef CONFIG_PWM_PULSECOUNT + ret = pwm_pulsecount_configure(dev); +#else + ret = pwm_configure(dev); +#endif + if (ret < 0) + { + pwmerr("failed to configure PWM %d\n", priv->timid); + ret = ERROR; + goto errout; + } + +errout: + return ret; } /**************************************************************************** @@ -2252,8 +3888,9 @@ static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) { FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; - uint32_t pincfg; - int i; + uint32_t pincfg = 0; + int i = 0; + int ret = OK; pwminfo("TIM%u\n", priv->timid); @@ -2263,38 +3900,43 @@ static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) /* Disable APB1/2 clocking for timer. */ - pwm_set_apb_clock(priv, false); + ret = pwm_set_apb_clock(priv, false); + if (ret < 0) + { + goto errout; + } /* Then put the GPIO pins back to the default state */ - for (i = 0; i < PWM_NCHANNELS; i++) + for (i = 0; i < priv->chan_num; i++) { - pincfg = priv->channels[i].pincfg; - if (pincfg == 0) + pincfg = priv->channels[i].out1.pincfg; + if (pincfg != 0) { - continue; + pwminfo("pincfg: %08x\n", pincfg); + + pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg |= PINCFG_DEFAULT; + + stm32_configgpio(pincfg); } - pwminfo("pincfg: %08x\n", pincfg); +#ifdef HAVE_COMPLEMENTARY + pincfg = priv->channels[i].out2.pincfg; + if (pincfg != 0) + { + pwminfo("pincfg: %08x\n", pincfg); - pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK); + pincfg |= PINCFG_DEFAULT; -#if defined(CONFIG_STM32_STM32F10XX) - pincfg |= GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT; -#elif defined(CONFIG_STM32_STM32F20XX) || \ - defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F37XX) || \ - defined(CONFIG_STM32_STM32F4XXX) || \ - defined(CONFIG_STM32_STM32L15XX) - pincfg |= GPIO_INPUT | GPIO_FLOAT; -#else -# error "Unrecognized STM32 chip" + stm32_configgpio(pincfg); + } #endif - - stm32_configgpio(pincfg); } - return OK; +errout: + return ret; } /**************************************************************************** @@ -2304,7 +3946,7 @@ static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) * (Re-)initialize the timer resources and start the pulsed output * * Input Parameters: - * dev - A reference to the lower half PWM driver state structure + * dev - A reference to the lower half PWM driver state structure * info - A reference to the characteristics of the pulsed output * * Returned Value: @@ -2323,7 +3965,9 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev, if (info->count > 0) { - /* Only the advanced timers (TIM1,8 can support the pulse counting) */ + /* Only the advanced timers (TIM1,8 can support the pulse counting) + * REVISIT: verify if TIMTYPE_COUNTUP16_N works with it + */ if (priv->timtype != TIMTYPE_ADVANCED) { @@ -2339,16 +3983,15 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev, /* Start the time */ - return pwm_timer(priv, info); + return pwm_pulsecount_timer(dev, info); } -#else +#else /* !CONFIG_PWM_PULSECOUNT */ static int pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_info_s *info) { - int ret = OK; FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + int ret = OK; -#ifndef CONFIG_PWM_PULSECOUNT /* if frequency has not changed we just update duty */ if (info->frequency == priv->frequency) @@ -2356,33 +3999,32 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev, #ifdef CONFIG_PWM_MULTICHAN int i; + /* REVISIT: */ + for (i = 0; ret == OK && i < CONFIG_PWM_NCHANNELS; i++) { - ret = pwm_update_duty(priv,info->channels[i].channel, + ret = pwm_duty_update(dev, info->channels[i].channel, info->channels[i].duty); } #else - ret = pwm_update_duty(priv,priv->channels[0].channel,info->duty); -#endif + ret = pwm_duty_update(dev, priv->channels[0].channel,info->duty); +#endif /* CONFIG_PWM_MULTICHAN */ } else -#endif { - ret = pwm_timer(priv, info); + ret = pwm_timer(dev, info); -#ifndef CONFIG_PWM_PULSECOUNT /* Save current frequency */ if (ret == OK) { priv->frequency = info->frequency; } -#endif } return ret; } -#endif +#endif /* CONFIG_PWM_PULSECOUNT */ /**************************************************************************** * Name: pwm_stop @@ -2406,10 +4048,11 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev, static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) { FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; - uint32_t resetbit; - uint32_t regaddr; - uint32_t regval; - irqstate_t flags; + irqstate_t flags = 0; + uint32_t resetbit = 0; + uint32_t regaddr = 0; + uint32_t regval = 0; + int ret = OK; pwminfo("TIM%u\n", priv->timid); @@ -2419,96 +4062,144 @@ static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) { #ifdef CONFIG_STM32_TIM1_PWM case 1: + { regaddr = TIMRCCRST_TIM1; resetbit = TIMRST_TIM1; break; + } #endif + #ifdef CONFIG_STM32_TIM2_PWM case 2: + { regaddr = TIMRCCRST_TIM2; resetbit = TIMRST_TIM2; break; + } #endif + #ifdef CONFIG_STM32_TIM3_PWM case 3: + { regaddr = TIMRCCRST_TIM3; resetbit = TIMRST_TIM3; break; + } #endif + #ifdef CONFIG_STM32_TIM4_PWM case 4: + { regaddr = TIMRCCRST_TIM4; resetbit = TIMRST_TIM4; break; + } #endif + #ifdef CONFIG_STM32_TIM5_PWM case 5: + { regaddr = TIMRCCRST_TIM5; resetbit = TIMRST_TIM5; break; + } #endif + #ifdef CONFIG_STM32_TIM8_PWM case 8: + { regaddr = TIMRCCRST_TIM8; resetbit = TIMRST_TIM8; break; + } #endif + #ifdef CONFIG_STM32_TIM9_PWM case 9: + { regaddr = TIMRCCRST_TIM9; resetbit = TIMRST_TIM9; break; + } #endif + #ifdef CONFIG_STM32_TIM10_PWM case 10: + { regaddr = TIMRCCRST_TIM10; resetbit = TIMRST_TIM10; break; + } #endif + #ifdef CONFIG_STM32_TIM11_PWM case 11: + { regaddr = TIMRCCRST_TIM11; resetbit = TIMRST_TIM11; break; + } #endif + #ifdef CONFIG_STM32_TIM12_PWM case 12: + { regaddr = TIMRCCRST_TIM12; resetbit = TIMRST_TIM12; break; + } #endif + #ifdef CONFIG_STM32_TIM13_PWM case 13: + { regaddr = TIMRCCRST_TIM13; resetbit = TIMRST_TIM13; break; + } #endif + #ifdef CONFIG_STM32_TIM14_PWM case 14: + { regaddr = TIMRCCRST_TIM14; resetbit = TIMRST_TIM14; break; + } #endif + #ifdef CONFIG_STM32_TIM15_PWM case 15: + { regaddr = TIMRCCRST_TIM15; resetbit = TIMRST_TIM15; break; + } #endif + #ifdef CONFIG_STM32_TIM16_PWM case 16: + { regaddr = TIMRCCRST_TIM16; resetbit = TIMRST_TIM16; break; + } #endif + #ifdef CONFIG_STM32_TIM17_PWM case 17: + { regaddr = TIMRCCRST_TIM17; resetbit = TIMRST_TIM17; break; + } #endif + default: - return -EINVAL; + { + ret = -EINVAL; + goto errout; + } } /* Disable interrupts momentary to stop any ongoing timer processing and @@ -2517,9 +4208,11 @@ static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) flags = enter_critical_section(); +#ifndef CONFIG_PWM_PULSECOUNT /* Stopped so frequency is zero */ priv->frequency = 0; +#endif /* Disable further interrupts and stop the timer */ @@ -2540,7 +4233,9 @@ static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) pwminfo("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); pwm_dumpregs(priv, "After stop"); - return OK; + +errout: + return ret; } /**************************************************************************** @@ -2594,7 +4289,7 @@ static int pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer) { - FAR struct stm32_pwmtimer_s *lower; + FAR struct stm32_pwmtimer_s *lower = NULL; pwminfo("TIM%u\n", timer); @@ -2602,114 +4297,172 @@ FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer) { #ifdef CONFIG_STM32_TIM1_PWM case 1: - lower = &g_pwm1dev; + { + lower = &g_pwm1dev; - /* Attach but disable the TIM1 update interrupt */ + /* Attach but disable the TIM1 update interrupt */ #ifdef CONFIG_PWM_PULSECOUNT - irq_attach(lower->irq, pwm_tim1interrupt, NULL); - up_disable_irq(lower->irq); + irq_attach(lower->irq, pwm_tim1interrupt, NULL); + up_disable_irq(lower->irq); #endif - break; + break; + } #endif #ifdef CONFIG_STM32_TIM2_PWM case 2: - lower = &g_pwm2dev; - break; + { + lower = &g_pwm2dev; + break; + } #endif #ifdef CONFIG_STM32_TIM3_PWM case 3: - lower = &g_pwm3dev; - break; + { + lower = &g_pwm3dev; + break; + } #endif #ifdef CONFIG_STM32_TIM4_PWM case 4: - lower = &g_pwm4dev; - break; + { + lower = &g_pwm4dev; + break; + } #endif #ifdef CONFIG_STM32_TIM5_PWM case 5: - lower = &g_pwm5dev; - break; + { + lower = &g_pwm5dev; + break; + } #endif #ifdef CONFIG_STM32_TIM8_PWM case 8: - lower = &g_pwm8dev; + { + lower = &g_pwm8dev; - /* Attach but disable the TIM8 update interrupt */ + /* Attach but disable the TIM8 update interrupt */ #ifdef CONFIG_PWM_PULSECOUNT - irq_attach(lower->irq, pwm_tim8interrupt, NULL); - up_disable_irq(lower->irq); + irq_attach(lower->irq, pwm_tim8interrupt, NULL); + up_disable_irq(lower->irq); #endif - break; + break; + } #endif #ifdef CONFIG_STM32_TIM9_PWM case 9: - lower = &g_pwm9dev; - break; + { + lower = &g_pwm9dev; + break; + } #endif #ifdef CONFIG_STM32_TIM10_PWM case 10: - lower = &g_pwm10dev; - break; + { + lower = &g_pwm10dev; + break; + } + #endif #ifdef CONFIG_STM32_TIM11_PWM case 11: - lower = &g_pwm11dev; - break; + { + lower = &g_pwm11dev; + break; + } #endif #ifdef CONFIG_STM32_TIM12_PWM case 12: - lower = &g_pwm12dev; - break; + { + lower = &g_pwm12dev; + break; + } #endif #ifdef CONFIG_STM32_TIM13_PWM case 13: - lower = &g_pwm13dev; - break; + { + lower = &g_pwm13dev; + break; + } #endif #ifdef CONFIG_STM32_TIM14_PWM case 14: - lower = &g_pwm14dev; - break; + { + lower = &g_pwm14dev; + break; + } #endif #ifdef CONFIG_STM32_TIM15_PWM case 15: - lower = &g_pwm15dev; - break; + { + lower = &g_pwm15dev; + break; + } #endif #ifdef CONFIG_STM32_TIM16_PWM case 16: - lower = &g_pwm16dev; - break; + { + lower = &g_pwm16dev; + break; + } #endif #ifdef CONFIG_STM32_TIM17_PWM case 17: - lower = &g_pwm17dev; - break; + { + lower = &g_pwm17dev; + break; + } #endif default: - pwmerr("ERROR: No such timer configured\n"); - return NULL; + { + pwmerr("ERROR: No such timer configured %d\n", timer); + lower = NULL; + goto errout; + } } +errout: return (FAR struct pwm_lowerhalf_s *)lower; } +/**************************************************************************** + * Name: stm32_llops_get + * + * Description: + * Get low-level ops from the generic PWM lower-half data. + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Pointer to low-level PWM ops + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_PWM_LL_OPS +FAR const struct stm32_pwm_ops_s *stm32_pwm_llops_get(FAR struct pwm_lowerhalf_s *dev) +{ + FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev; + + return priv->llops; +} +#endif + #endif /* CONFIG_STM32_TIMn_PWM, n = 1,...,17 */ diff --git a/arch/arm/src/stm32/stm32_pwm.h b/arch/arm/src/stm32/stm32_pwm.h index 7dba0a0862..a633f29233 100644 --- a/arch/arm/src/stm32/stm32_pwm.h +++ b/arch/arm/src/stm32/stm32_pwm.h @@ -5,6 +5,7 @@ * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. * Authors: Gregory Nutt * Paul Alexander Patience + * Mateusz Szafoni * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -127,44 +128,30 @@ #include #include "chip/stm32_tim.h" +#ifdef CONFIG_STM32_PWM_MULTICHAN +# ifndef CONFIG_PWM_MULTICHAN +# error CONFIG_STM32_PWM_MULTICHAN enabled but CONFIG_PWM_MULTICHAN not set! +# endif +#endif + #ifdef CONFIG_PWM_MULTICHAN #ifdef CONFIG_STM32_TIM1_CHANNEL1 -# ifdef CONFIG_STM32_TIM1_CH1OUT -# define PWM_TIM1_CH1CFG GPIO_TIM1_CH1OUT -# else -# define PWM_TIM1_CH1CFG 0 -# endif # define PWM_TIM1_CHANNEL1 1 #else # define PWM_TIM1_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM1_CHANNEL2 -# ifdef CONFIG_STM32_TIM1_CH2OUT -# define PWM_TIM1_CH2CFG GPIO_TIM1_CH2OUT -# else -# define PWM_TIM1_CH2CFG 0 -# endif # define PWM_TIM1_CHANNEL2 1 #else # define PWM_TIM1_CHANNEL2 0 #endif #ifdef CONFIG_STM32_TIM1_CHANNEL3 -# ifdef CONFIG_STM32_TIM1_CH3OUT -# define PWM_TIM1_CH3CFG GPIO_TIM1_CH3OUT -# else -# define PWM_TIM1_CH3CFG 0 -# endif # define PWM_TIM1_CHANNEL3 1 #else # define PWM_TIM1_CHANNEL3 0 #endif #ifdef CONFIG_STM32_TIM1_CHANNEL4 -# ifdef CONFIG_STM32_TIM1_CH4OUT -# define PWM_TIM1_CH4CFG GPIO_TIM1_CH4OUT -# else -# define PWM_TIM1_CH4CFG 0 -# endif # define PWM_TIM1_CHANNEL4 1 #else # define PWM_TIM1_CHANNEL4 0 @@ -173,41 +160,21 @@ PWM_TIM1_CHANNEL3 + PWM_TIM1_CHANNEL4) #ifdef CONFIG_STM32_TIM2_CHANNEL1 -# ifdef CONFIG_STM32_TIM2_CH1OUT -# define PWM_TIM2_CH1CFG GPIO_TIM2_CH1OUT_1 -# else -# define PWM_TIM2_CH1CFG 0 -# endif # define PWM_TIM2_CHANNEL1 1 #else # define PWM_TIM2_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM2_CHANNEL2 -# ifdef CONFIG_STM32_TIM2_CH2OUT -# define PWM_TIM2_CH2CFG GPIO_TIM2_CH2OUT -# else -# define PWM_TIM2_CH2CFG 0 -# endif # define PWM_TIM2_CHANNEL2 1 #else # define PWM_TIM2_CHANNEL2 0 #endif #ifdef CONFIG_STM32_TIM2_CHANNEL3 -# ifdef CONFIG_STM32_TIM2_CH3OUT -# define PWM_TIM2_CH3CFG GPIO_TIM2_CH3OUT -# else -# define PWM_TIM2_CH3CFG 0 -# endif # define PWM_TIM2_CHANNEL3 1 #else # define PWM_TIM2_CHANNEL3 0 #endif #ifdef CONFIG_STM32_TIM2_CHANNEL4 -# ifdef CONFIG_STM32_TIM2_CH4OUT -# define PWM_TIM2_CH4CFG GPIO_TIM2_CH4OUT -# else -# define PWM_TIM2_CH4CFG 0 -# endif # define PWM_TIM2_CHANNEL4 1 #else # define PWM_TIM2_CHANNEL4 0 @@ -216,41 +183,21 @@ PWM_TIM2_CHANNEL3 + PWM_TIM2_CHANNEL4) #ifdef CONFIG_STM32_TIM3_CHANNEL1 -# ifdef CONFIG_STM32_TIM3_CH1OUT -# define PWM_TIM3_CH1CFG GPIO_TIM3_CH1OUT -# else -# define PWM_TIM3_CH1CFG 0 -# endif # define PWM_TIM3_CHANNEL1 1 #else # define PWM_TIM3_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM3_CHANNEL2 -# ifdef CONFIG_STM32_TIM3_CH2OUT -# define PWM_TIM3_CH2CFG GPIO_TIM3_CH2OUT -# else -# define PWM_TIM3_CH2CFG 0 -# endif # define PWM_TIM3_CHANNEL2 1 #else # define PWM_TIM3_CHANNEL2 0 #endif #ifdef CONFIG_STM32_TIM3_CHANNEL3 -# ifdef CONFIG_STM32_TIM3_CH3OUT -# define PWM_TIM3_CH3CFG GPIO_TIM3_CH3OUT -# else -# define PWM_TIM3_CH3CFG 0 -# endif # define PWM_TIM3_CHANNEL3 1 #else # define PWM_TIM3_CHANNEL3 0 #endif #ifdef CONFIG_STM32_TIM3_CHANNEL4 -# ifdef CONFIG_STM32_TIM3_CH4OUT -# define PWM_TIM3_CH4CFG GPIO_TIM3_CH4OUT -# else -# define PWM_TIM3_CH4CFG 0 -# endif # define PWM_TIM3_CHANNEL4 1 #else # define PWM_TIM3_CHANNEL4 0 @@ -259,41 +206,21 @@ PWM_TIM3_CHANNEL3 + PWM_TIM3_CHANNEL4) #ifdef CONFIG_STM32_TIM4_CHANNEL1 -# ifdef CONFIG_STM32_TIM4_CH1OUT -# define PWM_TIM4_CH1CFG GPIO_TIM4_CH1OUT -# else -# define PWM_TIM4_CH1CFG 0 -# endif # define PWM_TIM4_CHANNEL1 1 #else # define PWM_TIM4_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM4_CHANNEL2 -# ifdef CONFIG_STM32_TIM4_CH2OUT -# define PWM_TIM4_CH2CFG GPIO_TIM4_CH2OUT -# else -# define PWM_TIM4_CH2CFG 0 -# endif # define PWM_TIM4_CHANNEL2 1 #else # define PWM_TIM4_CHANNEL2 0 #endif #ifdef CONFIG_STM32_TIM4_CHANNEL3 -# ifdef CONFIG_STM32_TIM4_CH3OUT -# define PWM_TIM4_CH3CFG GPIO_TIM4_CH3OUT -# else -# define PWM_TIM4_CH3CFG 0 -# endif # define PWM_TIM4_CHANNEL3 1 #else # define PWM_TIM4_CHANNEL3 0 #endif #ifdef CONFIG_STM32_TIM4_CHANNEL4 -# ifdef CONFIG_STM32_TIM4_CH4OUT -# define PWM_TIM4_CH4CFG GPIO_TIM4_CH4OUT -# else -# define PWM_TIM4_CH4CFG 0 -# endif # define PWM_TIM4_CHANNEL4 1 #else # define PWM_TIM4_CHANNEL4 0 @@ -302,41 +229,21 @@ PWM_TIM4_CHANNEL3 + PWM_TIM4_CHANNEL4) #ifdef CONFIG_STM32_TIM5_CHANNEL1 -# ifdef CONFIG_STM32_TIM5_CH1OUT -# define PWM_TIM5_CH1CFG GPIO_TIM5_CH1OUT -# else -# define PWM_TIM5_CH1CFG 0 -# endif # define PWM_TIM5_CHANNEL1 1 #else # define PWM_TIM5_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM5_CHANNEL2 -# ifdef CONFIG_STM32_TIM5_CH2OUT -# define PWM_TIM5_CH2CFG GPIO_TIM5_CH2OUT -# else -# define PWM_TIM5_CH2CFG 0 -# endif # define PWM_TIM5_CHANNEL2 1 #else # define PWM_TIM5_CHANNEL2 0 #endif #ifdef CONFIG_STM32_TIM5_CHANNEL3 -# ifdef CONFIG_STM32_TIM5_CH3OUT -# define PWM_TIM5_CH3CFG GPIO_TIM5_CH3OUT -# else -# define PWM_TIM5_CH3CFG 0 -# endif # define PWM_TIM5_CHANNEL3 1 #else # define PWM_TIM5_CHANNEL3 0 #endif #ifdef CONFIG_STM32_TIM5_CHANNEL4 -# ifdef CONFIG_STM32_TIM5_CH4OUT -# define PWM_TIM5_CH4CFG GPIO_TIM5_CH4OUT -# else -# define PWM_TIM5_CH4CFG 0 -# endif # define PWM_TIM5_CHANNEL4 1 #else # define PWM_TIM5_CHANNEL4 0 @@ -345,41 +252,21 @@ PWM_TIM5_CHANNEL3 + PWM_TIM5_CHANNEL4) #ifdef CONFIG_STM32_TIM8_CHANNEL1 -# ifdef CONFIG_STM32_TIM8_CH1OUT -# define PWM_TIM8_CH1CFG GPIO_TIM8_CH1OUT -# else -# define PWM_TIM8_CH1CFG 0 -# endif # define PWM_TIM8_CHANNEL1 1 #else # define PWM_TIM8_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM8_CHANNEL2 -# ifdef CONFIG_STM32_TIM8_CH2OUT -# define PWM_TIM8_CH2CFG GPIO_TIM8_CH2OUT -# else -# define PWM_TIM8_CH2CFG 0 -# endif # define PWM_TIM8_CHANNEL2 1 #else # define PWM_TIM8_CHANNEL2 0 #endif #ifdef CONFIG_STM32_TIM8_CHANNEL3 -# ifdef CONFIG_STM32_TIM8_CH3OUT -# define PWM_TIM8_CH3CFG GPIO_TIM8_CH3OUT -# else -# define PWM_TIM8_CH3CFG 0 -# endif # define PWM_TIM8_CHANNEL3 1 #else # define PWM_TIM8_CHANNEL3 0 #endif #ifdef CONFIG_STM32_TIM8_CHANNEL4 -# ifdef CONFIG_STM32_TIM8_CH4OUT -# define PWM_TIM8_CH4CFG GPIO_TIM8_CH4OUT -# else -# define PWM_TIM8_CH4CFG 0 -# endif # define PWM_TIM8_CHANNEL4 1 #else # define PWM_TIM8_CHANNEL4 0 @@ -388,279 +275,63 @@ PWM_TIM8_CHANNEL3 + PWM_TIM8_CHANNEL4) #ifdef CONFIG_STM32_TIM9_CHANNEL1 -# ifdef CONFIG_STM32_TIM9_CH1OUT -# define PWM_TIM9_CH1CFG GPIO_TIM9_CH1OUT -# else -# define PWM_TIM9_CH1CFG 0 -# endif # define PWM_TIM9_CHANNEL1 1 #else # define PWM_TIM9_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM9_CHANNEL2 -# ifdef CONFIG_STM32_TIM9_CH2OUT -# define PWM_TIM9_CH2CFG GPIO_TIM9_CH2OUT -# else -# define PWM_TIM9_CH2CFG 0 -# endif # define PWM_TIM9_CHANNEL2 1 #else # define PWM_TIM9_CHANNEL2 0 #endif -#ifdef CONFIG_STM32_TIM9_CHANNEL3 -# ifdef CONFIG_STM32_TIM9_CH3OUT -# define PWM_TIM9_CH3CFG GPIO_TIM9_CH3OUT -# else -# define PWM_TIM9_CH3CFG 0 -# endif -# define PWM_TIM9_CHANNEL3 1 -#else -# define PWM_TIM9_CHANNEL3 0 -#endif -#ifdef CONFIG_STM32_TIM9_CHANNEL4 -# ifdef CONFIG_STM32_TIM9_CH4OUT -# define PWM_TIM9_CH4CFG GPIO_TIM9_CH4OUT -# else -# define PWM_TIM9_CH4CFG 0 -# endif -# define PWM_TIM9_CHANNEL4 1 -#else -# define PWM_TIM9_CHANNEL4 0 -#endif -#define PWM_TIM9_NCHANNELS (PWM_TIM9_CHANNEL1 + PWM_TIM9_CHANNEL2 + \ - PWM_TIM9_CHANNEL3 + PWM_TIM9_CHANNEL4) +#define PWM_TIM9_NCHANNELS (PWM_TIM9_CHANNEL1 + PWM_TIM9_CHANNEL2) #ifdef CONFIG_STM32_TIM10_CHANNEL1 -# ifdef CONFIG_STM32_TIM10_CH1OUT -# define PWM_TIM10_CH1CFG GPIO_TIM10_CH1OUT -# else -# define PWM_TIM10_CH1CFG 0 -# endif # define PWM_TIM10_CHANNEL1 1 #else # define PWM_TIM10_CHANNEL1 0 #endif -#ifdef CONFIG_STM32_TIM10_CHANNEL2 -# ifdef CONFIG_STM32_TIM10_CH2OUT -# define PWM_TIM10_CH2CFG GPIO_TIM10_CH2OUT -# else -# define PWM_TIM10_CH2CFG 0 -# endif -# define PWM_TIM10_CHANNEL2 1 -#else -# define PWM_TIM10_CHANNEL2 0 -#endif -#ifdef CONFIG_STM32_TIM10_CHANNEL3 -# ifdef CONFIG_STM32_TIM10_CH3OUT -# define PWM_TIM10_CH3CFG GPIO_TIM10_CH3OUT -# else -# define PWM_TIM10_CH3CFG 0 -# endif -# define PWM_TIM10_CHANNEL3 1 -#else -# define PWM_TIM10_CHANNEL3 0 -#endif -#ifdef CONFIG_STM32_TIM10_CHANNEL4 -# ifdef CONFIG_STM32_TIM10_CH4OUT -# define PWM_TIM10_CH4CFG GPIO_TIM10_CH4OUT -# else -# define PWM_TIM10_CH4CFG 0 -# endif -# define PWM_TIM10_CHANNEL4 1 -#else -# define PWM_TIM10_CHANNEL4 0 -#endif -#define PWM_TIM10_NCHANNELS (PWM_TIM10_CHANNEL1 + PWM_TIM10_CHANNEL2 + \ - PWM_TIM10_CHANNEL3 + PWM_TIM10_CHANNEL4) +#define PWM_TIM10_NCHANNELS (PWM_TIM10_CHANNEL1) #ifdef CONFIG_STM32_TIM11_CHANNEL1 -# ifdef CONFIG_STM32_TIM11_CH1OUT -# define PWM_TIM11_CH1CFG GPIO_TIM11_CH1OUT -# else -# define PWM_TIM11_CH1CFG 0 -# endif # define PWM_TIM11_CHANNEL1 1 #else # define PWM_TIM11_CHANNEL1 0 #endif -#ifdef CONFIG_STM32_TIM11_CHANNEL2 -# ifdef CONFIG_STM32_TIM11_CH2OUT -# define PWM_TIM11_CH2CFG GPIO_TIM11_CH2OUT -# else -# define PWM_TIM11_CH2CFG 0 -# endif -# define PWM_TIM11_CHANNEL2 1 -#else -# define PWM_TIM11_CHANNEL2 0 -#endif -#ifdef CONFIG_STM32_TIM11_CHANNEL3 -# ifdef CONFIG_STM32_TIM11_CH3OUT -# define PWM_TIM11_CH3CFG GPIO_TIM11_CH3OUT -# else -# define PWM_TIM11_CH3CFG 0 -# endif -# define PWM_TIM11_CHANNEL3 1 -#else -# define PWM_TIM11_CHANNEL3 0 -#endif -#ifdef CONFIG_STM32_TIM11_CHANNEL4 -# ifdef CONFIG_STM32_TIM11_CH4OUT -# define PWM_TIM11_CH4CFG GPIO_TIM11_CH4OUT -# else -# define PWM_TIM11_CH4CFG 0 -# endif -# define PWM_TIM11_CHANNEL4 1 -#else -# define PWM_TIM11_CHANNEL4 0 -#endif -#define PWM_TIM11_NCHANNELS (PWM_TIM11_CHANNEL1 + PWM_TIM11_CHANNEL2 + \ - PWM_TIM11_CHANNEL3 + PWM_TIM11_CHANNEL4) +#define PWM_TIM11_NCHANNELS (PWM_TIM11_CHANNEL1) #ifdef CONFIG_STM32_TIM12_CHANNEL1 -# ifdef CONFIG_STM32_TIM12_CH1OUT -# define PWM_TIM12_CH1CFG GPIO_TIM12_CH1OUT -# else -# define PWM_TIM12_CH1CFG 0 -# endif # define PWM_TIM12_CHANNEL1 1 #else # define PWM_TIM12_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM12_CHANNEL2 -# ifdef CONFIG_STM32_TIM12_CH2OUT -# define PWM_TIM12_CH2CFG GPIO_TIM12_CH2OUT -# else -# define PWM_TIM12_CH2CFG 0 -# endif # define PWM_TIM12_CHANNEL2 1 #else # define PWM_TIM12_CHANNEL2 0 #endif -#ifdef CONFIG_STM32_TIM12_CHANNEL3 -# ifdef CONFIG_STM32_TIM12_CH3OUT -# define PWM_TIM12_CH3CFG GPIO_TIM12_CH3OUT -# else -# define PWM_TIM12_CH3CFG 0 -# endif -# define PWM_TIM12_CHANNEL3 1 -#else -# define PWM_TIM12_CHANNEL3 0 -#endif -#ifdef CONFIG_STM32_TIM12_CHANNEL4 -# ifdef CONFIG_STM32_TIM12_CH4OUT -# define PWM_TIM12_CH4CFG GPIO_TIM12_CH4OUT -# else -# define PWM_TIM12_CH4CFG 0 -# endif -# define PWM_TIM12_CHANNEL4 1 -#else -# define PWM_TIM12_CHANNEL4 0 -#endif -#define PWM_TIM12_NCHANNELS (PWM_TIM12_CHANNEL1 + PWM_TIM12_CHANNEL2 + \ - PWM_TIM12_CHANNEL3 + PWM_TIM12_CHANNEL4) +#define PWM_TIM12_NCHANNELS (PWM_TIM12_CHANNEL1 + PWM_TIM12_CHANNEL2) #ifdef CONFIG_STM32_TIM13_CHANNEL1 -# ifdef CONFIG_STM32_TIM13_CH1OUT -# define PWM_TIM13_CH1CFG GPIO_TIM13_CH1OUT -# else -# define PWM_TIM13_CH1CFG 0 -# endif # define PWM_TIM13_CHANNEL1 1 #else # define PWM_TIM13_CHANNEL1 0 #endif -#ifdef CONFIG_STM32_TIM13_CHANNEL2 -# ifdef CONFIG_STM32_TIM13_CH2OUT -# define PWM_TIM13_CH2CFG GPIO_TIM13_CH2OUT -# else -# define PWM_TIM13_CH2CFG 0 -# endif -# define PWM_TIM13_CHANNEL2 1 -#else -# define PWM_TIM13_CHANNEL2 0 -#endif -#ifdef CONFIG_STM32_TIM13_CHANNEL3 -# ifdef CONFIG_STM32_TIM13_CH3OUT -# define PWM_TIM13_CH3CFG GPIO_TIM13_CH3OUT -# else -# define PWM_TIM13_CH3CFG 0 -# endif -# define PWM_TIM13_CHANNEL3 1 -#else -# define PWM_TIM13_CHANNEL3 0 -#endif -#ifdef CONFIG_STM32_TIM13_CHANNEL4 -# ifdef CONFIG_STM32_TIM13_CH4OUT -# define PWM_TIM13_CH4CFG GPIO_TIM13_CH4OUT -# else -# define PWM_TIM13_CH4CFG 0 -# endif -# define PWM_TIM13_CHANNEL4 1 -#else -# define PWM_TIM13_CHANNEL4 0 -#endif -#define PWM_TIM13_NCHANNELS (PWM_TIM13_CHANNEL1 + PWM_TIM13_CHANNEL2 + \ - PWM_TIM13_CHANNEL3 + PWM_TIM13_CHANNEL4) +#define PWM_TIM13_NCHANNELS (PWM_TIM13_CHANNEL1) #ifdef CONFIG_STM32_TIM14_CHANNEL1 -# ifdef CONFIG_STM32_TIM14_CH1OUT -# define PWM_TIM14_CH1CFG GPIO_TIM14_CH1OUT -# else -# define PWM_TIM14_CH1CFG 0 -# endif # define PWM_TIM14_CHANNEL1 1 #else # define PWM_TIM14_CHANNEL1 0 #endif -#ifdef CONFIG_STM32_TIM14_CHANNEL2 -# ifdef CONFIG_STM32_TIM14_CH2OUT -# define PWM_TIM14_CH2CFG GPIO_TIM14_CH2OUT -# else -# define PWM_TIM14_CH2CFG 0 -# endif -# define PWM_TIM14_CHANNEL2 1 -#else -# define PWM_TIM14_CHANNEL2 0 -#endif -#ifdef CONFIG_STM32_TIM14_CHANNEL3 -# ifdef CONFIG_STM32_TIM14_CH3OUT -# define PWM_TIM14_CH3CFG GPIO_TIM14_CH3OUT -# else -# define PWM_TIM14_CH3CFG 0 -# endif -# define PWM_TIM14_CHANNEL3 1 -#else -# define PWM_TIM14_CHANNEL3 0 -#endif -#ifdef CONFIG_STM32_TIM14_CHANNEL4 -# ifdef CONFIG_STM32_TIM14_CH4OUT -# define PWM_TIM14_CH4CFG GPIO_TIM14_CH4OUT -# else -# define PWM_TIM14_CH4CFG 0 -# endif -# define PWM_TIM14_CHANNEL4 1 -#else -# define PWM_TIM14_CHANNEL4 0 -#endif -#define PWM_TIM14_NCHANNELS (PWM_TIM14_CHANNEL1 + PWM_TIM14_CHANNEL2 + \ - PWM_TIM14_CHANNEL3 + PWM_TIM14_CHANNEL4) +#define PWM_TIM14_NCHANNELS (PWM_TIM14_CHANNEL1) #ifdef CONFIG_STM32_TIM15_CHANNEL1 -# ifdef CONFIG_STM32_TIM15_CH1OUT -# define PWM_TIM15_CH1CFG GPIO_TIM15_CH1OUT -# else -# define PWM_TIM15_CH1CFG 0 -# endif # define PWM_TIM15_CHANNEL1 1 #else # define PWM_TIM15_CHANNEL1 0 #endif #ifdef CONFIG_STM32_TIM15_CHANNEL2 -# ifdef CONFIG_STM32_TIM15_CH2OUT -# define PWM_TIM15_CH2CFG GPIO_TIM15_CH2OUT -# else -# define PWM_TIM15_CH2CFG 0 -# endif # define PWM_TIM15_CHANNEL2 1 #else # define PWM_TIM15_CHANNEL2 0 @@ -668,11 +339,6 @@ #define PWM_TIM15_NCHANNELS (PWM_TIM15_CHANNEL1 + PWM_TIM15_CHANNEL2) #ifdef CONFIG_STM32_TIM16_CHANNEL1 -# ifdef CONFIG_STM32_TIM16_CH1OUT -# define PWM_TIM16_CH1CFG GPIO_TIM16_CH1OUT -# else -# define PWM_TIM16_CH1CFG 0 -# endif # define PWM_TIM16_CHANNEL1 1 #else # define PWM_TIM16_CHANNEL1 0 @@ -680,36 +346,13 @@ #define PWM_TIM16_NCHANNELS PWM_TIM16_CHANNEL1 #ifdef CONFIG_STM32_TIM17_CHANNEL1 -# ifdef CONFIG_STM32_TIM17_CH1OUT -# define PWM_TIM17_CH1CFG GPIO_TIM17_CH1OUT -# else -# define PWM_TIM17_CH1CFG 0 -# endif # define PWM_TIM17_CHANNEL1 1 #else # define PWM_TIM17_CHANNEL1 0 #endif #define PWM_TIM17_NCHANNELS PWM_TIM17_CHANNEL1 -#define PWM_MAX(a, b) ((a) > (b) ? (a) : (b)) - -#define PWM_NCHANNELS PWM_MAX(PWM_TIM1_NCHANNELS, \ - PWM_MAX(PWM_TIM2_NCHANNELS, \ - PWM_MAX(PWM_TIM3_NCHANNELS, \ - PWM_MAX(PWM_TIM4_NCHANNELS, \ - PWM_MAX(PWM_TIM5_NCHANNELS, \ - PWM_MAX(PWM_TIM8_NCHANNELS, \ - PWM_MAX(PWM_TIM9_NCHANNELS, \ - PWM_MAX(PWM_TIM10_NCHANNELS, \ - PWM_MAX(PWM_TIM11_NCHANNELS, \ - PWM_MAX(PWM_TIM12_NCHANNELS, \ - PWM_MAX(PWM_TIM13_NCHANNELS, \ - PWM_MAX(PWM_TIM14_NCHANNELS, \ - PWM_MAX(PWM_TIM15_NCHANNELS, \ - PWM_MAX(PWM_TIM16_NCHANNELS, \ - PWM_TIM17_NCHANNELS)))))))))))))) - -#else +#else /* !CONFIG_PWM_MULTICHAN */ /* For each timer that is enabled for PWM usage, we need the following additional * configuration settings: @@ -730,22 +373,19 @@ # elif CONFIG_STM32_TIM1_CHANNEL == 1 # define CONFIG_STM32_TIM1_CHANNEL1 1 # define CONFIG_STM32_TIM1_CH1MODE CONFIG_STM32_TIM1_CHMODE -# define PWM_TIM1_CH1CFG GPIO_TIM1_CH1OUT # elif CONFIG_STM32_TIM1_CHANNEL == 2 # define CONFIG_STM32_TIM1_CHANNEL2 1 # define CONFIG_STM32_TIM1_CH2MODE CONFIG_STM32_TIM1_CHMODE -# define PWM_TIM1_CH2CFG GPIO_TIM1_CH2OUT # elif CONFIG_STM32_TIM1_CHANNEL == 3 # define CONFIG_STM32_TIM1_CHANNEL3 1 # define CONFIG_STM32_TIM1_CH3MODE CONFIG_STM32_TIM1_CHMODE -# define PWM_TIM1_CH3CFG GPIO_TIM1_CH3OUT # elif CONFIG_STM32_TIM1_CHANNEL == 4 # define CONFIG_STM32_TIM1_CHANNEL4 1 # define CONFIG_STM32_TIM1_CH4MODE CONFIG_STM32_TIM1_CHMODE -# define PWM_TIM1_CH4CFG GPIO_TIM1_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM1_CHANNEL" # endif +# define PWM_TIM1_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM2_PWM @@ -754,22 +394,19 @@ # elif CONFIG_STM32_TIM2_CHANNEL == 1 # define CONFIG_STM32_TIM2_CHANNEL1 1 # define CONFIG_STM32_TIM2_CH1MODE CONFIG_STM32_TIM2_CHMODE -# define PWM_TIM2_CH1CFG GPIO_TIM2_CH1OUT_1 # elif CONFIG_STM32_TIM2_CHANNEL == 2 # define CONFIG_STM32_TIM2_CHANNEL2 1 # define CONFIG_STM32_TIM2_CH2MODE CONFIG_STM32_TIM2_CHMODE -# define PWM_TIM2_CH2CFG GPIO_TIM2_CH2OUT # elif CONFIG_STM32_TIM2_CHANNEL == 3 # define CONFIG_STM32_TIM2_CHANNEL3 1 # define CONFIG_STM32_TIM2_CH3MODE CONFIG_STM32_TIM2_CHMODE -# define PWM_TIM2_CH3CFG GPIO_TIM2_CH3OUT # elif CONFIG_STM32_TIM2_CHANNEL == 4 # define CONFIG_STM32_TIM2_CHANNEL4 1 # define CONFIG_STM32_TIM2_CH4MODE CONFIG_STM32_TIM2_CHMODE -# define PWM_TIM2_CH4CFG GPIO_TIM2_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM2_CHANNEL" # endif +# define PWM_TIM2_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM3_PWM @@ -778,22 +415,19 @@ # elif CONFIG_STM32_TIM3_CHANNEL == 1 # define CONFIG_STM32_TIM3_CHANNEL1 1 # define CONFIG_STM32_TIM3_CH1MODE CONFIG_STM32_TIM3_CHMODE -# define PWM_TIM3_CH1CFG GPIO_TIM3_CH1OUT # elif CONFIG_STM32_TIM3_CHANNEL == 2 # define CONFIG_STM32_TIM3_CHANNEL2 1 # define CONFIG_STM32_TIM3_CH2MODE CONFIG_STM32_TIM3_CHMODE -# define PWM_TIM3_CH2CFG GPIO_TIM3_CH2OUT # elif CONFIG_STM32_TIM3_CHANNEL == 3 # define CONFIG_STM32_TIM3_CHANNEL3 1 # define CONFIG_STM32_TIM3_CH3MODE CONFIG_STM32_TIM3_CHMODE -# define PWM_TIM3_CH3CFG GPIO_TIM3_CH3OUT # elif CONFIG_STM32_TIM3_CHANNEL == 4 # define CONFIG_STM32_TIM3_CHANNEL4 1 # define CONFIG_STM32_TIM3_CH4MODE CONFIG_STM32_TIM3_CHMODE -# define PWM_TIM3_CH4CFG GPIO_TIM3_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM3_CHANNEL" # endif +# define PWM_TIM3_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM4_PWM @@ -802,22 +436,19 @@ # elif CONFIG_STM32_TIM4_CHANNEL == 1 # define CONFIG_STM32_TIM4_CHANNEL1 1 # define CONFIG_STM32_TIM4_CH1MODE CONFIG_STM32_TIM4_CHMODE -# define PWM_TIM4_CH1CFG GPIO_TIM4_CH1OUT # elif CONFIG_STM32_TIM4_CHANNEL == 2 # define CONFIG_STM32_TIM4_CHANNEL2 1 # define CONFIG_STM32_TIM4_CH2MODE CONFIG_STM32_TIM4_CHMODE -# define PWM_TIM4_CH2CFG GPIO_TIM4_CH2OUT # elif CONFIG_STM32_TIM4_CHANNEL == 3 # define CONFIG_STM32_TIM4_CHANNEL3 1 # define CONFIG_STM32_TIM4_CH3MODE CONFIG_STM32_TIM4_CHMODE -# define PWM_TIM4_CH3CFG GPIO_TIM4_CH3OUT # elif CONFIG_STM32_TIM4_CHANNEL == 4 # define CONFIG_STM32_TIM4_CHANNEL4 1 # define CONFIG_STM32_TIM4_CH4MODE CONFIG_STM32_TIM4_CHMODE -# define PWM_TIM4_CH4CFG GPIO_TIM4_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM4_CHANNEL" # endif +# define PWM_TIM4_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM5_PWM @@ -826,22 +457,19 @@ # elif CONFIG_STM32_TIM5_CHANNEL == 1 # define CONFIG_STM32_TIM5_CHANNEL1 1 # define CONFIG_STM32_TIM5_CH1MODE CONFIG_STM32_TIM5_CHMODE -# define PWM_TIM5_CH1CFG GPIO_TIM5_CH1OUT # elif CONFIG_STM32_TIM5_CHANNEL == 2 # define CONFIG_STM32_TIM5_CHANNEL2 1 # define CONFIG_STM32_TIM5_CH2MODE CONFIG_STM32_TIM5_CHMODE -# define PWM_TIM5_CH2CFG GPIO_TIM5_CH2OUT # elif CONFIG_STM32_TIM5_CHANNEL == 3 # define CONFIG_STM32_TIM5_CHANNEL3 1 # define CONFIG_STM32_TIM5_CH3MODE CONFIG_STM32_TIM5_CHMODE -# define PWM_TIM5_CH3CFG GPIO_TIM5_CH3OUT # elif CONFIG_STM32_TIM5_CHANNEL == 4 # define CONFIG_STM32_TIM5_CHANNEL4 1 # define CONFIG_STM32_TIM5_CH4MODE CONFIG_STM32_TIM5_CHMODE -# define PWM_TIM5_CH4CFG GPIO_TIM5_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM5_CHANNEL" # endif +# define PWM_TIM5_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM8_PWM @@ -850,22 +478,19 @@ # elif CONFIG_STM32_TIM8_CHANNEL == 1 # define CONFIG_STM32_TIM8_CHANNEL1 1 # define CONFIG_STM32_TIM8_CH1MODE CONFIG_STM32_TIM8_CHMODE -# define PWM_TIM8_CH1CFG GPIO_TIM8_CH1OUT # elif CONFIG_STM32_TIM8_CHANNEL == 2 # define CONFIG_STM32_TIM8_CHANNEL2 1 # define CONFIG_STM32_TIM8_CH2MODE CONFIG_STM32_TIM8_CHMODE -# define PWM_TIM8_CH2CFG GPIO_TIM8_CH2OUT # elif CONFIG_STM32_TIM8_CHANNEL == 3 # define CONFIG_STM32_TIM8_CHANNEL3 1 # define CONFIG_STM32_TIM8_CH3MODE CONFIG_STM32_TIM8_CHMODE -# define PWM_TIM8_CH3CFG GPIO_TIM8_CH3OUT # elif CONFIG_STM32_TIM8_CHANNEL == 4 # define CONFIG_STM32_TIM8_CHANNEL4 1 # define CONFIG_STM32_TIM8_CH4MODE CONFIG_STM32_TIM8_CHMODE -# define PWM_TIM8_CH4CFG GPIO_TIM8_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM8_CHANNEL" # endif +# define PWM_TIM8_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM9_PWM @@ -874,22 +499,13 @@ # elif CONFIG_STM32_TIM9_CHANNEL == 1 # define CONFIG_STM32_TIM9_CHANNEL1 1 # define CONFIG_STM32_TIM9_CH1MODE CONFIG_STM32_TIM9_CHMODE -# define PWM_TIM9_CH1CFG GPIO_TIM9_CH1OUT # elif CONFIG_STM32_TIM9_CHANNEL == 2 # define CONFIG_STM32_TIM9_CHANNEL2 1 # define CONFIG_STM32_TIM9_CH2MODE CONFIG_STM32_TIM9_CHMODE -# define PWM_TIM9_CH2CFG GPIO_TIM9_CH2OUT -# elif CONFIG_STM32_TIM9_CHANNEL == 3 -# define CONFIG_STM32_TIM9_CHANNEL3 1 -# define CONFIG_STM32_TIM9_CH3MODE CONFIG_STM32_TIM9_CHMODE -# define PWM_TIM9_CH3CFG GPIO_TIM9_CH3OUT -# elif CONFIG_STM32_TIM9_CHANNEL == 4 -# define CONFIG_STM32_TIM9_CHANNEL4 1 -# define CONFIG_STM32_TIM9_CH4MODE CONFIG_STM32_TIM9_CHMODE -# define PWM_TIM9_CH4CFG GPIO_TIM9_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM9_CHANNEL" # endif +# define PWM_TIM9_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM10_PWM @@ -898,22 +514,10 @@ # elif CONFIG_STM32_TIM10_CHANNEL == 1 # define CONFIG_STM32_TIM10_CHANNEL1 1 # define CONFIG_STM32_TIM10_CH1MODE CONFIG_STM32_TIM10_CHMODE -# define PWM_TIM10_CH1CFG GPIO_TIM10_CH1OUT -# elif CONFIG_STM32_TIM10_CHANNEL == 2 -# define CONFIG_STM32_TIM10_CHANNEL2 1 -# define CONFIG_STM32_TIM10_CH2MODE CONFIG_STM32_TIM10_CHMODE -# define PWM_TIM10_CH2CFG GPIO_TIM10_CH2OUT -# elif CONFIG_STM32_TIM10_CHANNEL == 3 -# define CONFIG_STM32_TIM10_CHANNEL3 1 -# define CONFIG_STM32_TIM10_CH3MODE CONFIG_STM32_TIM10_CHMODE -# define PWM_TIM10_CH3CFG GPIO_TIM10_CH3OUT -# elif CONFIG_STM32_TIM10_CHANNEL == 4 -# define CONFIG_STM32_TIM10_CHANNEL4 1 -# define CONFIG_STM32_TIM10_CH4MODE CONFIG_STM32_TIM10_CHMODE -# define PWM_TIM10_CH4CFG GPIO_TIM10_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM10_CHANNEL" # endif +# define PWM_TIM10_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM11_PWM @@ -922,22 +526,10 @@ # elif CONFIG_STM32_TIM11_CHANNEL == 1 # define CONFIG_STM32_TIM11_CHANNEL1 1 # define CONFIG_STM32_TIM11_CH1MODE CONFIG_STM32_TIM11_CHMODE -# define PWM_TIM11_CH1CFG GPIO_TIM11_CH1OUT -# elif CONFIG_STM32_TIM11_CHANNEL == 2 -# define CONFIG_STM32_TIM11_CHANNEL2 1 -# define CONFIG_STM32_TIM11_CH2MODE CONFIG_STM32_TIM11_CHMODE -# define PWM_TIM11_CH2CFG GPIO_TIM11_CH2OUT -# elif CONFIG_STM32_TIM11_CHANNEL == 3 -# define CONFIG_STM32_TIM11_CHANNEL3 1 -# define CONFIG_STM32_TIM11_CH3MODE CONFIG_STM32_TIM11_CHMODE -# define PWM_TIM11_CH3CFG GPIO_TIM11_CH3OUT -# elif CONFIG_STM32_TIM11_CHANNEL == 4 -# define CONFIG_STM32_TIM11_CHANNEL4 1 -# define CONFIG_STM32_TIM11_CH4MODE CONFIG_STM32_TIM11_CHMODE -# define PWM_TIM11_CH4CFG GPIO_TIM11_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM11_CHANNEL" # endif +# define PWM_TIM11_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM12_PWM @@ -946,22 +538,13 @@ # elif CONFIG_STM32_TIM12_CHANNEL == 1 # define CONFIG_STM32_TIM12_CHANNEL1 1 # define CONFIG_STM32_TIM12_CH1MODE CONFIG_STM32_TIM12_CHMODE -# define PWM_TIM12_CH1CFG GPIO_TIM12_CH1OUT # elif CONFIG_STM32_TIM12_CHANNEL == 2 # define CONFIG_STM32_TIM12_CHANNEL2 1 # define CONFIG_STM32_TIM12_CH2MODE CONFIG_STM32_TIM12_CHMODE -# define PWM_TIM12_CH2CFG GPIO_TIM12_CH2OUT -# elif CONFIG_STM32_TIM12_CHANNEL == 3 -# define CONFIG_STM32_TIM12_CHANNEL3 1 -# define CONFIG_STM32_TIM12_CH3MODE CONFIG_STM32_TIM12_CHMODE -# define PWM_TIM12_CH3CFG GPIO_TIM12_CH3OUT -# elif CONFIG_STM32_TIM12_CHANNEL == 4 -# define CONFIG_STM32_TIM12_CHANNEL4 1 -# define CONFIG_STM32_TIM12_CH4MODE CONFIG_STM32_TIM12_CHMODE -# define PWM_TIM12_CH4CFG GPIO_TIM12_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM12_CHANNEL" # endif +# define PWM_TIM12_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM13_PWM @@ -970,22 +553,10 @@ # elif CONFIG_STM32_TIM13_CHANNEL == 1 # define CONFIG_STM32_TIM13_CHANNEL1 1 # define CONFIG_STM32_TIM13_CH1MODE CONFIG_STM32_TIM13_CHMODE -# define PWM_TIM13_CH1CFG GPIO_TIM13_CH1OUT -# elif CONFIG_STM32_TIM13_CHANNEL == 2 -# define CONFIG_STM32_TIM13_CHANNEL2 1 -# define CONFIG_STM32_TIM13_CH2MODE CONFIG_STM32_TIM13_CHMODE -# define PWM_TIM13_CH2CFG GPIO_TIM13_CH2OUT -# elif CONFIG_STM32_TIM13_CHANNEL == 3 -# define CONFIG_STM32_TIM13_CHANNEL3 1 -# define CONFIG_STM32_TIM13_CH3MODE CONFIG_STM32_TIM13_CHMODE -# define PWM_TIM13_CH3CFG GPIO_TIM13_CH3OUT -# elif CONFIG_STM32_TIM13_CHANNEL == 4 -# define CONFIG_STM32_TIM13_CHANNEL4 1 -# define CONFIG_STM32_TIM13_CH4MODE CONFIG_STM32_TIM13_CHMODE -# define PWM_TIM13_CH4CFG GPIO_TIM13_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM13_CHANNEL" # endif +# define PWM_TIM13_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM14_PWM @@ -994,22 +565,10 @@ # elif CONFIG_STM32_TIM14_CHANNEL == 1 # define CONFIG_STM32_TIM14_CHANNEL1 1 # define CONFIG_STM32_TIM14_CH1MODE CONFIG_STM32_TIM14_CHMODE -# define PWM_TIM14_CH1CFG GPIO_TIM14_CH1OUT -# elif CONFIG_STM32_TIM14_CHANNEL == 2 -# define CONFIG_STM32_TIM14_CHANNEL2 1 -# define CONFIG_STM32_TIM14_CH2MODE CONFIG_STM32_TIM14_CHMODE -# define PWM_TIM14_CH2CFG GPIO_TIM14_CH2OUT -# elif CONFIG_STM32_TIM14_CHANNEL == 3 -# define CONFIG_STM32_TIM14_CHANNEL3 1 -# define CONFIG_STM32_TIM14_CH3MODE CONFIG_STM32_TIM14_CHMODE -# define PWM_TIM14_CH3CFG GPIO_TIM14_CH3OUT -# elif CONFIG_STM32_TIM14_CHANNEL == 4 -# define CONFIG_STM32_TIM14_CHANNEL4 1 -# define CONFIG_STM32_TIM14_CH4MODE CONFIG_STM32_TIM14_CHMODE -# define PWM_TIM14_CH4CFG GPIO_TIM14_CH4OUT # else # error "Unsupported value of CONFIG_STM32_TIM14_CHANNEL" # endif +# define PWM_TIM14_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM15_PWM @@ -1018,14 +577,13 @@ # elif CONFIG_STM32_TIM15_CHANNEL == 1 # define CONFIG_STM32_TIM15_CHANNEL1 1 # define CONFIG_STM32_TIM15_CH1MODE CONFIG_STM32_TIM15_CHMODE -# define PWM_TIM15_CH1CFG GPIO_TIM15_CH1OUT # elif CONFIG_STM32_TIM15_CHANNEL == 2 # define CONFIG_STM32_TIM15_CHANNEL2 1 # define CONFIG_STM32_TIM15_CH2MODE CONFIG_STM32_TIM15_CHMODE -# define PWM_TIM15_CH2CFG GPIO_TIM15_CH2OUT # else # error "Unsupported value of CONFIG_STM32_TIM15_CHANNEL" # endif +# define PWM_TIM15_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM16_PWM @@ -1034,10 +592,10 @@ # elif CONFIG_STM32_TIM16_CHANNEL == 1 # define CONFIG_STM32_TIM16_CHANNEL1 1 # define CONFIG_STM32_TIM16_CH1MODE CONFIG_STM32_TIM16_CHMODE -# define PWM_TIM16_CH1CFG GPIO_TIM16_CH1OUT # else # error "Unsupported value of CONFIG_STM32_TIM16_CHANNEL" # endif +# define PWM_TIM16_NCHANNELS 1 #endif #ifdef CONFIG_STM32_TIM17_PWM @@ -1046,20 +604,362 @@ # elif CONFIG_STM32_TIM17_CHANNEL == 1 # define CONFIG_STM32_TIM17_CHANNEL1 1 # define CONFIG_STM32_TIM17_CH1MODE CONFIG_STM32_TIM17_CHMODE -# define PWM_TIM17_CH1CFG GPIO_TIM17_CH1OUT # else # error "Unsupported value of CONFIG_STM32_TIM17_CHANNEL" # endif +# define PWM_TIM17_NCHANNELS 1 #endif -#define PWM_NCHANNELS 1 +#endif /* CONFIG_PWM_MULTICHAN */ +#ifdef CONFIG_STM32_TIM1_CH1OUT +# define PWM_TIM1_CH1CFG GPIO_TIM1_CH1OUT +#else +# define PWM_TIM1_CH1CFG 0 #endif +#ifdef CONFIG_STM32_TIM1_CH1NOUT +# define PWM_TIM1_CH1NCFG GPIO_TIM1_CH1NOUT +#else +# define PWM_TIM1_CH1NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM1_CH2OUT +# define PWM_TIM1_CH2CFG GPIO_TIM1_CH2OUT +#else +# define PWM_TIM1_CH2CFG 0 +#endif +#ifdef CONFIG_STM32_TIM1_CH2NOUT +# define PWM_TIM1_CH2NCFG GPIO_TIM1_CH2NOUT +#else +# define PWM_TIM1_CH2NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM1_CH3OUT +# define PWM_TIM1_CH3CFG GPIO_TIM1_CH3OUT +#else +# define PWM_TIM1_CH3CFG 0 +#endif +#ifdef CONFIG_STM32_TIM1_CH3NOUT +# define PWM_TIM1_CH3NCFG GPIO_TIM1_CH3NOUT +#else +# define PWM_TIM1_CH3NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM1_CH4OUT +# define PWM_TIM1_CH4CFG GPIO_TIM1_CH4OUT +#else +# define PWM_TIM1_CH4CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM2_CH1OUT +# define PWM_TIM2_CH1CFG GPIO_TIM2_CH1OUT +#else +# define PWM_TIM2_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM2_CH2OUT +# define PWM_TIM2_CH2CFG GPIO_TIM2_CH2OUT +#else +# define PWM_TIM2_CH2CFG 0 +#endif +#ifdef CONFIG_STM32_TIM2_CH3OUT +# define PWM_TIM2_CH3CFG GPIO_TIM2_CH3OUT +#else +# define PWM_TIM2_CH3CFG 0 +#endif +#ifdef CONFIG_STM32_TIM2_CH4OUT +# define PWM_TIM2_CH4CFG GPIO_TIM2_CH4OUT +#else +# define PWM_TIM2_CH4CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM3_CH1OUT +# define PWM_TIM3_CH1CFG GPIO_TIM3_CH1OUT +#else +# define PWM_TIM3_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM3_CH2OUT +# define PWM_TIM3_CH2CFG GPIO_TIM3_CH2OUT +#else +# define PWM_TIM3_CH2CFG 0 +#endif +#ifdef CONFIG_STM32_TIM3_CH3OUT +# define PWM_TIM3_CH3CFG GPIO_TIM3_CH3OUT +#else +# define PWM_TIM3_CH3CFG 0 +#endif +#ifdef CONFIG_STM32_TIM3_CH4OUT +# define PWM_TIM3_CH4CFG GPIO_TIM3_CH4OUT +#else +# define PWM_TIM3_CH4CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM4_CH1OUT +# define PWM_TIM4_CH1CFG GPIO_TIM4_CH1OUT +#else +# define PWM_TIM4_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM4_CH2OUT +# define PWM_TIM4_CH2CFG GPIO_TIM4_CH2OUT +#else +# define PWM_TIM4_CH2CFG 0 +#endif +#ifdef CONFIG_STM32_TIM4_CH3OUT +# define PWM_TIM4_CH3CFG GPIO_TIM4_CH3OUT +#else +# define PWM_TIM4_CH3CFG 0 +#endif +#ifdef CONFIG_STM32_TIM4_CH4OUT +# define PWM_TIM4_CH4CFG GPIO_TIM4_CH4OUT +#else +# define PWM_TIM4_CH4CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM5_CH1OUT +# define PWM_TIM5_CH1CFG GPIO_TIM5_CH1OUT +#else +# define PWM_TIM5_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM5_CH2OUT +# define PWM_TIM5_CH2CFG GPIO_TIM5_CH2OUT +#else +# define PWM_TIM5_CH2CFG 0 +#endif +#ifdef CONFIG_STM32_TIM5_CH3OUT +# define PWM_TIM5_CH3CFG GPIO_TIM5_CH3OUT +#else +# define PWM_TIM5_CH3CFG 0 +#endif +#ifdef CONFIG_STM32_TIM5_CH4OUT +# define PWM_TIM5_CH4CFG GPIO_TIM5_CH4OUT +#else +# define PWM_TIM5_CH4CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM8_CH1OUT +# define PWM_TIM8_CH1CFG GPIO_TIM8_CH1OUT +#else +# define PWM_TIM8_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM8_CH1NOUT +# define PWM_TIM8_CH1NCFG GPIO_TIM8_CH1NOUT +#else +# define PWM_TIM8_CH1NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM8_CH2OUT +# define PWM_TIM8_CH2CFG GPIO_TIM8_CH2OUT +#else +# define PWM_TIM8_CH2CFG 0 +#endif +#ifdef CONFIG_STM32_TIM8_CH2NOUT +# define PWM_TIM8_CH2NCFG GPIO_TIM8_CH2NOUT +#else +# define PWM_TIM8_CH2NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM8_CH3OUT +# define PWM_TIM8_CH3CFG GPIO_TIM8_CH3OUT +#else +# define PWM_TIM8_CH3CFG 0 +#endif +#ifdef CONFIG_STM32_TIM8_CH3NOUT +# define PWM_TIM8_CH3NCFG GPIO_TIM8_CH3NOUT +#else +# define PWM_TIM8_CH3NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM8_CH4OUT +# define PWM_TIM8_CH4CFG GPIO_TIM8_CH4OUT +#else +# define PWM_TIM8_CH4CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM9_CH1OUT +# define PWM_TIM9_CH1CFG GPIO_TIM9_CH1OUT +#else +# define PWM_TIM9_CH1CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM9_CH2OUT +# define PWM_TIM9_CH2CFG GPIO_TIM9_CH2OUT +#else +# define PWM_TIM9_CH2CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM10_CH1OUT +# define PWM_TIM10_CH1CFG GPIO_TIM10_CH1OUT +#else +# define PWM_TIM10_CH1CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM11_CH1OUT +# define PWM_TIM11_CH1CFG GPIO_TIM11_CH1OUT +#else +# define PWM_TIM11_CH1CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM12_CH1OUT +# define PWM_TIM12_CH1CFG GPIO_TIM12_CH1OUT +#else +# define PWM_TIM12_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM12_CH2OUT +# define PWM_TIM12_CH2CFG GPIO_TIM12_CH2OUT +#else +# define PWM_TIM12_CH2CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM13_CH1OUT +# define PWM_TIM13_CH1CFG GPIO_TIM13_CH1OUT +#else +# define PWM_TIM13_CH1CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM14_CH1OUT +# define PWM_TIM14_CH1CFG GPIO_TIM14_CH1OUT +#else +# define PWM_TIM14_CH1CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM15_CH1OUT +# define PWM_TIM15_CH1CFG GPIO_TIM15_CH1OUT +#else +# define PWM_TIM15_CH1CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM15_CH1NOUT +# define PWM_TIM15_CH1NCFG GPIO_TIM15_CH1NOUT +#else +# define PWM_TIM15_CH1NCFG 0 +#endif +#ifdef CONFIG_STM32_TIM15_CH2OUT +# define PWM_TIM15_CH2CFG GPIO_TIM15_CH2OUT +#else +# define PWM_TIM15_CH2CFG 0 +#endif + +#ifdef CONFIG_STM32_TIM16_CH1OUT +# define PWM_TIM16_CH1CFG GPIO_TIM16_CH1OUT +#else +# define PWM_TIM16_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM16_CH1NOUT +# define PWM_TIM16_CH1NCFG GPIO_TIM16_CH1NOUT +#else +# define PWM_TIM16_CH1NCFG 0 +#endif + +#ifdef CONFIG_STM32_TIM17_CH1OUT +# define PWM_TIM17_CH1CFG GPIO_TIM17_CH1OUT +#else +# define PWM_TIM17_CH1CFG 0 +#endif +#ifdef CONFIG_STM32_TIM17_CH1NOUT +# define PWM_TIM17_CH1NCFG GPIO_TIM17_CH1NOUT +#else +# define PWM_TIM17_CH1NCFG 0 +#endif + /************************************************************************************ * Public Types ************************************************************************************/ +/* Timer mode */ + +enum stm32_pwm_tim_mode_e +{ + STM32_TIMMODE_COUNTUP = 0, + STM32_TIMMODE_COUNTDOWN = 1, + STM32_TIMMODE_CENTER1 = 2, + STM32_TIMMODE_CENTER2 = 3, + STM32_TIMMODE_CENTER3 = 4, +}; + +/* Timer output polarity */ + +enum stm32_pwm_pol_e +{ + STM32_POL_POS = 0, + STM32_POL_NEG = 1, +}; + +/* Timer output IDLE state */ + +enum stm32_pwm_idle_e +{ + STM32_IDLE_INACTIVE = 0, + STM32_IDLE_ACTIVE = 1 +}; + +/* PWM channel mode */ + +enum stm32_chan_mode_e +{ + STM32_CHANMODE_PWM1 = 0, + STM32_CHANMODE_PWM2 = 1, +#ifdef HAVE_IP_TIMERS_V2 + STM32_CHANMODE_COMBINED1 = 2, + STM32_CHANMODE_COMBINED2 = 3, + STM32_CHANMODE_ASYMMETRIC1 = 4, + STM32_CHANMODE_ASYMMETRIC2 = 5 +#endif +}; + +/* Timer channel */ + +enum stm32_chan_e +{ + STM32_CHAN1 = (1 << 0), + STM32_CHAN1N = (1 << 1), + STM32_CHAN2 = (1 << 2), + STM32_CHAN2N = (1 << 3), + STM32_CHAN3 = (1 << 4), + STM32_CHAN3N = (1 << 5), + STM32_CHAN4 = (1 << 6), + /* No complementary output for CH4 */ +#ifdef HAVE_IP_TIMERS_V2 + /* Only available inside micro */ + + STM32_CHAN5 = (1 << 7), + /* 1<<8 reserved */ + STM32_CHAN6 = (1 << 9), + /* 1<<10 reserved */ +#endif +}; + +#ifdef CONFIG_STM32_PWM_LL_OPS + +/* */ +struct pwm_lowerhalf_s; +struct stm32_pwm_ops_s +{ + + /* Update CCR register */ + + int (*ccr_update)(FAR struct pwm_lowerhalf_s *dev, uint8_t index, uint32_t ccr); + + /* Get CCR register */ + + uint32_t (*ccr_get)(FAR struct pwm_lowerhalf_s *dev, uint8_t index); + + /* Update ARR register */ + + int (*arr_update)(FAR struct pwm_lowerhalf_s *dev, uint32_t arr); + + /* Get ARR register */ + + uint32_t (*arr_get)(FAR struct pwm_lowerhalf_s *dev); + + /* Enable outputs */ + + int (*outputs_enable)(FAR struct pwm_lowerhalf_s *dev, uint16_t outputs, bool state); + + /* Software update */ + + int (*soft_update)(FAR struct pwm_lowerhalf_s *dev); + + /* PWM configure */ + + int (*configure)(FAR struct pwm_lowerhalf_s *dev); +}; + +#endif + /************************************************************************************ * Public Data ************************************************************************************/ @@ -1098,6 +998,15 @@ extern "C" FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer); +/************************************************************************************ + * Name: stm32_pwm_llops_get + * + ************************************************************************************/ + +#ifdef CONFIG_STM32_PWM_LL_OPS + FAR const struct stm32_pwm_ops_s *stm32_pwm_llops_get(FAR struct pwm_lowerhalf_s *dev); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/configs/nucleo-f302r8/include/board.h b/configs/nucleo-f302r8/include/board.h index 31a65c4331..c0bf3dbadf 100644 --- a/configs/nucleo-f302r8/include/board.h +++ b/configs/nucleo-f302r8/include/board.h @@ -218,4 +218,24 @@ /* DMA channels *************************************************************/ + +/* PWM configuration ********************************************************/ + +/* TIM1 PWM */ + +#define STM32_TIM1_TRGO 0 + +#define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_2 /* PA8 */ +#define GPIO_TIM1_CH1NOUT GPIO_TIM1_CH1N_3 /* PA11 */ +#define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_2 /* PA9 */ +#define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_2 /* PA12 */ +#define GPIO_TIM1_CH3OUT GPIO_TIM1_CH3OUT_2 /* PA10 */ +#define GPIO_TIM1_CH3NOUT GPIO_TIM1_CH3N_3 /* PB1 */ + +/* TIM2 PWM */ + +#define GPIO_TIM2_CH1OUT GPIO_TIM2_CH1_ETR_1 /* PA0 */ +#define GPIO_TIM2_CH2OUT GPIO_TIM2_CH2OUT_1 /* PA1 */ +#define GPIO_TIM2_CH3OUT GPIO_TIM2_CH3OUT_1 /* PA9 */ + #endif /* __CONFIG_NUCLEO_F302R8_INCLUDE_BOARD_H */ diff --git a/configs/nucleo-f302r8/src/Makefile b/configs/nucleo-f302r8/src/Makefile index 45266ef3ce..83f6fe7c00 100644 --- a/configs/nucleo-f302r8/src/Makefile +++ b/configs/nucleo-f302r8/src/Makefile @@ -52,4 +52,8 @@ ifeq ($(CONFIG_LIB_BOARDCTL),y) CSRCS += stm32_appinitialize.c endif +ifeq ($(CONFIG_PWM),y) +CSRCS += stm32_pwm.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/nucleo-f302r8/src/nucleo-f302r8.h b/configs/nucleo-f302r8/src/nucleo-f302r8.h index af924368d9..91a571edef 100644 --- a/configs/nucleo-f302r8/src/nucleo-f302r8.h +++ b/configs/nucleo-f302r8/src/nucleo-f302r8.h @@ -88,6 +88,10 @@ #define GPIO_BTN_USER (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTC|GPIO_PIN13) +/* PWM */ + +#define NUCLEOF302R8_PWMTIMER 1 + /**************************************************************************** * Public Data ****************************************************************************/ @@ -96,4 +100,16 @@ * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +#ifdef CONFIG_PWM +int stm32_pwm_setup(void); +#endif + #endif /* __CONFIGS_NUCLEO_F302R8_SRC_NUCLEO_F302R8_H */ diff --git a/configs/nucleo-f302r8/src/stm32_appinitialize.c b/configs/nucleo-f302r8/src/stm32_appinitialize.c index ffe43e3c84..a248ccd48a 100644 --- a/configs/nucleo-f302r8/src/stm32_appinitialize.c +++ b/configs/nucleo-f302r8/src/stm32_appinitialize.c @@ -106,6 +106,16 @@ int board_app_initialize(uintptr_t arg) } #endif +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device. */ + + ret = stm32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret); + } +#endif + UNUSED(ret); return OK; } diff --git a/configs/nucleo-f302r8/src/stm32_pwm.c b/configs/nucleo-f302r8/src/stm32_pwm.c new file mode 100644 index 0000000000..51574e9d79 --- /dev/null +++ b/configs/nucleo-f302r8/src/stm32_pwm.c @@ -0,0 +1,122 @@ +/************************************************************************************ + * configs/nucleo-f302r8/src/stm32_pwm.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Authors: Mateusz Szafoni + * + * 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 "chip.h" +#include "up_arch.h" +#include "stm32_pwm.h" +#include "nucleo-f302r8.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration *******************************************************************/ + +#define HAVE_PWM 1 + +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM1 +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM1_PWM +# undef HAVE_PWM +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ************************************************************************************/ + +int stm32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + pwm = stm32_pwminitialize(NUCLEOF302R8_PWMTIMER); + if (!pwm) + { + tmrerr("ERROR: Failed to get the STM32 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm0" */ + + ret = pwm_register("/dev/pwm0", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENODEV; +#endif +} diff --git a/configs/stm32f103-minimum/audio_tone/defconfig b/configs/stm32f103-minimum/audio_tone/defconfig index 4b7da85a6a..ba110d67f4 100644 --- a/configs/stm32f103-minimum/audio_tone/defconfig +++ b/configs/stm32f103-minimum/audio_tone/defconfig @@ -50,6 +50,7 @@ CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y CONFIG_STM32_JTAG_FULL_ENABLE=y CONFIG_STM32_ONESHOT=y CONFIG_STM32_TIM2=y +CONFIG_STM32_TIM2_CH2OUT=y CONFIG_STM32_TIM2_CHANNEL=2 CONFIG_STM32_TIM2_PWM=y CONFIG_STM32_TIM3=y diff --git a/configs/stm32f103-minimum/pwm/defconfig b/configs/stm32f103-minimum/pwm/defconfig index a0cf99fbbd..e7703b8c40 100644 --- a/configs/stm32f103-minimum/pwm/defconfig +++ b/configs/stm32f103-minimum/pwm/defconfig @@ -48,6 +48,7 @@ CONFIG_START_YEAR=2011 CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y CONFIG_STM32_JTAG_FULL_ENABLE=y CONFIG_STM32_TIM3=y +CONFIG_STM32_TIM3_CH3OUT=y CONFIG_STM32_TIM3_CHANNEL=3 CONFIG_STM32_TIM3_PWM=y CONFIG_STM32_USART1=y diff --git a/configs/stm32f103-minimum/rgbled/defconfig b/configs/stm32f103-minimum/rgbled/defconfig index 9fd85e12f1..967326d648 100644 --- a/configs/stm32f103-minimum/rgbled/defconfig +++ b/configs/stm32f103-minimum/rgbled/defconfig @@ -48,14 +48,18 @@ CONFIG_START_YEAR=2011 CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y CONFIG_STM32_JTAG_FULL_ENABLE=y CONFIG_STM32_TIM1=y +CONFIG_STM32_TIM1_CH1OUT=y CONFIG_STM32_TIM1_PWM=y CONFIG_STM32_TIM2=y +CONFIG_STM32_TIM2_CH2OUT=y CONFIG_STM32_TIM2_CHANNEL=2 CONFIG_STM32_TIM2_PWM=y CONFIG_STM32_TIM3=y +CONFIG_STM32_TIM3_CH3OUT=y CONFIG_STM32_TIM3_CHANNEL=3 CONFIG_STM32_TIM3_PWM=y CONFIG_STM32_TIM4=y +CONFIG_STM32_TIM4_CH4OUT=y CONFIG_STM32_TIM4_CHANNEL=4 CONFIG_STM32_TIM4_PWM=y CONFIG_STM32_USART1=y diff --git a/configs/stm32f429i-disco/include/board.h b/configs/stm32f429i-disco/include/board.h index 8774b70f28..c6db54ba9d 100644 --- a/configs/stm32f429i-disco/include/board.h +++ b/configs/stm32f429i-disco/include/board.h @@ -224,6 +224,13 @@ #define GPIO_TIM4_CH2OUT GPIO_TIM4_CH2OUT_2 +#define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_2 /* PE9 */ +#define GPIO_TIM1_CH1NOUT GPIO_TIM1_CH1N_3 /* PE8 */ +#define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_2 /* PE11 */ +#define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_3 /* PE10 */ +#define GPIO_TIM1_CH3OUT GPIO_TIM1_CH3OUT_2 /* PE13 */ +#define GPIO_TIM1_CH3NOUT GPIO_TIM1_CH3N_3 /* PE12 */ + /* I2C - There is a STMPE811 TouchPanel on I2C3 using these pins: */ #define GPIO_I2C3_SCL GPIO_I2C3_SCL_1 diff --git a/configs/stm32f429i-disco/src/Makefile b/configs/stm32f429i-disco/src/Makefile index 430b7d201b..d00fe9fa79 100644 --- a/configs/stm32f429i-disco/src/Makefile +++ b/configs/stm32f429i-disco/src/Makefile @@ -87,4 +87,8 @@ ifeq ($(CONFIG_ARCH_FPU),y) CSRCS += stm32_ostest.c endif +ifeq ($(CONFIG_PWM),y) +CSRCS += stm32_pwm.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/stm32f429i-disco/src/stm32_bringup.c b/configs/stm32f429i-disco/src/stm32_bringup.c index 3ec0651fe9..5d8bdc223d 100644 --- a/configs/stm32f429i-disco/src/stm32_bringup.c +++ b/configs/stm32f429i-disco/src/stm32_bringup.c @@ -365,6 +365,17 @@ int stm32_bringup(void) } #endif + +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device. */ + + ret = stm32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret); + } +#endif + UNUSED(ret); return OK; } diff --git a/configs/stm32f429i-disco/src/stm32_pwm.c b/configs/stm32f429i-disco/src/stm32_pwm.c new file mode 100644 index 0000000000..600b326c1a --- /dev/null +++ b/configs/stm32f429i-disco/src/stm32_pwm.c @@ -0,0 +1,126 @@ +/************************************************************************************ + * configs/nucleo-f302r8/src/stm32_pwm.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Authors: Mateusz Szafoni + * + * 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 "chip.h" +#include "up_arch.h" +#include "stm32_pwm.h" +#include "stm32f429i-disco.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration *******************************************************************/ + +/* PWM Timer */ + +#define STM32F429IDISCO_PWMTIMER 1 + +#define HAVE_PWM 1 + +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM1 +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM1_PWM +# undef HAVE_PWM +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ************************************************************************************/ + +int stm32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + pwm = stm32_pwminitialize(STM32F429IDISCO_PWMTIMER); + if (!pwm) + { + tmrerr("ERROR: Failed to get the STM32 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm0" */ + + ret = pwm_register("/dev/pwm0", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENODEV; +#endif +} diff --git a/configs/stm32f429i-disco/src/stm32f429i-disco.h b/configs/stm32f429i-disco/src/stm32f429i-disco.h index 18063a5391..8fc6be2966 100644 --- a/configs/stm32f429i-disco/src/stm32f429i-disco.h +++ b/configs/stm32f429i-disco/src/stm32f429i-disco.h @@ -391,5 +391,17 @@ FAR struct spi_dev_s *stm32_spi5initialize(void); int stm32_l3gd20initialize(FAR const char *devpath); #endif +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +#ifdef CONFIG_PWM +int stm32_pwm_setup(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_STM32F429I_DISCO_SRC_STM32F429I_DISCO_H */ diff --git a/configs/stm32f4discovery/rgbled/defconfig b/configs/stm32f4discovery/rgbled/defconfig index 1d238f90b9..0163ff32af 100644 --- a/configs/stm32f4discovery/rgbled/defconfig +++ b/configs/stm32f4discovery/rgbled/defconfig @@ -50,9 +50,11 @@ CONFIG_STM32_SPI1=y CONFIG_STM32_TIM1=y CONFIG_STM32_TIM1_PWM=y CONFIG_STM32_TIM2=y +CONFIG_STM32_TIM2_CH2OUT=y CONFIG_STM32_TIM2_CHANNEL=2 CONFIG_STM32_TIM2_PWM=y CONFIG_STM32_TIM3=y +CONFIG_STM32_TIM3_CH3OUT=y CONFIG_STM32_TIM3_CHANNEL=3 CONFIG_STM32_TIM3_PWM=y CONFIG_STM32_USART2=y diff --git a/configs/stm32f4discovery/xen1210/defconfig b/configs/stm32f4discovery/xen1210/defconfig index 2e4b42d571..a6b05c7dc3 100644 --- a/configs/stm32f4discovery/xen1210/defconfig +++ b/configs/stm32f4discovery/xen1210/defconfig @@ -47,6 +47,7 @@ CONFIG_STM32_PWR=y CONFIG_STM32_SPI1=y CONFIG_STM32_TIM1=y CONFIG_STM32_TIM1_PWM=y +CONFIG_STM32_TIM1_CH1OUT=y CONFIG_STM32_USART2=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_NSH_CXXINITIALIZE=y