diff --git a/hal/LowPowerTickerWrapper.cpp b/hal/LowPowerTickerWrapper.cpp index 4f39235b14..179895f7ff 100644 --- a/hal/LowPowerTickerWrapper.cpp +++ b/hal/LowPowerTickerWrapper.cpp @@ -32,15 +32,7 @@ void LowPowerTickerWrapper::irq_handler(ticker_irq_handler_type handler) { core_util_critical_section_enter(); - if (_suspended) { - if (handler) { - handler(&data); - } - core_util_critical_section_exit(); - return; - } - - if (_pending_fire_now || _match_check(_intf->read())) { + if (_pending_fire_now || _match_check(_intf->read()) || _suspended) { _timeout.detach(); _pending_timeout = false; _pending_match = false; @@ -78,6 +70,14 @@ void LowPowerTickerWrapper::resume() { core_util_critical_section_enter(); + // Wait until rescheduling is allowed + while (!_set_interrupt_allowed) { + timestamp_t current = _intf->read(); + if (((current - _last_actual_set_interrupt) & _mask) >= _min_count_between_writes) { + _set_interrupt_allowed = true; + } + } + _suspended = false; core_util_critical_section_exit(); @@ -118,7 +118,7 @@ uint32_t LowPowerTickerWrapper::read() core_util_critical_section_enter(); timestamp_t current = _intf->read(); - if (_match_check(current)) { + if (!_suspended && _match_check(current)) { _intf->fire_interrupt(); } @@ -133,7 +133,13 @@ void LowPowerTickerWrapper::set_interrupt(timestamp_t timestamp) _last_set_interrupt = _intf->read(); _cur_match_time = timestamp; _pending_match = true; - _schedule_match(_last_set_interrupt); + if (!_suspended) { + _schedule_match(_last_set_interrupt); + } else { + _intf->set_interrupt(timestamp); + _last_actual_set_interrupt = _last_set_interrupt; + _set_interrupt_allowed = false; + } core_util_critical_section_exit(); } @@ -277,7 +283,7 @@ void LowPowerTickerWrapper::_schedule_match(timestamp_t current) _intf->set_interrupt(_cur_match_time); current = _intf->read(); _last_actual_set_interrupt = current; - _set_interrupt_allowed = false; + _set_interrupt_allowed = false; // Check for overflow uint32_t new_cycles_until_match = (_cur_match_time - current) & _mask; diff --git a/hal/LowPowerTickerWrapper.h b/hal/LowPowerTickerWrapper.h index aac8d70d17..8a6a05aca0 100644 --- a/hal/LowPowerTickerWrapper.h +++ b/hal/LowPowerTickerWrapper.h @@ -74,6 +74,9 @@ public: * * This stops to wrapper layer from using the microsecond ticker. * This should be called before using the low power ticker APIs directly. + * + * @warning: Make sure to suspend the LP ticker first (call ticker_suspend()), + * otherwise the behavior is undefined. */ void suspend(); diff --git a/hal/mbed_lp_ticker_wrapper.h b/hal/mbed_lp_ticker_wrapper.h index 4b317e36c2..e1c1fe4a26 100644 --- a/hal/mbed_lp_ticker_wrapper.h +++ b/hal/mbed_lp_ticker_wrapper.h @@ -53,6 +53,9 @@ const ticker_data_t *get_lp_ticker_wrapper_data(const ticker_data_t *data); * * Pass through all interrupts to the low power ticker and stop using * the microsecond ticker. + * + * @warning: Make sure to suspend the LP ticker first (call ticker_suspend()), + * otherwise the behavior is undefined. */ void lp_ticker_wrapper_suspend(void);