mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 06:42:32 +08:00
arch/arm/src/stm32l4 and boards/arm/stm32l4/nucleo-l476rg: Add support for LPTIM timers on the STM32L4 as PWM outputs.
This commit is contained in:
@@ -1810,6 +1810,74 @@ config STM32L4_ONESHOT_MAXTIMERS
|
|||||||
of the timers and places an upper limit on the number of oneshot
|
of the timers and places an upper limit on the number of oneshot
|
||||||
timers that you can use.
|
timers that you can use.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "LPTIM1 clock source"
|
||||||
|
default STM32L4_LPTIM1_CLK_APB1
|
||||||
|
|
||||||
|
config STM32L4_LPTIM1_CLK_APB1
|
||||||
|
bool "Clock LPTIM1 from APB1"
|
||||||
|
|
||||||
|
config STM32L4_LPTIM1_CLK_LSE
|
||||||
|
bool "Clock LPTIM1 from LSE"
|
||||||
|
|
||||||
|
config STM32L4_LPTIM1_CLK_LSI
|
||||||
|
bool "Clock LPTIM1 from LSI"
|
||||||
|
|
||||||
|
config STM32L4_LPTIM1_CLK_HSI
|
||||||
|
bool "Clock LPTIM1 from HSI"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "LPTIM2 clock source"
|
||||||
|
default STM32L4_LPTIM2_CLK_APB1
|
||||||
|
|
||||||
|
config STM32L4_LPTIM2_CLK_APB1
|
||||||
|
bool "Clock LPTIM2 from APB1"
|
||||||
|
|
||||||
|
config STM32L4_LPTIM2_CLK_LSE
|
||||||
|
bool "Clock LPTIM2 from LSE"
|
||||||
|
|
||||||
|
config STM32L4_LPTIM2_CLK_LSI
|
||||||
|
bool "Clock LPTIM2 from LSI"
|
||||||
|
|
||||||
|
config STM32L4_LPTIM2_CLK_HSI
|
||||||
|
bool "Clock LPTIM2 from HSI"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endif # STM32L4_LPTIM2_PWM
|
||||||
|
|
||||||
config STM32L4_TIM1_PWM
|
config STM32L4_TIM1_PWM
|
||||||
bool "TIM1 PWM"
|
bool "TIM1 PWM"
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -114,4 +114,12 @@
|
|||||||
#define LPTIM_CR_SNGSTRT (1 << 1) /* Bit 1: Single Mode */
|
#define LPTIM_CR_SNGSTRT (1 << 1) /* Bit 1: Single Mode */
|
||||||
#define LPTIM_CR_CNTSTRT (1 << 2) /* Bit 2: Continuous Mode */
|
#define LPTIM_CR_CNTSTRT (1 << 2) /* Bit 2: Continuous Mode */
|
||||||
|
|
||||||
|
#define LPTIM_ISR_CMPM (1 << 0) /* Bit 0: Compare match */
|
||||||
|
#define LPTIM_ISR_ARRM (1 << 1) /* Bit 1: Autoreload match */
|
||||||
|
#define LPTIM_ISR_EXTTRIG (1 << 2) /* Bit 2: External trigger edge event */
|
||||||
|
#define LPTIM_ISR_CMPOK (1 << 3) /* Bit 3: Compare register update OK */
|
||||||
|
#define LPTIM_ISR_ARROK (1 << 4) /* Bit 4: Autoreload register update OK */
|
||||||
|
#define LPTIM_ISR_UP (1 << 5) /* Bit 5: Counter direction change down to up */
|
||||||
|
#define LPTIM_ISR_DOWN (1 << 6) /* Bit 6: Counter direction change up to down */
|
||||||
|
|
||||||
#endif /* __ARCH_ARM_SRC_STM32L4_HARDWARE_STM32L4_LPTIM_H */
|
#endif /* __ARCH_ARM_SRC_STM32L4_HARDWARE_STM32L4_LPTIM_H */
|
||||||
|
|||||||
@@ -116,18 +116,6 @@
|
|||||||
#define STM32L4_ATIM_OR2_OFFSET 0x0050 /* Timer option register 2 */
|
#define STM32L4_ATIM_OR2_OFFSET 0x0050 /* Timer option register 2 */
|
||||||
#define STM32L4_ATIM_OR3_OFFSET 0x0050 /* Timer option register 3 */
|
#define STM32L4_ATIM_OR3_OFFSET 0x0050 /* Timer option register 3 */
|
||||||
|
|
||||||
/* Low-Power Timers - LPTIM1 and LPTIM2 */
|
|
||||||
|
|
||||||
#define STM32L4_LPTIM_ISR_OFFSET 0x0000 /* Interrupt and Status register */
|
|
||||||
#define STM32L4_LPTIM_ICR_OFFSET 0x0004 /* Interrupt clear register */
|
|
||||||
#define STM32L4_LPTIM_IER_OFFSET 0x0008 /* Interrupt enable register */
|
|
||||||
#define STM32L4_LPTIM_CFGR_OFFSET 0x000c /* Configuration register */
|
|
||||||
#define STM32L4_LPTIM_CR_OFFSET 0x0010 /* Control register */
|
|
||||||
#define STM32L4_LPTIM_CMP_OFFSET 0x0014 /* Compare register */
|
|
||||||
#define STM32L4_LPTIM_ARR_OFFSET 0x0018 /* Auto-reloud register (16-bit) */
|
|
||||||
#define STM32L4_LPTIM_CNT_OFFSET 0x001c /* Counter (16-bit) */
|
|
||||||
#define STM32L4_LPTIM_OR_OFFSET 0x001c /* Options Register */
|
|
||||||
|
|
||||||
/* Register Addresses ***************************************************************/
|
/* Register Addresses ***************************************************************/
|
||||||
|
|
||||||
/* Advanced Timers - TIM1 and TIM8 */
|
/* Advanced Timers - TIM1 and TIM8 */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -55,11 +55,14 @@
|
|||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
/* Configuration ********************************************************************/
|
/* Configuration ********************************************************************/
|
||||||
|
|
||||||
/* Timer devices may be used for different purposes. One special purpose is
|
/* Timer devices may be used for different purposes. One special purpose is
|
||||||
* to generate modulated outputs for such things as motor control. If CONFIG_STM32L4_TIMn
|
* to generate modulated outputs for such things as motor control. If
|
||||||
* is defined then the CONFIG_STM32L4_TIMn_PWM must also be defined to indicate that
|
* CONFIG_STM32L4_TIMn is defined then the CONFIG_STM32L4_TIMn_PWM must also be
|
||||||
* timer "n" is intended to be used for pulsed output signal generation.
|
* defined to indicate that timer "n" is intended to be used for pulsed output
|
||||||
|
* signal generation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_STM32L4_TIM1
|
#ifndef CONFIG_STM32L4_TIM1
|
||||||
@@ -101,10 +104,12 @@
|
|||||||
defined(CONFIG_STM32L4_TIM3_PWM) || defined(CONFIG_STM32L4_TIM4_PWM) || \
|
defined(CONFIG_STM32L4_TIM3_PWM) || defined(CONFIG_STM32L4_TIM4_PWM) || \
|
||||||
defined(CONFIG_STM32L4_TIM5_PWM) || defined(CONFIG_STM32L4_TIM8_PWM) || \
|
defined(CONFIG_STM32L4_TIM5_PWM) || defined(CONFIG_STM32L4_TIM8_PWM) || \
|
||||||
defined(CONFIG_STM32L4_TIM15_PWM) || defined(CONFIG_STM32L4_TIM16_PWM) || \
|
defined(CONFIG_STM32L4_TIM15_PWM) || defined(CONFIG_STM32L4_TIM16_PWM) || \
|
||||||
defined(CONFIG_STM32L4_TIM17_PWM)
|
defined(CONFIG_STM32L4_TIM17_PWM) || defined(CONFIG_STM32L4_LPTIM1_PWM) || \
|
||||||
|
defined(CONFIG_STM32L4_LPTIM2_PWM)
|
||||||
|
|
||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
#include "hardware/stm32l4_tim.h"
|
#include "hardware/stm32l4_tim.h"
|
||||||
|
#include "hardware/stm32l4_lptim.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PWM_MULTICHAN
|
#ifdef CONFIG_PWM_MULTICHAN
|
||||||
|
|
||||||
@@ -677,6 +682,40 @@
|
|||||||
# endif
|
# endif
|
||||||
#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
|
||||||
|
# error "Unsupported value of CONFIG_STM32L4_LPTIM1_CHANNEL"
|
||||||
|
# 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
|
||||||
|
# error "Unsupported value of CONFIG_STM32L4_LPTIM2_CHANNEL"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PWM_NCHANNELS 1
|
#define PWM_NCHANNELS 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -723,6 +762,25 @@ extern "C"
|
|||||||
|
|
||||||
FAR struct pwm_lowerhalf_s *stm32l4_pwminitialize(int timer);
|
FAR struct pwm_lowerhalf_s *stm32l4_pwminitialize(int timer);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: stm32l4_lp_pwminitialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize one low-power timer for use with the upper_level PWM driver.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* timer - A number identifying the timer use. The number of valid timer
|
||||||
|
* IDs varies with the STM32 MCU and MCU family but is somewhere in
|
||||||
|
* the range of {1,..,2}.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, a pointer to the STM32 lower half PWM driver is returned.
|
||||||
|
* NULL is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct pwm_lowerhalf_s *stm32l4_lp_pwminitialize(int timer);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,6 +261,9 @@
|
|||||||
#define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_1
|
#define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_1
|
||||||
#define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_1
|
#define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_1
|
||||||
|
|
||||||
|
#define GPIO_LPTIM1_CH1OUT GPIO_LPTIM1_OUT_1
|
||||||
|
#define GPIO_LPTIM2_CH1OUT GPIO_LPTIM2_OUT_2
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
@@ -202,8 +202,9 @@
|
|||||||
* DFSDM
|
* DFSDM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* prescaler common to all PLL inputs; will be 1 (XXX source is implicitly
|
/* Prescaler common to all PLL inputs; will be 1 (XXX source is implicitly
|
||||||
as per comment above HSI) */
|
* as per comment above HSI) .
|
||||||
|
*/
|
||||||
|
|
||||||
#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
|
#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
|
||||||
|
|
||||||
@@ -274,6 +275,7 @@
|
|||||||
#define STM32L4_PCLK1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 1)
|
#define STM32L4_PCLK1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 1)
|
||||||
|
|
||||||
/* Timers driven from APB1 will be twice PCLK1 */
|
/* Timers driven from APB1 will be twice PCLK1 */
|
||||||
|
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
#define STM32L4_APB1_TIM2_CLKIN (2 * STM32L4_PCLK1_FREQUENCY)
|
#define STM32L4_APB1_TIM2_CLKIN (2 * STM32L4_PCLK1_FREQUENCY)
|
||||||
@@ -289,6 +291,7 @@
|
|||||||
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 1)
|
#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 1)
|
||||||
|
|
||||||
/* Timers driven from APB2 will be twice PCLK2 */
|
/* Timers driven from APB2 will be twice PCLK2 */
|
||||||
|
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
|
||||||
@@ -301,6 +304,7 @@
|
|||||||
* otherwise frequency is 2xAPBx.
|
* otherwise frequency is 2xAPBx.
|
||||||
* Note: TIM1,8,15,16,17 are on APB2, others on APB1
|
* Note: TIM1,8,15,16,17 are on APB2, others on APB1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* REVISIT : this can be configured */
|
/* REVISIT : this can be configured */
|
||||||
|
|
||||||
/* TODO SDMMC */
|
/* TODO SDMMC */
|
||||||
@@ -488,8 +492,8 @@
|
|||||||
#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
|
#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
|
||||||
#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define STM32L4_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
#define STM32L4_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@@ -262,6 +263,43 @@ int stm32l4_pwm_setup(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_STM32L4_LPTIM1_PWM)
|
||||||
|
pwm = stm32l4_lp_pwminitialize(1);
|
||||||
|
if (!pwm)
|
||||||
|
{
|
||||||
|
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register the PWM driver at "/dev/lppwm1" */
|
||||||
|
|
||||||
|
ret = pwm_register("/dev/lppwm1", pwm);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
aerr("ERROR: pwm_register failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_STM32L4_LPTIM2_PWM)
|
||||||
|
pwm = stm32l4_lp_pwminitialize(2);
|
||||||
|
if (!pwm)
|
||||||
|
{
|
||||||
|
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register the PWM driver at "/dev/lppwm2" */
|
||||||
|
|
||||||
|
ret = pwm_register("/dev/lppwm2", pwm);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
aerr("ERROR: pwm_register failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now we are initialized */
|
/* Now we are initialized */
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user