diff --git a/arch/arm/src/stm32l4/hardware/stm32l4_lptim.h b/arch/arm/src/stm32l4/hardware/stm32l4_lptim.h index 773a05201f..240ce9e99c 100644 --- a/arch/arm/src/stm32l4/hardware/stm32l4_lptim.h +++ b/arch/arm/src/stm32l4/hardware/stm32l4_lptim.h @@ -79,8 +79,17 @@ /* Register Bitfield Definitions ********************************************************************/ #define LPTIM_CFGR_CKSEL (1 << 0) /* Bit 0: Clock selector */ -#define LPTIM_CFGR_CKPOL_SHIFT (1) /* Bits 2-1: Clock Polarity */ -#define LPTIM_CFGR_CKPOL_MASK (3 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKSEL_SHIFT (0) +#define LPTIM_CFGR_CKSEL_MASK (1) +# define LPTIM_CFGR_CKSEL_INTCLK (0) /* 0: Internal clock */ +# define LPTIM_CFGR_CKSEL_EXTCLK (1) /* 1: External clock */ + +#define LPTIM_CFGR_CKPOL_SHIFT (1) /* Bits 2-1: Clock Polarity */ +#define LPTIM_CFGR_CKPOL_MASK (3 << LPTIM_CFGR_CKPOL_SHIFT) +# define LPTIM_CFGR_CKPOL_RISING (0 << LPTIM_CFGR_CKPOL_SHIFT) /* 00: Rising Edge */ +# define LPTIM_CFGR_CKPOL_FALLING (1 << LPTIM_CFGR_CKPOL_SHIFT) /* 01: Falling Edge */ +# define LPTIM_CFGR_CKPOL_BOTH (2 << LPTIM_CFGR_CKPOL_SHIFT) /* 00: Both Edges */ + #define LPTIM_CFGR_CKFLT_SHIFT (3) /* Bits 4-3: Digital filter for external clock */ #define LPTIM_CFGR_CKFLTN_MASK (3 << LPTIM_CFGR_CKFLT_SHIFT) /* Bit 5: reserved */ diff --git a/arch/arm/src/stm32l4/stm32l4_lptim.c b/arch/arm/src/stm32l4/stm32l4_lptim.c index 6963ede473..f6097b953f 100644 --- a/arch/arm/src/stm32l4/stm32l4_lptim.c +++ b/arch/arm/src/stm32l4/stm32l4_lptim.c @@ -82,6 +82,7 @@ #include "stm32l4.h" #include "stm32l4_gpio.h" #include "stm32l4_lptim.h" +#include "stm32l4_rcc.h" #if defined(CONFIG_STM32L4_LPTIM1) || defined(CONFIG_STM32L4_LPTIM2) @@ -119,6 +120,16 @@ static int stm32l4_lptim_setclock(FAR struct stm32l4_lptim_dev_s *dev, uint32_t freq); static int stm32l4_lptim_setchannel(FAR struct stm32l4_lptim_dev_s *dev, stm32l4_lptim_channel_t channel, int enable); +static int stm32l4_lptim_setclocksource(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_clksrc_t clksrc); +static int stm32l4_lptim_setpolarity(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_clkpol_t polarity); +static uint32_t stm32l4_lptim_getcounter(FAR struct stm32l4_lptim_dev_s *dev); +static int stm32l4_lptim_setcountmode(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_cntmode_t cntmode); +static void stm32l4_lptim_setperiod(FAR struct stm32l4_lptim_dev_s *dev, + uint32_t period); +static uint32_t stm32l4_lptim_getperiod(FAR struct stm32l4_lptim_dev_s *dev); /************************************************************************************ * Private Data @@ -126,9 +137,15 @@ static int stm32l4_lptim_setchannel(FAR struct stm32l4_lptim_dev_s *dev, static const struct stm32l4_lptim_ops_s stm32l4_lptim_ops = { - .setmode = &stm32l4_lptim_setmode, - .setclock = &stm32l4_lptim_setclock, - .setchannel = &stm32l4_lptim_setchannel, + .setmode = &stm32l4_lptim_setmode, + .setclock = &stm32l4_lptim_setclock, + .setchannel = &stm32l4_lptim_setchannel, + .setclocksource = &stm32l4_lptim_setclocksource, + .setpolarity = &stm32l4_lptim_setpolarity, + .getcounter = &stm32l4_lptim_getcounter, + .setcountmode = &stm32l4_lptim_setcountmode, + .setperiod = &stm32l4_lptim_setperiod, + .getperiod = &stm32l4_lptim_getperiod }; #if defined(CONFIG_STM32L4_LPTIM1) @@ -486,6 +503,222 @@ static int stm32l4_lptim_setchannel(FAR struct stm32l4_lptim_dev_s *dev, return ret; } +/************************************************************************************ + * Name: stm32l4_lptim_setclocksource + ************************************************************************************/ + +static int stm32l4_lptim_setclocksource(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_clksrc_t clksrc) +{ + FAR struct stm32l4_lptim_priv_s *priv = (FAR struct stm32l4_lptim_priv_s *)dev; + + DEBUGASSERT(dev != NULL); + + if (clksrc == STM32L4_LPTIM_CLK_EXT) + { + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, LPTIM_CFGR_CKSEL_MASK, + LPTIM_CFGR_CKSEL_EXTCLK); + } + else + { + uint32_t ccr_mask = 0; + + switch(priv->base) + { +#ifdef CONFIG_STM32L4_LPTIM1 + case STM32L4_LPTIM1_BASE: + ccr_mask = RCC_CCIPR_LPTIM1SEL_MASK; + break; +#endif +#ifdef CONFIG_STM32L4_LPTIM2 + case STM32L4_LPTIM2_BASE: + ccr_mask = RCC_CCIPR_LPTIM2SEL_MASK; + break; +#endif + } + + uint32_t ccr_bits = 0; + + switch(clksrc) + { + case STM32L4_LPTIM_CLK_PCLK: + switch(priv->base) + { +#ifdef CONFIG_STM32L4_LPTIM1 + case STM32L4_LPTIM1_BASE: + ccr_bits = RCC_CCIPR_LPTIM1SEL_PCLK; + break; +#endif +#ifdef CONFIG_STM32L4_LPTIM2 + case STM32L4_LPTIM2_BASE: + ccr_bits = RCC_CCIPR_LPTIM2SEL_PCLK; + break; +#endif + } + break; + case STM32L4_LPTIM_CLK_HSI: + switch(priv->base) + { +#ifdef CONFIG_STM32L4_LPTIM1 + case STM32L4_LPTIM1_BASE: + ccr_bits = RCC_CCIPR_LPTIM1SEL_HSI; + break; +#endif +#ifdef CONFIG_STM32L4_LPTIM2 + case STM32L4_LPTIM2_BASE: + ccr_bits = RCC_CCIPR_LPTIM2SEL_HSI; + break; +#endif + } + break; + case STM32L4_LPTIM_CLK_LSI: + switch(priv->base) + { +#ifdef CONFIG_STM32L4_LPTIM1 + case STM32L4_LPTIM1_BASE: + ccr_bits = RCC_CCIPR_LPTIM1SEL_LSI; + break; +#endif +#ifdef CONFIG_STM32L4_LPTIM2 + case STM32L4_LPTIM2_BASE: + ccr_bits = RCC_CCIPR_LPTIM2SEL_LSI; + break; +#endif + } + break; + case STM32L4_LPTIM_CLK_LSE: + switch(priv->base) + { +#ifdef CONFIG_STM32L4_LPTIM1 + case STM32L4_LPTIM1_BASE: + ccr_bits = RCC_CCIPR_LPTIM1SEL_LSE; + break; +#endif +#ifdef CONFIG_STM32L4_LPTIM2 + case STM32L4_LPTIM2_BASE: + ccr_bits = RCC_CCIPR_LPTIM2SEL_LSE; + break; +#endif + } + break; + default: + break; + } + + modifyreg32(STM32L4_RCC_CCIPR, ccr_mask, ccr_bits); + + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, LPTIM_CFGR_CKSEL_MASK, + LPTIM_CFGR_CKSEL_INTCLK); + } + + return OK; +} + +/************************************************************************************ + * Name: stm32l4_lptim_setperiod + ************************************************************************************/ + +static void stm32l4_lptim_setperiod(FAR struct stm32l4_lptim_dev_s *dev, + uint32_t period) +{ + FAR struct stm32l4_lptim_priv_s *priv = (FAR struct stm32l4_lptim_priv_s *)dev; + + DEBUGASSERT(dev != NULL); + putreg32(period, (uintptr_t)(priv->base + STM32L4_LPTIM_ARR_OFFSET)); +} + +/************************************************************************************ + * Name: stm32l4_tim_getperiod + ************************************************************************************/ + +static uint32_t stm32l4_lptim_getperiod(FAR struct stm32l4_lptim_dev_s *dev) +{ + FAR struct stm32l4_lptim_priv_s *priv = (FAR struct stm32l4_lptim_priv_s *)dev; + + DEBUGASSERT(dev != NULL); + return getreg32((uintptr_t)(priv->base + STM32L4_LPTIM_ARR_OFFSET)); +} + +/************************************************************************************ + * Name: stm32l4_lptim_setcountmode + ************************************************************************************/ + +static int stm32l4_lptim_setcountmode(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_cntmode_t cntmode) +{ + DEBUGASSERT(dev != NULL); + + + if (cntmode == STM32L4_LPTIM_COUNT_CLOCK) + { + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, + LPTIM_CFGR_COUNTMODE, 0); + } + else if (cntmode == STM32L4_LPTIM_COUNT_EXTTRIG) + { + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, + 0, LPTIM_CFGR_COUNTMODE); + } + else + { + return ERROR; + } + + return OK; +} + +/************************************************************************************ + * Name: stm32l4_lptim_setpolarity + ************************************************************************************/ + +static int stm32l4_lptim_setpolarity(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_clkpol_t polarity) +{ + DEBUGASSERT(dev != NULL); + + switch(polarity) + { + case STM32L4_LPTIM_CLKPOL_RISING: + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, LPTIM_CFGR_CKPOL_MASK, + LPTIM_CFGR_CKPOL_RISING); + break; + + case STM32L4_LPTIM_CLKPOL_FALLING: + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, LPTIM_CFGR_CKPOL_MASK, + LPTIM_CFGR_CKPOL_FALLING); + break; + + case STM32L4_LPTIM_CLKPOL_BOTH: + stm32l4_modifyreg32(dev, STM32L4_LPTIM_CFGR_OFFSET, LPTIM_CFGR_CKPOL_MASK, + LPTIM_CFGR_CKPOL_BOTH); + break; + } + + return OK; +} + +/************************************************************************************ + * Name: stm32l4_lptim_setpolarity + ************************************************************************************/ + +static uint32_t stm32l4_lptim_getcounter(FAR struct stm32l4_lptim_dev_s *dev) +{ + FAR struct stm32l4_lptim_priv_s *priv = (FAR struct stm32l4_lptim_priv_s *)dev; + + DEBUGASSERT(dev != NULL); + + uint32_t counter1, counter2; + + do + { + counter1 = getreg32((uintptr_t)(priv->base + STM32L4_LPTIM_CNT_OFFSET)); + counter2 = getreg32((uintptr_t)(priv->base + STM32L4_LPTIM_CNT_OFFSET)); + } while (counter1 != counter2); + + + return counter1; +} + /************************************************************************************ * Public Functions ************************************************************************************/ diff --git a/arch/arm/src/stm32l4/stm32l4_lptim.h b/arch/arm/src/stm32l4/stm32l4_lptim.h index 150b20fcc3..31a398c821 100644 --- a/arch/arm/src/stm32l4/stm32l4_lptim.h +++ b/arch/arm/src/stm32l4/stm32l4_lptim.h @@ -88,6 +88,11 @@ #define STM32L4_LPTIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode)) #define STM32L4_LPTIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq)) #define STM32L4_LPTIM_SETCHANNEL(d,ch,en) ((d)->ops->setchannel(d,ch,en)) +#define STM32L4_LPTIM_SETCLOCKSOURCE(d,s) ((d)->ops->setclocksource(d,s)) +#define STM32L4_LPTIM_GETCOUNTER(d) ((d)->ops->getcounter(d)) +#define STM32L4_LPTIM_SETCOUNTMODE(d,m) ((d)->ops->setcountmode(d,m)) +#define STM32L4_LPTIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period)) +#define STM32L4_LPTIM_GETPERIOD(d) ((d)->ops->getperiod(d)) /************************************************************************************ * Public Types @@ -122,9 +127,44 @@ typedef enum STM32L4_LPTIM_MODE_DISABLED = 0x0000, STM32L4_LPTIM_MODE_SINGLE = 0x0001, STM32L4_LPTIM_MODE_CONTINUOUS = 0x0002, - STM32L4_LPTIM_MODE_MASK = 0x003f, + STM32L4_LPTIM_MODE_MASK = 0x000f, } stm32l4_lptim_mode_t; + +/* LPTIM Clock Source */ + +typedef enum +{ + /* Clock Sources */ + + STM32L4_LPTIM_CLK_PCLK = 0x0000, + STM32L4_LPTIM_CLK_LSI = 0x0001, + STM32L4_LPTIM_CLK_HSI = 0x0002, + STM32L4_LPTIM_CLK_LSE = 0x0003, + STM32L4_LPTIM_CLK_EXT = 0x0004, +} stm32l4_lptim_clksrc_t; + +/* LPTIM Counter Modes */ + +typedef enum +{ + /* Modes */ + + STM32L4_LPTIM_COUNT_CLOCK = 0x0000, + STM32L4_LPTIM_COUNT_EXTTRIG = 0x0001, +} stm32l4_lptim_cntmode_t; + +/* LPTIM Clock Polarity */ + +typedef enum +{ + /* MODES */ + + STM32L4_LPTIM_CLKPOL_RISING = 0x0000, + STM32L4_LPTIM_CLKPOL_FALLING = 0x0001, + STM32L4_LPTIM_CLKPOL_BOTH = 0x0002, +} stm32l4_lptim_clkpol_t; + /* LPTIM Channel Modes */ typedef enum @@ -148,6 +188,15 @@ struct stm32l4_lptim_ops_s int (*setclock)(FAR struct stm32l4_lptim_dev_s *dev, uint32_t freq); int (*setchannel)(FAR struct stm32l4_lptim_dev_s *dev, stm32l4_lptim_channel_t channel, int enable); + int (*setclocksource)(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_clksrc_t clksrc); + int (*setpolarity)(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_clkpol_t polarity); + uint32_t (*getcounter)(FAR struct stm32l4_lptim_dev_s *dev); + int (*setcountmode)(FAR struct stm32l4_lptim_dev_s *dev, + stm32l4_lptim_cntmode_t cntmode); + void (*setperiod)(FAR struct stm32l4_lptim_dev_s *dev, uint32_t period); + uint32_t (*getperiod)(FAR struct stm32l4_lptim_dev_s *dev); }; /************************************************************************************