Merged in kyChuGit/nuttx (pull request #1077)

STM23L4 LPTIM PWM support with multi-channel

* arch/arm/src/stm32l4/stm32l4_pwm.c:
        fixed some bugs
    arch/arm/src/stm32l4/stm32l4_pwm.h:
        support LPTIM PWM if PWM multi-channel is selected
        Channel mode for LPTIM are not available

* arch/arm/src/stm32l4/Kconfig:  add new configuration for STM32L4 LPTIM support

* arch/arm/src/stm32l4/stm32l4_pwm.c:  fix warning: resetbit may be used uninitialized

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
kyChu 2019-11-27 13:45:41 +00:00 committed by Gregory Nutt
parent 93ed8b66d9
commit 01cda09aba
3 changed files with 170 additions and 18 deletions

View File

@ -2993,10 +2993,122 @@ endif # !STM32L4_PWM_MULTICHAN
endif # STM32L4_TIM17_PWM
config STM32L4_LPTIM1_PWM
bool "LPTIM1 PWM"
default n
depends on STM32L4_LPTIM1
select PWM
---help---
Reserve Low-power timer 1 for use by PWM
Timer devices may be used for different purposes. One special purpose is
to generate modulated outputs for such things as motor control. If STM32L4_LPTIM1
is defined then THIS following may also be defined to indicate that
the timer is intended to be used for pulsed output modulation.
if STM32L4_LPTIM1_PWM
if STM32L4_PWM_MULTICHAN
config STM32L4_LPTIM1_CHANNEL1
bool "LPTIM1 Channel 1"
default n
---help---
Enables channel 1.
if STM32L4_LPTIM1_CHANNEL1
config STM32L4_LPTIM1_CH1OUT
bool "LPTIM1 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config STM32L4_LPTIM1_CH1NOUT
bool "LPTIM1 Channel 1 Complementary Output"
default n
depends on STM32L4_LPTIM1_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_LPTIM1_CHANNEL1
endif # STM32L4_PWM_MULTICHAN
if !STM32L4_PWM_MULTICHAN
config STM32L4_LPTIM1_CHANNEL
int "LPTIM1 PWM Output Channel"
default 1
range 1 1
---help---
If LPTIM1 is enabled for PWM usage, you also need specifies the timer output
channel {1}
endif # !STM32L4_PWM_MULTICHAN
endif # STM32L4_LPTIM1_PWM
config STM32L4_LPTIM2_PWM
bool "LPTIM2 PWM"
default n
depends on STM32L4_LPTIM2
select PWM
---help---
Reserve Low-power timer 2 for use by PWM
Timer devices may be used for different purposes. One special purpose is
to generate modulated outputs for such things as motor control. If STM32L4_LPTIM2
is defined then THIS following may also be defined to indicate that
the timer is intended to be used for pulsed output modulation.
if STM32L4_LPTIM2_PWM
if STM32L4_PWM_MULTICHAN
config STM32L4_LPTIM2_CHANNEL1
bool "LPTIM2 Channel 1"
default n
---help---
Enables channel 1.
if STM32L4_LPTIM2_CHANNEL1
config STM32L4_LPTIM2_CH1OUT
bool "LPTIM2 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config STM32L4_LPTIM2_CH1NOUT
bool "LPTIM2 Channel 1 Complementary Output"
default n
depends on STM32L4_LPTIM2_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_LPTIM2_CHANNEL1
endif # STM32L4_PWM_MULTICHAN
if !STM32L4_PWM_MULTICHAN
config STM32L4_LPTIM2_CHANNEL
int "LPTIM2 PWM Output Channel"
default 1
range 1 1
---help---
If LPTIM2 is enabled for PWM usage, you also need specifies the timer output
channel {1}
endif # !STM32L4_PWM_MULTICHAN
endif # STM32L4_LPTIM2_PWM
config STM32L4_PWM_MULTICHAN
bool "PWM Multiple Output Channels"
default n
depends on STM32L4_TIM1_PWM || STM32L4_TIM2_PWM || STM32L4_TIM3_PWM || STM32L4_TIM4_PWM || STM32L4_TIM5_PWM || STM32L4_TIM8_PWM || STM32L4_TIM15_PWM || STM32L4_TIM16_PWM || STM32L4_TIM17_PWM
depends on STM32L4_TIM1_PWM || STM32L4_TIM2_PWM || STM32L4_TIM3_PWM || STM32L4_TIM4_PWM || STM32L4_TIM5_PWM || STM32L4_TIM8_PWM || STM32L4_TIM15_PWM || STM32L4_TIM16_PWM || STM32L4_TIM17_PWM || STM32L4_LPTIM1_PWM || STM32L4_LPTIM2_PWM
select ARCH_HAVE_PWM_MULTICHAN
---help---
Specifies that the PWM driver supports multiple output

View File

@ -1478,7 +1478,11 @@ static int stm32l4pwm_lptimer(FAR struct stm32l4_pwmtimer_s *priv,
DEBUGASSERT(priv != NULL && info != NULL);
pwminfo("LPTIM%u frequency: %u duty: %08x\n",
#ifdef CONFIG_PWM_MULTICHAN
priv->timid, info->frequency, info->channels[0].duty);
#else
priv->timid, info->frequency, info->duty);
#endif
DEBUGASSERT(info->frequency > 0);
DEBUGASSERT(info->duty >= 0 && info->duty < uitoub16(100));
@ -1546,7 +1550,11 @@ static int stm32l4pwm_lptimer(FAR struct stm32l4_pwmtimer_s *priv,
/* Compute reload value */
#ifdef CONFIG_PWM_MULTICHAN
ub16_t duty = info->channels[0].duty;
#else
ub16_t duty = info->duty;
#endif
/* Duty cycle:
*
@ -1879,7 +1887,7 @@ static void stm32l4pwm_setapbclock(FAR struct stm32l4_pwmtimer_s *priv, bool on)
#ifdef CONFIG_STM32L4_TIM3_PWM
case 3:
regaddr = STM32L4_RCC_APB1ENR1;
en_bit = RCC_APB1ENR_TIM3EN;
en_bit = RCC_APB1ENR1_TIM3EN;
break;
#endif
#ifdef CONFIG_STM32L4_TIM4_PWM
@ -1891,7 +1899,7 @@ static void stm32l4pwm_setapbclock(FAR struct stm32l4_pwmtimer_s *priv, bool on)
#ifdef CONFIG_STM32L4_TIM5_PWM
case 5:
regaddr = STM32L4_RCC_APB1ENR1;
en_bit = RCC_APB1ENR_TIM5EN;
en_bit = RCC_APB1ENR1_TIM5EN;
break;
#endif
#ifdef CONFIG_STM32L4_TIM8_PWM
@ -2256,7 +2264,7 @@ static int stm32l4pwm_start(FAR struct pwm_lowerhalf_s *dev,
static int stm32l4pwm_stop(FAR struct pwm_lowerhalf_s *dev)
{
FAR struct stm32l4_pwmtimer_s *priv = (FAR struct stm32l4_pwmtimer_s *)dev;
uint32_t resetbit;
uint32_t resetbit = 0;
uint32_t regaddr;
uint32_t regval;
irqstate_t flags;
@ -2306,7 +2314,7 @@ static int stm32l4pwm_stop(FAR struct pwm_lowerhalf_s *dev)
#ifdef CONFIG_STM32L4_TIM3_PWM
case 3:
regaddr = STM32L4_RCC_APB1RSTR1;
resetbit = RCC_APB1RSTR_TIM3RST;
resetbit = RCC_APB1RSTR1_TIM3RST;
break;
#endif
#ifdef CONFIG_STM32L4_TIM4_PWM
@ -2318,7 +2326,7 @@ static int stm32l4pwm_stop(FAR struct pwm_lowerhalf_s *dev)
#ifdef CONFIG_STM32L4_TIM5_PWM
case 5:
regaddr = STM32L4_RCC_APB1RSTR1;
resetbit = RCC_APB1RSTR_TIM5RST;
resetbit = RCC_APB1RSTR1_TIM5RST;
break;
#endif
#ifdef CONFIG_STM32L4_TIM8_PWM
@ -2349,7 +2357,7 @@ static int stm32l4pwm_stop(FAR struct pwm_lowerhalf_s *dev)
{
#ifdef CONFIG_STM32L4_LPTIM1_PWM
case 1:
regaddr = STM32L4_RCC_APB2RSTR;
regaddr = STM32L4_RCC_APB1RSTR1;
resetbit = RCC_APB1RSTR1_LPTIM1RST;
break;
#endif

View File

@ -92,6 +92,12 @@
#ifndef CONFIG_STM32L4_TIM17
# undef CONFIG_STM32L4_TIM17_PWM
#endif
#ifndef CONFIG_STM32L4_LPTIM1
# undef CONFIG_STM32L4_LPTIM1_PWM
#endif
#ifndef CONFIG_STM32L4_LPTIM2
# undef CONFIG_STM32L4_LPTIM2_PWM
#endif
/* The basic timers (timer 6 and 7) are not capable of generating output pulses */
@ -462,6 +468,40 @@
#endif
#define PWM_TIM17_NCHANNELS PWM_TIM17_CHANNEL1
#ifdef CONFIG_STM32L4_LPTIM1_CHANNEL1
# ifdef CONFIG_STM32L4_LPTIM1_CH1OUT
# define PWM_LPTIM1_CH1CFG GPIO_LPTIM1_CH1OUT
# else
# define PWM_LPTIM1_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_LPTIM1_CH1NOUT
# define PWM_LPTIM1_CH1NCFG GPIO_LPTIM1_CH1NOUT
# else
# define PWM_LPTIM1_CH1NCFG 0
# endif
# define PWM_LPTIM1_CHANNEL1 1
#else
# define PWM_LPTIM1_CHANNEL1 0
#endif
#define PWM_LPTIM1_NCHANNELS PWM_LPTIM1_CHANNEL1
#ifdef CONFIG_STM32L4_LPTIM2_CHANNEL1
# ifdef CONFIG_STM32L4_LPTIM2_CH1OUT
# define PWM_LPTIM2_CH1CFG GPIO_LPTIM2_CH1OUT
# else
# define PWM_LPTIM2_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_LPTIM2_CH1NOUT
# define PWM_LPTIM2_CH1NCFG GPIO_LPTIM2_CH1NOUT
# else
# define PWM_LPTIM2_CH1NCFG 0
# endif
# define PWM_LPTIM2_CHANNEL1 1
#else
# define PWM_LPTIM2_CHANNEL1 0
#endif
#define PWM_LPTIM2_NCHANNELS PWM_LPTIM2_CHANNEL1
#define PWM_MAX(a, b) ((a) > (b) ? (a) : (b))
#define PWM_NCHANNELS PWM_MAX(PWM_TIM1_NCHANNELS, \
@ -472,7 +512,9 @@
PWM_MAX(PWM_TIM8_NCHANNELS, \
PWM_MAX(PWM_TIM15_NCHANNELS, \
PWM_MAX(PWM_TIM16_NCHANNELS, \
PWM_TIM17_NCHANNELS))))))))
PWM_MAX(PWM_TIM17_NCHANNELS, \
PWM_MAX(PWM_LPTIM1_NCHANNELS, \
PWM_LPTIM2_NCHANNELS))))))))))
#else
@ -682,16 +724,11 @@
# endif
#endif
/* REVISIT: any other LPTIM implementations have more than one channel? */
#define CONFIG_STM32L4_LPTIM1_CHANNEL 1
#ifdef CONFIG_STM32L4_LPTIM1_PWM
# if !defined(CONFIG_STM32L4_LPTIM1_CHANNEL)
# error "CONFIG_STM32L4_LPTIM1_CHANNEL must be provided"
# elif CONFIG_STM32L4_LPTIM1_CHANNEL == 1
# define CONFIG_STM32L4_LPTIM1_CHANNEL1 1
# define CONFIG_STM32L4_LPTIM1_CH1MODE CONFIG_STM32L4_LPTIM1_CHMODE
# define PWM_LPTIM1_CH1CFG GPIO_LPTIM1_CH1OUT
# define PWM_LPTIM1_CH1NCFG 0
# else
@ -699,16 +736,11 @@
# endif
#endif
/* REVISIT: any other LPTIM implementations have more than one channel? */
#define CONFIG_STM32L4_LPTIM2_CHANNEL 1
#ifdef CONFIG_STM32L4_LPTIM2_PWM
# if !defined(CONFIG_STM32L4_LPTIM2_CHANNEL)
# error "CONFIG_STM32L4_LPTIM2_CHANNEL must be provided"
# elif CONFIG_STM32L4_LPTIM2_CHANNEL == 1
# define CONFIG_STM32L4_LPTIM2_CHANNEL1 1
# define CONFIG_STM32L4_LPTIM2_CH1MODE CONFIG_STM32L4_LPTIM2_CHMODE
# define PWM_LPTIM2_CH1CFG GPIO_LPTIM2_CH1OUT
# define PWM_LPTIM2_CH1NCFG 0
# else