Add ticker suspend/resume API

Add an API to suspend and resume the ticker.
pull/7524/head
Russ Butler 2018-07-13 13:58:37 -05:00
parent 3c25b96441
commit 23e6d50000
2 changed files with 60 additions and 1 deletions

View File

@ -32,6 +32,9 @@ static void initialize(const ticker_data_t *ticker)
if (ticker->queue->initialized) {
return;
}
if (ticker->queue->suspended) {
return;
}
ticker->interface->init();
@ -70,6 +73,7 @@ static void initialize(const ticker_data_t *ticker)
ticker->queue->max_delta_us = max_delta_us;
ticker->queue->present_time = 0;
ticker->queue->dispatching = false;
ticker->queue->suspended = false;
ticker->queue->initialized = true;
update_present_time(ticker);
@ -121,6 +125,9 @@ static us_timestamp_t convert_timestamp(us_timestamp_t ref, timestamp_t timestam
static void update_present_time(const ticker_data_t *const ticker)
{
ticker_event_queue_t *queue = ticker->queue;
if (queue->suspended) {
return;
}
uint32_t ticker_time = ticker->interface->read();
if (ticker_time == ticker->queue->tick_last_read) {
// No work to do
@ -230,7 +237,7 @@ int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, t
static void schedule_interrupt(const ticker_data_t *const ticker)
{
ticker_event_queue_t *queue = ticker->queue;
if (ticker->queue->dispatching) {
if (queue->suspended || ticker->queue->dispatching) {
// Don't schedule the next interrupt until dispatching is
// finished. This prevents repeated calls to interface->set_interrupt
return;
@ -285,6 +292,10 @@ void ticker_irq_handler(const ticker_data_t *const ticker)
core_util_critical_section_enter();
ticker->interface->clear_interrupt();
if (ticker->queue->suspended) {
core_util_critical_section_exit();
return;
}
/* Go through all the pending TimerEvents */
ticker->queue->dispatching = true;
@ -430,3 +441,29 @@ int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *time
return ret;
}
void ticker_suspend(const ticker_data_t *const ticker)
{
core_util_critical_section_enter();
ticker->queue->suspended = true;
core_util_critical_section_exit();
}
void ticker_resume(const ticker_data_t *const ticker)
{
core_util_critical_section_enter();
ticker->queue->suspended = false;
if (ticker->queue->initialized) {
ticker->queue->tick_last_read = ticker->interface->read();
update_present_time(ticker);
schedule_interrupt(ticker);
} else {
initialize(ticker);
}
core_util_critical_section_exit();
}

View File

@ -82,6 +82,7 @@ typedef struct {
us_timestamp_t present_time; /**< Store the timestamp used for present time */
bool initialized; /**< Indicate if the instance is initialized */
bool dispatching; /**< The function ticker_irq_handler is dispatching */
bool suspended; /**< Indicate if the instance is suspended */
uint8_t frequency_shifts; /**< If frequency is a value of 2^n, this is n, otherwise 0 */
} ticker_event_queue_t;
@ -184,6 +185,27 @@ us_timestamp_t ticker_read_us(const ticker_data_t *const ticker);
*/
int ticker_get_next_timestamp(const ticker_data_t *const ticker, timestamp_t *timestamp);
/** Suspend this ticker
*
* When suspended reads will always return the same time and no
* events will be dispatched. When suspended the common layer
* will only ever call the interface function clear_interrupt()
* and that is only if ticker_irq_handler is called.
*
*
* @param ticker The ticker object.
*/
void ticker_suspend(const ticker_data_t *const ticker);
/** Resume this ticker
*
* When resumed the ticker will ignore any time that has passed
* and continue counting up where it left off.
*
* @param ticker The ticker object.
*/
void ticker_resume(const ticker_data_t *const ticker);
/* Private functions
*
* @cond PRIVATE