mirror of https://github.com/ARMmbed/mbed-os.git
PmwOut: Add methods to suspend and resume PWM
It is now possible to temporarily suspend PWM and safely preserve the duty cycle set. This functionality is needed to allow a device to enter deep sleep as a PWM instance prevents deep sleep in order for the timer it relies on to run so its output can be modified. The duty cycle configuration can be restored upon resuming from deep sleep.pull/11641/head
parent
7eb8807a76
commit
a9496ad9f7
|
@ -118,6 +118,24 @@ public:
|
|||
*/
|
||||
void pulsewidth_us(int us);
|
||||
|
||||
/** Suspend PWM operation
|
||||
*
|
||||
* Control the PWM state. This is primarily intended
|
||||
* for temporary power-saving; This call can
|
||||
* allow pwm to be temporarily disabled to permit power saving without
|
||||
* losing device state. The subsequent function call must be PwmOut::resume
|
||||
* for PWM to resume; any other calls prior to resuming are undefined behavior.
|
||||
*/
|
||||
void suspend();
|
||||
|
||||
/** Resume PWM operation
|
||||
*
|
||||
* Control the PWM state. This is primarily intended
|
||||
* to resume PWM operations after a previous PwmOut::suspend call;
|
||||
* This call restores the device state prior to suspension.
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/** A operator shorthand for write()
|
||||
* \sa PwmOut::write()
|
||||
*/
|
||||
|
@ -155,8 +173,17 @@ protected:
|
|||
/** Unlock deep sleep in case it is locked */
|
||||
void unlock_deep_sleep();
|
||||
|
||||
/** Initialize this instance */
|
||||
void init();
|
||||
|
||||
/** Power down this instance */
|
||||
void deinit();
|
||||
|
||||
pwmout_t _pwm;
|
||||
PinName _pin;
|
||||
bool _deep_sleep_locked;
|
||||
bool _initialized;
|
||||
float _duty_cycle;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -22,28 +22,28 @@
|
|||
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "platform/mbed_power_mgmt.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
PwmOut::PwmOut(PinName pin) : _deep_sleep_locked(false)
|
||||
PwmOut::PwmOut(PinName pin) :
|
||||
_pin(pin),
|
||||
_deep_sleep_locked(false),
|
||||
_initialized(false),
|
||||
_duty_cycle(0)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
pwmout_init(&_pwm, pin);
|
||||
core_util_critical_section_exit();
|
||||
PwmOut::init();
|
||||
}
|
||||
|
||||
PwmOut::~PwmOut()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
pwmout_free(&_pwm);
|
||||
unlock_deep_sleep();
|
||||
core_util_critical_section_exit();
|
||||
MBED_ASSERT(!_initialized);
|
||||
PwmOut::deinit();
|
||||
}
|
||||
|
||||
void PwmOut::write(float value)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
lock_deep_sleep();
|
||||
pwmout_write(&_pwm, value);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
@ -98,6 +98,26 @@ void PwmOut::pulsewidth_us(int us)
|
|||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void PwmOut::suspend()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
if (_initialized) {
|
||||
_duty_cycle = PwmOut::read();
|
||||
PwmOut::deinit();
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void PwmOut::resume()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
if (!_initialized) {
|
||||
PwmOut::init();
|
||||
PwmOut::write(_duty_cycle);
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void PwmOut::lock_deep_sleep()
|
||||
{
|
||||
if (_deep_sleep_locked == false) {
|
||||
|
@ -114,6 +134,32 @@ void PwmOut::unlock_deep_sleep()
|
|||
}
|
||||
}
|
||||
|
||||
void PwmOut::init()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
|
||||
if (!_initialized) {
|
||||
pwmout_init(&_pwm, _pin);
|
||||
lock_deep_sleep();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void PwmOut::deinit()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
|
||||
if (_initialized) {
|
||||
pwmout_free(&_pwm);
|
||||
unlock_deep_sleep();
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // #if DEVICE_PWMOUT
|
||||
|
|
Loading…
Reference in New Issue