mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
sys/ztimer: add power management for ztimer clocks
This commit is contained in:
parent
c42677609b
commit
73e22612e2
@ -223,6 +223,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables interaction with pm_layered for a clock
|
||||||
|
*/
|
||||||
|
#define ZTIMER_CLOCK_NO_REQUIRED_PM_MODE (UINT8_MAX)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ztimer_base_t forward declaration
|
* @brief ztimer_base_t forward declaration
|
||||||
*/
|
*/
|
||||||
@ -297,6 +302,9 @@ struct ztimer_clock {
|
|||||||
uint32_t lower_last; /**< timer value at last now() call */
|
uint32_t lower_last; /**< timer value at last now() call */
|
||||||
ztimer_now_t checkpoint; /**< cumulated time at last now() call */
|
ztimer_now_t checkpoint; /**< cumulated time at last now() call */
|
||||||
#endif
|
#endif
|
||||||
|
#if MODULE_PM_LAYERED || DOXYGEN
|
||||||
|
uint8_t required_pm_mode; /**< min. pm mode required for the clock to run */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,6 +86,14 @@
|
|||||||
#define CONFIG_ZTIMER_USEC_WIDTH (32)
|
#define CONFIG_ZTIMER_USEC_WIDTH (32)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE
|
||||||
|
#define CONFIG_ZTIMER_USEC_REQUIRED_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE
|
||||||
|
#define CONFIG_ZTIMER_MSEC_REQUIRED_PM_MODE ZTIMER_CLOCK_NO_REQUIRED_PM_MODE
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MODULE_ZTIMER_USEC
|
#if MODULE_ZTIMER_USEC
|
||||||
# if CONFIG_ZTIMER_USEC_TYPE_PERIPH_TIMER
|
# if CONFIG_ZTIMER_USEC_TYPE_PERIPH_TIMER
|
||||||
static ztimer_periph_timer_t _ztimer_periph_timer_usec = { .min = CONFIG_ZTIMER_USEC_MIN };
|
static ztimer_periph_timer_t _ztimer_periph_timer_usec = { .min = CONFIG_ZTIMER_USEC_MIN };
|
||||||
@ -160,6 +168,11 @@ void ztimer_init(void)
|
|||||||
CONFIG_ZTIMER_USEC_ADJUST);
|
CONFIG_ZTIMER_USEC_ADJUST);
|
||||||
ZTIMER_USEC->adjust = CONFIG_ZTIMER_USEC_ADJUST;
|
ZTIMER_USEC->adjust = CONFIG_ZTIMER_USEC_ADJUST;
|
||||||
# endif
|
# 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
|
#endif
|
||||||
|
|
||||||
#ifdef ZTIMER_RTT_INIT
|
#ifdef ZTIMER_RTT_INIT
|
||||||
@ -180,5 +193,10 @@ void ztimer_init(void)
|
|||||||
CONFIG_ZTIMER_MSEC_ADJUST);
|
CONFIG_ZTIMER_MSEC_ADJUST);
|
||||||
ZTIMER_MSEC->adjust = CONFIG_ZTIMER_MSEC_ADJUST;
|
ZTIMER_MSEC->adjust = CONFIG_ZTIMER_MSEC_ADJUST;
|
||||||
# endif
|
# 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
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
#include "kernel_defines.h"
|
#include "kernel_defines.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
|
#ifdef MODULE_PM_LAYERED
|
||||||
|
#include "pm_layered.h"
|
||||||
|
#endif
|
||||||
#include "ztimer.h"
|
#include "ztimer.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
@ -106,6 +109,13 @@ static void _add_entry_to_list(ztimer_clock_t *clock, ztimer_base_t *entry)
|
|||||||
|
|
||||||
ztimer_base_t *list = &clock->list;
|
ztimer_base_t *list = &clock->list;
|
||||||
|
|
||||||
|
#ifdef MODULE_PM_LAYERED
|
||||||
|
/* First timer on the clock's linked list */
|
||||||
|
if (list->next == NULL && clock->required_pm_mode != ZTIMER_CLOCK_NO_REQUIRED_PM_MODE) {
|
||||||
|
pm_block(clock->required_pm_mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Jump past all entries which are set to an earlier target than the new entry */
|
/* Jump past all entries which are set to an earlier target than the new entry */
|
||||||
while (list->next) {
|
while (list->next) {
|
||||||
ztimer_base_t *list_entry = list->next;
|
ztimer_base_t *list_entry = list->next;
|
||||||
@ -223,6 +233,13 @@ static void _del_entry_from_list(ztimer_clock_t *clock, ztimer_base_t *entry)
|
|||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_PM_LAYERED
|
||||||
|
/* The last timer just got removed from the clock's linked list */
|
||||||
|
if (clock->list.next == NULL && clock->required_pm_mode != ZTIMER_CLOCK_NO_REQUIRED_PM_MODE) {
|
||||||
|
pm_unblock(clock->required_pm_mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ztimer_t *_now_next(ztimer_clock_t *clock)
|
static ztimer_t *_now_next(ztimer_clock_t *clock)
|
||||||
@ -232,7 +249,13 @@ static ztimer_t *_now_next(ztimer_clock_t *clock)
|
|||||||
if (entry && (entry->offset == 0)) {
|
if (entry && (entry->offset == 0)) {
|
||||||
clock->list.next = entry->next;
|
clock->list.next = entry->next;
|
||||||
if (!entry->next) {
|
if (!entry->next) {
|
||||||
|
/* The last timer just got removed from the clock's linked list */
|
||||||
clock->last = NULL;
|
clock->last = NULL;
|
||||||
|
#ifdef MODULE_PM_LAYERED
|
||||||
|
if (clock->required_pm_mode != ZTIMER_CLOCK_NO_REQUIRED_PM_MODE) {
|
||||||
|
pm_unblock(clock->required_pm_mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return (ztimer_t*)entry;
|
return (ztimer_t*)entry;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user