STM32 TIM: Add method to get timer width. Freerun timer: Use timer width to get the correct clock rollover point.
This commit is contained in:
parent
c64983dbeb
commit
aa11d637a8
@ -137,6 +137,7 @@ int stm32_freerun_initialize(struct stm32_freerun_s *freerun, int chan,
|
||||
*/
|
||||
|
||||
freerun->chan = chan;
|
||||
freerun->width = STM32_TIM_GETWIDTH(freerun->tch);
|
||||
freerun->running = false;
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
@ -153,7 +154,7 @@ int stm32_freerun_initialize(struct stm32_freerun_s *freerun, int chan,
|
||||
|
||||
/* Set timer period */
|
||||
|
||||
STM32_TIM_SETPERIOD(freerun->tch, UINT32_MAX);
|
||||
STM32_TIM_SETPERIOD(freerun->tch, (uint32_t)((1ull << freerun->width) - 1));
|
||||
|
||||
/* Start the counter */
|
||||
|
||||
@ -248,7 +249,8 @@ int stm32_freerun_counter(struct stm32_freerun_s *freerun,
|
||||
* usecs = (ticks * USEC_PER_SEC) / frequency;
|
||||
*/
|
||||
|
||||
usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * USEC_PER_SEC) /
|
||||
usec = ((((uint64_t)overflow << freerun->width) +
|
||||
(uint64_t)counter) * USEC_PER_SEC) /
|
||||
freerun->frequency;
|
||||
|
||||
/* And return the value of the timer */
|
||||
|
@ -63,6 +63,7 @@
|
||||
struct stm32_freerun_s
|
||||
{
|
||||
uint8_t chan; /* The timer/counter in use */
|
||||
uint8_t width; /* Width of timer (16- or 32-bits) */
|
||||
bool running; /* True: the timer is running */
|
||||
FAR struct stm32_tim_dev_s *tch; /* Handle returned by stm32_tim_init() */
|
||||
uint32_t frequency;
|
||||
|
@ -334,22 +334,23 @@ static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode);
|
||||
|
||||
/* Timer methods */
|
||||
|
||||
static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
|
||||
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
|
||||
static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
|
||||
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
|
||||
static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev,
|
||||
uint32_t period);
|
||||
static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev);
|
||||
static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
stm32_tim_channel_t mode);
|
||||
static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
uint32_t compare);
|
||||
static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
|
||||
static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler,
|
||||
void *arg, int source);
|
||||
static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev);
|
||||
static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
stm32_tim_channel_t mode);
|
||||
static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
uint32_t compare);
|
||||
static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
|
||||
static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler,
|
||||
void *arg, int source);
|
||||
static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
@ -361,6 +362,7 @@ static const struct stm32_tim_ops_s stm32_tim_ops =
|
||||
.setclock = stm32_tim_setclock,
|
||||
.setperiod = stm32_tim_setperiod,
|
||||
.getcounter = stm32_tim_getcounter,
|
||||
.getwidth = stm32_tim_getwidth,
|
||||
.setchannel = stm32_tim_setchannel,
|
||||
.setcompare = stm32_tim_setcompare,
|
||||
.getcapture = stm32_tim_getcapture,
|
||||
@ -904,6 +906,41 @@ static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev)
|
||||
return stm32_getreg32(dev, STM32_BTIM_CNT_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_tim_getwidth
|
||||
************************************************************************************/
|
||||
|
||||
static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev)
|
||||
{
|
||||
/* Only TIM2 and TIM5 timers may be 32-bits in width
|
||||
*
|
||||
* Reference Table 2 of en.DM00042534.pdf
|
||||
*/
|
||||
|
||||
switch (((struct stm32_tim_priv_s *)dev)->base)
|
||||
{
|
||||
/* TIM2 is 32-bits on all except F10x, L0x, and L1x lines */
|
||||
|
||||
#if defined(CONFIG_STM32_TIM2) && !defined(STM32_STM32F10XX) && \
|
||||
!defined(STM32_STM32L15XX)
|
||||
case STM32_TIM2_BASE:
|
||||
return 32;
|
||||
#endif
|
||||
|
||||
/* TIM5 is 32-bits on all except F10x lines */
|
||||
|
||||
#if defined(CONFIG_STM32_TIM5) && !defined(STM32_STM32F10XX)
|
||||
case STM32_TIM5_BASE:
|
||||
return 32;
|
||||
#endif
|
||||
|
||||
/* All others are 16-bit times */
|
||||
|
||||
default:
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_tim_setchannel
|
||||
************************************************************************************/
|
||||
|
@ -61,6 +61,7 @@
|
||||
#define STM32_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq))
|
||||
#define STM32_TIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period))
|
||||
#define STM32_TIM_GETCOUNTER(d) ((d)->ops->getcounter(d))
|
||||
#define STM32_TIM_GETWIDTH(d) ((d)->ops->getwidth(d))
|
||||
#define STM32_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode))
|
||||
#define STM32_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp))
|
||||
#define STM32_TIM_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch))
|
||||
@ -166,6 +167,7 @@ struct stm32_tim_ops_s
|
||||
|
||||
/* General and Advanced Timers Adds */
|
||||
|
||||
int (*getwidth)(FAR struct stm32_tim_dev_s *dev);
|
||||
int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
stm32_tim_channel_t mode);
|
||||
int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
|
Loading…
Reference in New Issue
Block a user