diff --git a/sys/include/ztimer/config.h b/sys/include/ztimer/config.h index 87770b1067..2240d7e2ee 100644 --- a/sys/include/ztimer/config.h +++ b/sys/include/ztimer/config.h @@ -104,17 +104,36 @@ extern "C" { #endif /* MODULE_ZTIMER_PERIPH_RTT */ /** - * @brief The minimum pm mode required for ZTIMER_USEC to run. + * @brief The minimum pm mode required for ZTIMER_TIMER to run. */ -#ifndef CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE -#define CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE +#ifndef CONFIG_ZTIMER_TIMER_BLOCK_PM_MODE +# ifdef CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE +# define CONFIG_ZTIMER_TIMER_BLOCK_PM_MODE CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE +# else +# define CONFIG_ZTIMER_TIMER_BLOCK_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE +# endif #endif /** - * @brief The minimum pm mode required for ZTIMER_MSEC to run + * @brief The minimum pm mode required for ZTIMER_RTT to run */ -#ifndef CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE -#define CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE +#ifndef CONFIG_ZTIMER_RTT_BLOCK_PM_MODE +# ifdef CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE +# define CONFIG_ZTIMER_RTT_BLOCK_PM_MODE CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE +# else +# define CONFIG_ZTIMER_RTT_BLOCK_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE +# endif +#endif + +/** + * @brief The minimum pm mode required for ZTIMER_RTC to run + */ +#ifndef CONFIG_ZTIMER_RTC_BLOCK_PM_MODE +# ifdef CONFIG_ZTIMER_SEC_REQUIRED_PM_MODE +# define CONFIG_ZTIMER_RTC_BLOCK_PM_MODE CONFIG_ZTIMER_SEC_REQUIRED_PM_MODE +# else +# define CONFIG_ZTIMER_RTC_BLOCK_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE +# endif #endif #ifdef __cplusplus diff --git a/sys/ztimer/auto_init.c b/sys/ztimer/auto_init.c index 8a36ec4fd7..ed1b8d8b28 100644 --- a/sys/ztimer/auto_init.c +++ b/sys/ztimer/auto_init.c @@ -36,6 +36,9 @@ * @} */ +#include "kernel_defines.h" +#if IS_USED(MODULE_AUTO_INIT_ZTIMER) + #include "board.h" #include "ztimer.h" #include "ztimer/convert_frac.h" @@ -55,103 +58,214 @@ #define FREQ_1KHZ 1000LU #define FREQ_1HZ 1LU -#if MODULE_ZTIMER_USEC -# if CONFIG_ZTIMER_USEC_TYPE_PERIPH_TIMER -static ztimer_periph_timer_t _ztimer_periph_timer_usec = { - .min = CONFIG_ZTIMER_USEC_MIN -}; +/* Step 0: define available ztimer-periphery by activated modules */ -ztimer_clock_t *const ZTIMER_USEC_BASE = &_ztimer_periph_timer_usec.super; -# if CONFIG_ZTIMER_USEC_BASE_FREQ == FREQ_1MHZ -ztimer_clock_t *const ZTIMER_USEC = &_ztimer_periph_timer_usec.super; -# elif CONFIG_ZTIMER_USEC_BASE_FREQ == 250000LU -static ztimer_convert_shift_t _ztimer_convert_shift_usec; -ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_shift_usec.super.super; -# else -static ztimer_convert_frac_t _ztimer_convert_frac_usec; -ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_frac_usec.super.super; -# endif -# else -# error ztimer_usec selected, but no configuration available! +/* #if CONFIG_ZTIMER_USEC_TYPE_PERIPH_TIMER + * replaces #if MODULE_ZTIMER_PERIPH_TIMER + * the ztimer_periph_timer is always available + * having an (1) config defined in ztimer/config.h + */ + +#if CONFIG_ZTIMER_USEC_TYPE_PERIPH_TIMER +# define ZTIMER_TIMER _ztimer_periph_timer +# define ZTIMER_TIMER_CLK _ztimer_periph_timer.super +# define ZTIMER_TIMER_FREQ CONFIG_ZTIMER_USEC_BASE_FREQ +#endif + +#if MODULE_ZTIMER_PERIPH_RTT +# define ZTIMER_RTT _ztimer_periph_timer_rtt +# define ZTIMER_RTT_CLK _ztimer_periph_timer_rtt +# define ZTIMER_RTT_FREQ RTT_FREQUENCY +#endif + +#if MODULE_ZTIMER_PERIPH_RTC +# define ZTIMER_RTC _ztimer_periph_timer_rtc +# define ZTIMER_RTC_CLK _ztimer_periph_timer_rtc +# define ZTIMER_RTC_FREQ FREQ_1HZ +#endif + +/* Step 1: select which periphery to use for the higher level ZTIMER_*SEC + * selected periphery is marked for initialisation (INIT_ZTIMER_ + * prepare defines for ztimer initialization + */ + +/* ZTIMER_USEC always uses the basic timer + * basic timer is available on all boards */ +#if MODULE_ZTIMER_USEC +# ifndef INIT_ZTIMER_TIMER +# define INIT_ZTIMER_TIMER 1 # endif #endif -/* use RTT for ZTIMER_MSEC, if used. Use RTT also for ZTIMER_USEC, - unless module ztimer_periph_rtc is explicitly used by application */ -#if MODULE_ZTIMER_PERIPH_RTT && (MODULE_ZTIMER_MSEC || (MODULE_ZTIMER_SEC && !MODULE_ZTIMER_PERIPH_RTC)) -static ztimer_periph_rtt_t _ztimer_periph_timer_rtt_msec_sec; -# define ZTIMER_RTT_INIT (&_ztimer_periph_timer_rtt_msec_sec) +/* ZTIMER_MSEC prefers ZTIMER_RTT (ztimer_periph_rtt) + * if it is available and runs at a frequency > 1kHz + * if not it falls back to use the basic timer */ +#if MODULE_ZTIMER_MSEC +# if defined(ZTIMER_RTT) && ZTIMER_RTT_FREQ >= FREQ_1KHZ +# define ZTIMER_MSEC_RTT 1 +# ifndef INIT_ZTIMER_RTT +# define INIT_ZTIMER_RTT 1 +# endif +# if ZTIMER_RTT_FREQ != FREQ_1KHZ +# define ZTIMER_MSEC_CONVERT_LOWER_FREQ ZTIMER_RTT_FREQ +# endif +# else +# define ZTIMER_MSEC_TIMER 1 +# ifndef INIT_ZTIMER_TIMER +# define INIT_ZTIMER_TIMER 1 +# endif +# define ZTIMER_MSEC_CONVERT_LOWER_FREQ ZTIMER_TIMER_FREQ +# endif +#endif + +/* ZTIMER_SEC prefers ZTIMER_RTT (ztimer_periph_rtt) if it is available + * if not it prefers ZTIMER_RTC (ztimer_periph_rtc) if it is available + * if not it falls back to use the basic timer */ +#if MODULE_ZTIMER_SEC +# ifdef ZTIMER_RTT +# define ZTIMER_SEC_RTT +# ifndef INIT_ZTIMER_RTT +# define INIT_ZTIMER_RTT 1 +# endif +# define ZTIMER_SEC_CONVERT_LOWER_FREQ ZTIMER_RTT_FREQ +# else +# ifdef ZTIMER_RTC +# define ZTIMER_SEC_RTC +# ifndef INIT_ZTIMER_RTC +# define INIT_ZTIMER_RTC 1 +# endif +# else +# define ZTIMER_SEC_TIMER +# ifndef INIT_ZTIMER_TIMER +# define INIT_ZTIMER_TIMER 1 +# endif +# define ZTIMER_SEC_CONVERT_LOWER_FREQ ZTIMER_TIMER_FREQ +# endif +# endif +#endif + +/* Step 2: setup static memory for used ztimer-periphery */ + +#if INIT_ZTIMER_TIMER +static ztimer_periph_timer_t ZTIMER_TIMER = { + .min = CONFIG_ZTIMER_USEC_MIN +}; +#endif + +#if INIT_ZTIMER_RTT +static ztimer_periph_rtt_t ZTIMER_RTT; +#endif + +#if INIT_ZTIMER_RTC +static ztimer_periph_rtc_t ZTIMER_RTC; +#endif + +/* Step 3: setup constants for ztimers and memory for converters */ + +#if MODULE_ZTIMER_USEC +# ifdef ZTIMER_TIMER +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 +ztimer_clock_t *const ZTIMER_USEC = &ZTIMER_TIMER_CLK; +# elif ZTIMER_TIMER_FREQ == 250000LU +static ztimer_convert_shift_t _ztimer_convert_shift_usec; +ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_shift_usec.super.super; +# else +static ztimer_convert_frac_t _ztimer_convert_frac_usec; +ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_frac_usec.super.super; +# endif #endif #if MODULE_ZTIMER_MSEC -# if MODULE_ZTIMER_PERIPH_RTT -ztimer_clock_t *const ZTIMER_MSEC_BASE = &_ztimer_periph_timer_rtt_msec_sec; -# if RTT_FREQUENCY != FREQ_1KHZ -static ztimer_convert_frac_t _ztimer_convert_frac_msec; -ztimer_clock_t *const ZTIMER_MSEC = &_ztimer_convert_frac_msec_sec.super.super; -# define ZTIMER_MSEC_CONVERT_LOWER_FREQ RTT_FREQUENCY -# define ZTIMER_MSEC_CONVERT_LOWER (&_ztimer_periph_timer_rtt_msec_sec) -# else -ztimer_clock_t *const ZTIMER_MSEC = &_ztimer_periph_timer_rtt_msec_sec; -# endif -# elif MODULE_ZTIMER_USEC +# ifdef ZTIMER_MSEC_RTT +ztimer_clock_t *const ZTIMER_MSEC_BASE = &ZTIMER_RTT_CLK; +# elif defined(ZTIMER_MSEC_TIMER) +ztimer_clock_t *const ZTIMER_MSEC_BASE = &ZTIMER_TIMER_CLK; +# else +# error No suitable ZTIMER_MSEC config. No rtt or basic timer? +# endif +# ifdef ZTIMER_MSEC_CONVERT_LOWER_FREQ static ztimer_convert_frac_t _ztimer_convert_frac_msec; ztimer_clock_t *const ZTIMER_MSEC = &_ztimer_convert_frac_msec.super.super; -ztimer_clock_t *const ZTIMER_MSEC_BASE = &_ztimer_periph_timer_usec.super; -# define ZTIMER_MSEC_CONVERT_LOWER ZTIMER_USEC_BASE -# define ZTIMER_MSEC_CONVERT_LOWER_FREQ CONFIG_ZTIMER_USEC_BASE_FREQ # else -# error No suitable ZTIMER_MSEC config. Maybe add USEMODULE += ztimer_usec? -# endif +ztimer_clock_t *const ZTIMER_MSEC = &ZTIMER_RTT_CLK; +# endif #endif #if MODULE_ZTIMER_SEC -# if MODULE_ZTIMER_PERIPH_RTC -static ztimer_periph_rtc_t _ztimer_periph_timer_rtc_sec; -ztimer_clock_t *const ZTIMER_SEC = &_ztimer_periph_timer_rtc_sec; -# elif MODULE_ZTIMER_PERIPH_RTT -static ztimer_convert_frac_t _ztimer_convert_frac_sec; -ztimer_clock_t *const ZTIMER_SEC = &_ztimer_convert_frac_sec.super.super; -ztimer_clock_t *const ZTIMER_SEC_BASE = &_ztimer_periph_timer_msec_sec.super; -# define ZTIMER_SEC_CONVERT_LOWER (&_ztimer_periph_timer_rtt_msec_sec) -# define ZTIMER_SEC_CONVERT_LOWER_FREQ RTT_FREQUENCY -# elif MODULE_ZTIMER_USEC -static ztimer_convert_frac_t _ztimer_convert_frac_sec; -ztimer_clock_t *const ZTIMER_SEC = &_ztimer_convert_frac_sec.super.super; -ztimer_clock_t *const ZTIMER_SEC_BASE = &_ztimer_periph_timer_usec.super; -# define ZTIMER_SEC_CONVERT_LOWER ZTIMER_USEC_BASE -# define ZTIMER_SEC_CONVERT_LOWER_FREQ CONFIG_ZTIMER_USEC_BASE_FREQ +# ifdef ZTIMER_SEC_RTC +ztimer_clock_t *const ZTIMER_SEC_BASE = &ZTIMER_RTC_CLK; +ztimer_clock_t *const ZTIMER_SEC = &ZTIMER_RTC_CLK; +# elif defined(ZTIMER_SEC_RTT) +ztimer_clock_t *const ZTIMER_SEC_BASE = &ZTIMER_RTT_CLK; +# elif defined(ZTIMER_SEC_TIMER) +ztimer_clock_t *const ZTIMER_SEC_BASE = &ZTIMER_TIMER_CLK; # else -# error No suitable ZTIMER_SEC config. Maybe add USEMODULE += ztimer_usec? +# error No suitable ZTIMER_SEC config. No rtc, rtt or basic timer? +# endif + +# ifdef ZTIMER_SEC_CONVERT_LOWER_FREQ +static ztimer_convert_frac_t _ztimer_convert_frac_sec; +ztimer_clock_t *const ZTIMER_SEC = &_ztimer_convert_frac_sec.super.super; # endif #endif void ztimer_init(void) { -#if MODULE_ZTIMER_USEC -# if CONFIG_ZTIMER_USEC_TYPE_PERIPH_TIMER +/* Step 4: initialize used ztimer-periphery */ +#if INIT_ZTIMER_TIMER LOG_DEBUG( - "ztimer_init(): ZTIMER_USEC using periph timer %u, freq %lu, width %u\n", + "ztimer_init(): ZTIMER_TIMER using periph timer %u, freq %lu, width %u\n", CONFIG_ZTIMER_USEC_DEV, CONFIG_ZTIMER_USEC_BASE_FREQ, CONFIG_ZTIMER_USEC_WIDTH); - - ztimer_periph_timer_init(&_ztimer_periph_timer_usec, CONFIG_ZTIMER_USEC_DEV, - CONFIG_ZTIMER_USEC_BASE_FREQ, - WIDTH_TO_MAXVAL(CONFIG_ZTIMER_USEC_WIDTH)); + ztimer_periph_timer_init(&ZTIMER_TIMER, CONFIG_ZTIMER_USEC_DEV, + ZTIMER_TIMER_FREQ, WIDTH_TO_MAXVAL(CONFIG_ZTIMER_USEC_WIDTH)); +# ifdef MODULE_PM_LAYERED + LOG_DEBUG("ztimer_init(): ZTIMER_TIMER setting required_pm_mode to %i\n", + CONFIG_ZTIMER_TIMER_BLOCK_PM_MODE); + ZTIMER_TIMER_CLK.required_pm_mode = CONFIG_ZTIMER_TIMER_BLOCK_PM_MODE; # endif -# if CONFIG_ZTIMER_USEC_BASE_FREQ != FREQ_1MHZ -# if CONFIG_ZTIMER_USEC_BASE_FREQ == FREQ_250KHZ +#endif + +#if INIT_ZTIMER_RTT + LOG_DEBUG("ztimer_init(): initializing rtt\n"); + ztimer_periph_rtt_init(&ZTIMER_RTT); +# ifdef MODULE_PM_LAYERED + LOG_DEBUG("ztimer_init(): ZTIMER_RTT setting required_pm_mode to %i\n", + CONFIG_ZTIMER_RTT_BLOCK_PM_MODE); + ZTIMER_RTT_CLK.required_pm_mode = CONFIG_ZTIMER_RTT_BLOCK_PM_MODE; +# endif +#endif + +#if INIT_ZTIMER_RTC + LOG_DEBUG("ztimer_init(): initializing rtc\n"); + ztimer_periph_rtc_init(&ZTIMER_RTC); +# ifdef MODULE_PM_LAYERED + LOG_DEBUG("ztimer_init(): ZTIMER_RTC setting required_pm_mode to %i\n", + CONFIG_ZTIMER_RTC_BLOCK_PM_MODE); + ZTIMER_RTC_CLK.required_pm_mode = CONFIG_ZTIMER_RTC_BLOCK_PM_MODE; +# endif +#endif + +/* Step 5: initialize ztimers requested */ +#if MODULE_ZTIMER_USEC +# if ZTIMER_TIMER_FREQ != FREQ_1MHZ +# if ZTIMER_TIMER_FREQ == FREQ_250KHZ LOG_DEBUG("ztimer_init(): ZTIMER_USEC convert_shift %lu to 1000000\n", - CONFIG_ZTIMER_USEC_BASE_FREQ); + ZTIMER_TIMER_FREQ); ztimer_convert_shift_up_init(&_ztimer_convert_shift_usec, - &_ztimer_periph_timer_usec.super, 2); + ZTIMER_USEC_BASE, 2); # else LOG_DEBUG("ztimer_init(): ZTIMER_USEC convert_frac %lu to 1000000\n", - CONFIG_ZTIMER_USEC_BASE_FREQ); - ztimer_convert_frac_init(&_ztimer_convert_frac_usec, - &_ztimer_periph_timer_usec.super, - FREQ_1MHZ, CONFIG_ZTIMER_USEC_BASE_FREQ); + ZTIMER_TIMER_FREQ); + ztimer_convert_frac_init(&_ztimer_convert_frac_usec, ZTIMER_USEC_BASE, + FREQ_1MHZ, ZTIMER_TIMER_FREQ); # endif +# else + LOG_DEBUG("ztimer_init(): ZTIMER_USEC without conversion\n"); # endif # ifdef CONFIG_ZTIMER_USEC_ADJUST_SET LOG_DEBUG("ztimer_init(): ZTIMER_USEC setting adjust_set value to %i\n", @@ -163,24 +277,13 @@ void ztimer_init(void) CONFIG_ZTIMER_USEC_ADJUST_SLEEP ); ZTIMER_USEC->adjust_sleep = CONFIG_ZTIMER_USEC_ADJUST_SLEEP; # endif -# ifdef MODULE_PM_LAYERED - LOG_DEBUG("ztimer_init(): ZTIMER_USEC setting required_pm_mode to %i\n", - CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE); - ZTIMER_USEC->required_pm_mode = CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE; -# endif -#endif - -#ifdef ZTIMER_RTT_INIT - LOG_DEBUG("ztimer_init(): initializing rtt\n"); - ztimer_periph_rtt_init(ZTIMER_RTT_INIT); #endif #if MODULE_ZTIMER_MSEC # if ZTIMER_MSEC_CONVERT_LOWER_FREQ LOG_DEBUG("ztimer_init(): ZTIMER_MSEC convert_frac from %lu to 1000\n", (long unsigned)ZTIMER_MSEC_CONVERT_LOWER_FREQ); - ztimer_convert_frac_init(&_ztimer_convert_frac_msec, - ZTIMER_MSEC_CONVERT_LOWER, + ztimer_convert_frac_init(&_ztimer_convert_frac_msec, ZTIMER_MSEC_BASE, FREQ_1KHZ, ZTIMER_MSEC_CONVERT_LOWER_FREQ); # endif # ifdef CONFIG_ZTIMER_MSEC_ADJUST @@ -188,23 +291,15 @@ void ztimer_init(void) CONFIG_ZTIMER_MSEC_ADJUST); ZTIMER_MSEC->adjust = CONFIG_ZTIMER_MSEC_ADJUST; # endif -# ifdef MODULE_PM_LAYERED - LOG_DEBUG("ztimer_init(): ZTIMER_MSEC setting required_pm_mode to %i\n", - CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE); - ZTIMER_MSEC->required_pm_mode = CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE; -# endif #endif #if MODULE_ZTIMER_SEC -# if MODULE_ZTIMER_PERIPH_RTC - LOG_DEBUG("ztimer_init(): initializing rtc\n"); - ztimer_periph_rtc_init(&_ztimer_periph_timer_rtc_sec); -# else - LOG_DEBUG("ztimer_init(): ZTIMER_SEC convert_frac from %lu to 1000\n", +# if ZTIMER_SEC_CONVERT_LOWER_FREQ + LOG_DEBUG("ztimer_init(): ZTIMER_SEC convert_frac from %lu to 1\n", (long unsigned)ZTIMER_SEC_CONVERT_LOWER_FREQ); - ztimer_convert_frac_init(&_ztimer_convert_frac_sec, - ZTIMER_SEC_CONVERT_LOWER, + ztimer_convert_frac_init(&_ztimer_convert_frac_sec, ZTIMER_SEC_BASE, FREQ_1HZ, ZTIMER_SEC_CONVERT_LOWER_FREQ); # endif #endif } +#endif /* IS_USED(MODULE_AUTO_INIT_ZTIMER) */