diff --git a/arch/arm/src/stm32/stm32_freerun.c b/arch/arm/src/stm32/stm32_freerun.c index 673b0412d7..f631aa0aa5 100644 --- a/arch/arm/src/stm32/stm32_freerun.c +++ b/arch/arm/src/stm32/stm32_freerun.c @@ -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 */ diff --git a/arch/arm/src/stm32/stm32_freerun.h b/arch/arm/src/stm32/stm32_freerun.h index bc7609666c..b263367d16 100644 --- a/arch/arm/src/stm32/stm32_freerun.h +++ b/arch/arm/src/stm32/stm32_freerun.h @@ -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; diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c index 5590992827..d4a4ed2559 100644 --- a/arch/arm/src/stm32/stm32_tim.c +++ b/arch/arm/src/stm32/stm32_tim.c @@ -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 ************************************************************************************/ diff --git a/arch/arm/src/stm32/stm32_tim.h b/arch/arm/src/stm32/stm32_tim.h index 921baebc6c..5b9422f3ee 100644 --- a/arch/arm/src/stm32/stm32_tim.h +++ b/arch/arm/src/stm32/stm32_tim.h @@ -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,