stm32l4_lptim: add various functions

This commit is contained in:
Matias Nitsche 2020-04-24 12:31:55 -03:00 committed by Alan Carvalho de Assis
parent 9a17ed4dd9
commit 38bd0364bf
3 changed files with 297 additions and 6 deletions

View File

@ -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 */

View File

@ -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
************************************************************************************/

View File

@ -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);
};
/************************************************************************************