diff --git a/sys/event/periodic.c b/sys/event/periodic.c index e493b0ee33..cba234b491 100644 --- a/sys/event/periodic.c +++ b/sys/event/periodic.c @@ -28,7 +28,11 @@ static int _event_periodic_callback(void *arg) event_post(event_periodic->queue, event_periodic->event); - return 0; + if (event_periodic->count && --event_periodic->count == 0) { + return !ZTIMER_PERIODIC_KEEP_GOING; + } + + return ZTIMER_PERIODIC_KEEP_GOING; } void event_periodic_init(event_periodic_t *event_periodic, @@ -37,6 +41,7 @@ void event_periodic_init(event_periodic_t *event_periodic, { ztimer_periodic_init(clock, &event_periodic->timer, _event_periodic_callback, event_periodic, 0); + event_periodic->count = EVENT_PERIODIC_FOREVER; event_periodic->queue = queue; event_periodic->event = event; } diff --git a/sys/include/event/periodic.h b/sys/include/event/periodic.h index 408e8f0eef..8f786d7ba9 100644 --- a/sys/include/event/periodic.h +++ b/sys/include/event/periodic.h @@ -43,6 +43,11 @@ extern "C" { #endif +/** + * @brief Run the periodic event forever + */ +#define EVENT_PERIODIC_FOREVER 0 + /** * @brief Timeout Event structure */ @@ -50,10 +55,13 @@ typedef struct { ztimer_periodic_t timer; /**< ztimer object used for timeout */ event_queue_t *queue; /**< event queue to post event to */ event_t *event; /**< event to post after timeout */ + uint32_t count; /**< times the event should repeat itself */ } event_periodic_t; /** - * @brief Initialize a periodic event timeout + * @brief Initialize a periodic event timeout + * + * @note: On init the periodic event is to to run forever. * * @param[in] event_periodic event_periodic object to initialize * @param[in] clock the clock to configure this timer on @@ -73,16 +81,32 @@ void event_periodic_init(event_periodic_t *event_periodic, ztimer_clock_t *clock * @note: the used event_periodic struct must stay valid until after the timeout * event has been processed! * + * @note: this function does not touch the current count value. + * * @param[in] event_periodic event_timout context object to use * @param[in] interval period length for the event */ -static inline void event_periodic_start(event_periodic_t *event_periodic, - uint32_t interval) +static inline void event_periodic_start(event_periodic_t *event_periodic, uint32_t interval) { event_periodic->timer.interval = interval; ztimer_periodic_start(&event_periodic->timer); } +/** + * @brief Set the amount of times the periodic event should repeat itself. + * + * @param[in] event_periodic event_timout context object to use + * @param[in] count times the event should repeat itself, + * EVENT_PERIODIC_FOREVER to run for ever. + */ +static inline void event_periodic_set_count(event_periodic_t *event_periodic, uint32_t count) +{ + unsigned state = irq_disable(); + + event_periodic->count = count; + irq_restore(state); +} + /** * @brief Stop a periodic timeout event * @@ -91,6 +115,10 @@ static inline void event_periodic_start(event_periodic_t *event_periodic, * connected event will be put already into the given event queue and this * function does not have any effect. * + * @note Calling this function does not touch event_periodic->count, if the + * periodic event was not set to run for ever and did run until expiration, + * then count will be != 0 after this function is called. + * * @param[in] event_periodic event_periodic_timeout context object to use */ static inline void event_periodic_stop(event_periodic_t *event_periodic) diff --git a/tests/event_ztimer/main.c b/tests/event_ztimer/main.c index bd96db260d..54ebead68e 100644 --- a/tests/event_ztimer/main.c +++ b/tests/event_ztimer/main.c @@ -72,8 +72,14 @@ static void callback_4times(void *arg) printf("trigger %d of periodic timeout, elapsed time: %" PRIu32 " us\n", *count, elapsed); } - if (*count == 4) { + if (*count == 2) { + puts("stop periodic event"); event_periodic_stop(&event_periodic); + puts("resume periodic event, 2 triggers remaining"); + event_periodic_start(&event_periodic, EVENT_TIMEOUT_TIME); + before = event_periodic.timer.last; + } + if (*count == 4) { mutex_unlock(&lock); } else if (*count > 4) { @@ -103,6 +109,7 @@ int main(void) puts("posting periodic timed callback with timeout 1sec"); event_periodic_init(&event_periodic, ZTIMER_USEC, EVENT_PRIO_MEDIUM, &event_4times.super); + event_periodic_set_count(&event_periodic, 4); event_periodic_start(&event_periodic, EVENT_TIMEOUT_TIME); before = event_periodic.timer.last; puts("waiting for periodic callback to be triggered 4 times");