1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 10:03:50 +01:00

sys/ztimer: make use of periph_timer_query_freqs

This makes use of the `periph_timer_query_freqs` feature:

1. It does choose the closest frequency supported before calling
   timer_init() in the ztimer_periph_timer backend.
2. It does make use of the actually chosen frequency when using
   `ztimer_convert_frac`.
3. It does `assert()` the frequency is within 5% of the specified when
   no frequency conversion is performed or `ztimer_convert_shift_up`
   is used.
This commit is contained in:
Marian Buschsieweke 2024-04-15 20:27:37 +02:00 committed by Marian Buschsieweke
parent e00923915e
commit 25b8d65f68
No known key found for this signature in database
GPG Key ID: 758BD52517F79C41
4 changed files with 39 additions and 12 deletions

View File

@ -52,8 +52,10 @@ typedef struct {
* @param[in] dev periph timer to use
* @param[in] freq frequency to configure
* @param[in] max_val maximum value this timer supports
*
* @return The actual frequency the timer has been configured to
*/
void ztimer_periph_timer_init(ztimer_periph_timer_t *clock, tim_t dev,
uint32_t ztimer_periph_timer_init(ztimer_periph_timer_t *clock, tim_t dev,
uint32_t freq, uint32_t max_val);
#ifdef __cplusplus

View File

@ -39,6 +39,7 @@ endif
ifneq (,$(filter ztimer_periph_timer,$(USEMODULE)))
FEATURES_REQUIRED += periph_timer
FEATURES_OPTIONAL += periph_timer_query_freqs
endif
ifneq (,$(filter ztimer_periph_rtc,$(USEMODULE)))

View File

@ -39,7 +39,9 @@
#include "kernel_defines.h"
#include "assert.h"
#include "board.h"
#include "compiler_hints.h"
#include "ztimer.h"
#include "ztimer/convert_frac.h"
#include "ztimer/convert_shift.h"
@ -72,6 +74,9 @@
# define ZTIMER_TIMER _ztimer_periph_timer
# define ZTIMER_TIMER_CLK _ztimer_periph_timer.super
# define ZTIMER_TIMER_FREQ CONFIG_ZTIMER_USEC_BASE_FREQ
# ifndef CONFIG_ZTIMER_PERIPH_TIMER_FORCE_CONVERSION
# define CONFIG_ZTIMER_PERIPH_TIMER_FORCE_CONVERSION 0
# endif
#endif
#if MODULE_ZTIMER_PERIPH_LPTIMER
@ -209,9 +214,9 @@ ztimer_clock_t *const ZTIMER_USEC_BASE = &ZTIMER_TIMER_CLK;
# else
# error No suitable ZTIMER_USEC config. Basic timer configuration missing?
# endif
# if ZTIMER_TIMER_FREQ == FREQ_1MHZ
# if (ZTIMER_TIMER_FREQ == FREQ_1MHZ) && !(CONFIG_ZTIMER_PERIPH_TIMER_FORCE_CONVERSION)
ztimer_clock_t *const ZTIMER_USEC = &ZTIMER_TIMER_CLK;
# elif ZTIMER_TIMER_FREQ == 250000LU
# elif (ZTIMER_TIMER_FREQ == 250000LU) && !(CONFIG_ZTIMER_PERIPH_TIMER_FORCE_CONVERSION)
static ztimer_convert_shift_t _ztimer_convert_shift_usec;
ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_shift_usec.super.super;
# else
@ -290,8 +295,11 @@ void ztimer_init(void)
"ztimer_init(): ZTIMER_TIMER using periph timer %u, freq %lu, width %u\n",
CONFIG_ZTIMER_USEC_DEV, ZTIMER_TIMER_FREQ,
CONFIG_ZTIMER_USEC_WIDTH);
MAYBE_UNUSED
uint32_t periph_timer_freq =
ztimer_periph_timer_init(&ZTIMER_TIMER, CONFIG_ZTIMER_USEC_DEV,
ZTIMER_TIMER_FREQ, WIDTH_TO_MAXVAL(CONFIG_ZTIMER_USEC_WIDTH));
ZTIMER_TIMER_FREQ,
WIDTH_TO_MAXVAL(CONFIG_ZTIMER_USEC_WIDTH));
# if MODULE_PM_LAYERED && !MODULE_ZTIMER_ONDEMAND
LOG_DEBUG("ztimer_init(): ZTIMER_TIMER setting block_pm_mode to %i\n",
CONFIG_ZTIMER_TIMER_BLOCK_PM_MODE);
@ -335,19 +343,27 @@ void ztimer_init(void)
/* Step 5: initialize ztimers requested */
#if MODULE_ZTIMER_USEC
# if ZTIMER_TIMER_FREQ != FREQ_1MHZ
# if ZTIMER_TIMER_FREQ == FREQ_250KHZ
# if (ZTIMER_TIMER_FREQ != FREQ_1MHZ) || CONFIG_ZTIMER_PERIPH_TIMER_FORCE_CONVERSION
# if (ZTIMER_TIMER_FREQ == FREQ_250KHZ) && !(CONFIG_ZTIMER_PERIPH_TIMER_FORCE_CONVERSION)
if (IS_ACTIVE(DEVELHELP) && ((periph_timer_freq < 237500) || (periph_timer_freq > 262500))) {
LOG_WARNING("ZTIMER_USEC from %" PRIu32 " Hz clock with \"left-shift by 2\" frequency conversion\n",
periph_timer_freq);
}
LOG_DEBUG("ztimer_init(): ZTIMER_USEC convert_shift %lu to 1000000\n",
ZTIMER_TIMER_FREQ);
periph_timer_freq);
ztimer_convert_shift_up_init(&_ztimer_convert_shift_usec,
ZTIMER_USEC_BASE, 2);
# else
LOG_DEBUG("ztimer_init(): ZTIMER_USEC convert_frac %lu to 1000000\n",
ZTIMER_TIMER_FREQ);
ztimer_convert_frac_init(&_ztimer_convert_frac_usec, ZTIMER_USEC_BASE,
FREQ_1MHZ, ZTIMER_TIMER_FREQ);
FREQ_1MHZ, periph_timer_freq);
# endif
# else
if (IS_ACTIVE(DEVELHELP) && ((periph_timer_freq < 950000) || (periph_timer_freq > 1050000))) {
LOG_WARNING("ZTIMER_USEC from %" PRIu32 " Hz clock without frequency conversion\n",
periph_timer_freq);
}
LOG_DEBUG("ztimer_init(): ZTIMER_USEC without conversion\n");
# endif

View File

@ -21,7 +21,9 @@
*/
#include "assert.h"
#include "compiler_hints.h"
#include "irq.h"
#include "modules.h"
#include "ztimer/periph_timer.h"
#ifndef ZTIMER_PERIPH_TIMER_OFFSET
@ -104,12 +106,16 @@ static const ztimer_ops_t _ztimer_periph_timer_ops = {
#endif
};
void ztimer_periph_timer_init(ztimer_periph_timer_t *clock, tim_t dev,
uint32_t ztimer_periph_timer_init(ztimer_periph_timer_t *clock, tim_t dev,
uint32_t freq, uint32_t max_val)
{
clock->dev = dev;
clock->super.ops = &_ztimer_periph_timer_ops;
clock->super.max_value = max_val;
if (IS_USED(MODULE_PERIPH_TIMER_QUERY_FREQS)) {
freq = timer_get_closest_freq(dev, freq);
}
int ret = timer_init(dev, freq, _ztimer_periph_timer_callback, clock);
(void)ret;
@ -127,4 +133,6 @@ void ztimer_periph_timer_init(ztimer_periph_timer_t *clock, tim_t dev,
* the first ztimer_acquire() call starts the peripheral */
timer_stop(dev);
#endif
return freq;
}