From 10ee2fa935779d994cb5f43952a7014387ecef24 Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Wed, 20 Sep 2017 11:07:42 +0200 Subject: [PATCH] Enable deepsleep for low power Ticker and low power Timer. Fix for issue #5076. --- drivers/Ticker.cpp | 5 +++-- drivers/Ticker.h | 24 +++++++++++++++--------- drivers/Timer.cpp | 16 ++++++++++++---- drivers/Timer.h | 1 + 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/Ticker.cpp b/drivers/Ticker.cpp index 35c2ee43dd3..c2589c0d808 100644 --- a/drivers/Ticker.cpp +++ b/drivers/Ticker.cpp @@ -25,10 +25,11 @@ namespace mbed { void Ticker::detach() { core_util_critical_section_enter(); remove(); - // unlocked only if we were attached (we locked it) - if (_function) { + // unlocked only if we were attached (we locked it) and this is not low power ticker + if(_function && _lock_deepsleep) { sleep_manager_unlock_deep_sleep(); } + _function = 0; core_util_critical_section_exit(); } diff --git a/drivers/Ticker.h b/drivers/Ticker.h index 66b38490519..d7e3cfcd3f7 100644 --- a/drivers/Ticker.h +++ b/drivers/Ticker.h @@ -21,13 +21,14 @@ #include "platform/mbed_toolchain.h" #include "platform/NonCopyable.h" #include "platform/mbed_sleep.h" +#include "hal/lp_ticker_api.h" namespace mbed { /** \addtogroup drivers */ /** A Ticker is used to call a function at a recurring interval * - * You can use as many seperate Ticker objects as you require. + * You can use as many separate Ticker objects as you require. * * @note Synchronization level: Interrupt safe * @@ -64,14 +65,18 @@ namespace mbed { class Ticker : public TimerEvent, private NonCopyable { public: - Ticker() : TimerEvent(), _function(0) { + Ticker() : TimerEvent(), _function(0), _lock_deepsleep(true) { } - Ticker(const ticker_data_t *data) : TimerEvent(data), _function(0) { + // When low power ticker is in use, then do not disable deep-sleep. + Ticker(const ticker_data_t *data) : TimerEvent(data), _function(0), _lock_deepsleep(true) { data->interface->init(); +#if DEVICE_LOWPOWERTIMER + _lock_deepsleep = (data != get_lp_ticker_data()); +#endif } - /** Attach a function to be called by the Ticker, specifiying the interval in seconds + /** Attach a function to be called by the Ticker, specifying the interval in seconds * * @param func pointer to the function to be called * @param t the time between calls in seconds @@ -80,7 +85,7 @@ class Ticker : public TimerEvent, private NonCopyable { attach_us(func, t * 1000000.0f); } - /** Attach a member function to be called by the Ticker, specifiying the interval in seconds + /** Attach a member function to be called by the Ticker, specifying the interval in seconds * * @param obj pointer to the object to call the member function on * @param method pointer to the member function to be called @@ -97,21 +102,21 @@ class Ticker : public TimerEvent, private NonCopyable { attach(callback(obj, method), t); } - /** Attach a function to be called by the Ticker, specifiying the interval in micro-seconds + /** Attach a function to be called by the Ticker, specifying the interval in micro-seconds * * @param func pointer to the function to be called * @param t the time between calls in micro-seconds */ void attach_us(Callback func, us_timestamp_t t) { - // lock only for the initial callback setup - if (!_function) { + // lock only for the initial callback setup and this is not low power ticker + if(!_function && _lock_deepsleep) { sleep_manager_lock_deep_sleep(); } _function = func; setup(t); } - /** Attach a member function to be called by the Ticker, specifiying the interval in micro-seconds + /** Attach a member function to be called by the Ticker, specifying the interval in micro-seconds * * @param obj pointer to the object to call the member function on * @param method pointer to the member function to be called @@ -143,6 +148,7 @@ class Ticker : public TimerEvent, private NonCopyable { protected: us_timestamp_t _delay; /**< Time delay (in microseconds) for re-setting the multi-shot callback. */ Callback _function; /**< Callback. */ + bool _lock_deepsleep; /**< Flag which indicates if deep-sleep should be disabled. */ }; } // namespace mbed diff --git a/drivers/Timer.cpp b/drivers/Timer.cpp index 12f9737ca46..57b4ac33c48 100644 --- a/drivers/Timer.cpp +++ b/drivers/Timer.cpp @@ -17,21 +17,27 @@ #include "hal/ticker_api.h" #include "hal/us_ticker_api.h" #include "platform/mbed_critical.h" +#include "hal/lp_ticker_api.h" namespace mbed { -Timer::Timer() : _running(), _start(), _time(), _ticker_data(get_us_ticker_data()) { +Timer::Timer() : _running(), _start(), _time(), _ticker_data(get_us_ticker_data()), _lock_deepsleep(true) { reset(); } -Timer::Timer(const ticker_data_t *data) : _running(), _start(), _time(), _ticker_data(data) { +Timer::Timer(const ticker_data_t *data) : _running(), _start(), _time(), _ticker_data(data), _lock_deepsleep(true) { reset(); +#if DEVICE_LOWPOWERTIMER + _lock_deepsleep = (data != get_lp_ticker_data()); +#endif } void Timer::start() { core_util_critical_section_enter(); if (!_running) { - sleep_manager_lock_deep_sleep(); + if(_lock_deepsleep) { + sleep_manager_lock_deep_sleep(); + } _start = ticker_read_us(_ticker_data); _running = 1; } @@ -42,7 +48,9 @@ void Timer::stop() { core_util_critical_section_enter(); _time += slicetime(); if (_running) { - sleep_manager_unlock_deep_sleep(); + if(_lock_deepsleep) { + sleep_manager_unlock_deep_sleep(); + } } _running = 0; core_util_critical_section_exit(); diff --git a/drivers/Timer.h b/drivers/Timer.h index e353720b966..caef8771e8d 100644 --- a/drivers/Timer.h +++ b/drivers/Timer.h @@ -100,6 +100,7 @@ class Timer : private NonCopyable { us_timestamp_t _start; // the start time of the latest slice us_timestamp_t _time; // any accumulated time from previous slices const ticker_data_t *_ticker_data; + bool _lock_deepsleep; // flag which indicates if deep-sleep should be disabled }; } // namespace mbed