Skip to content

Commit

Permalink
Fix PwmOut::resume() for static pinmap usage (#281)
Browse files Browse the repository at this point in the history
* Fix PwmOut::resume() for static pinmap usage

* Use function pointers, like SPI does

* Fix style

* Remove "static"

* Revert "Remove "static""

This reverts commit c009297.
  • Loading branch information
multiplemonomials authored Jun 19, 2024
1 parent 47ee2ce commit f442436
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
19 changes: 17 additions & 2 deletions drivers/include/drivers/PwmOut.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class PwmOut {

/** Create a PwmOut connected to the specified pin
*
* @param pinmap reference to structure which holds static pinmap.
* @param pinmap reference to structure which holds static pinmap.
* This reference is stored in the PwmOut, so the pinmap needs to live as long as this object does.
*/
PwmOut(const PinMap &pinmap);
PwmOut(const PinMap &&) = delete; // prevent passing of temporary objects
Expand Down Expand Up @@ -199,14 +200,28 @@ class PwmOut {
/** Unlock deep sleep in case it is locked */
void unlock_deep_sleep();

// Functions which call the underlying HAL init function. The direct one calls the static
// pinmap version (pwmout_init_direct()) and the normal one calls the PinName-accepting one (pwmout_init()).
// A pointer to one of these two functions is stored in the _init_func member.
// It's done this way so that references to pwmout_init(), and therefore to the pinmap tables,
// can be removed by the linker if only the static pinmap version is used.
static void _call_pwmout_init_direct(PwmOut *thisPtr);
static void _call_pwmout_init(PwmOut *thisPtr);

/** Initialize this instance */
void init();

/** Power down this instance */
void deinit();

pwmout_t _pwm;
PinName _pin;

const PinName _pin; // Pin, NC if using static pinmap
PinMap const *const _pinmap; // Static pinmap, nullptr if not used

/* Pointer to HAL init function */
void (*_init_func)(PwmOut *);

bool _deep_sleep_locked;
bool _initialized;
float _duty_cycle;
Expand Down
30 changes: 25 additions & 5 deletions drivers/source/PwmOut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ namespace mbed {

PwmOut::PwmOut(PinName pin) :
_pin(pin),
_pinmap(nullptr),
_init_func(_call_pwmout_init),
_deep_sleep_locked(false),
_initialized(false),
_duty_cycle(0),
Expand All @@ -36,11 +38,16 @@ PwmOut::PwmOut(PinName pin) :
PwmOut::init();
}

PwmOut::PwmOut(const PinMap &pinmap) : _deep_sleep_locked(false)
PwmOut::PwmOut(const PinMap &pinmap) :
_pin(NC),
_pinmap(&pinmap),
_init_func(_call_pwmout_init_direct),
_deep_sleep_locked(false),
_initialized(false),
_duty_cycle(0),
_period_us(0)
{
core_util_critical_section_enter();
pwmout_init_direct(&_pwm, &pinmap);
core_util_critical_section_exit();
PwmOut::init();
}

PwmOut::~PwmOut()
Expand Down Expand Up @@ -164,12 +171,25 @@ void PwmOut::unlock_deep_sleep()
}
}

void PwmOut::_call_pwmout_init_direct(PwmOut *thisPtr)
{
pwmout_init_direct(&thisPtr->_pwm, thisPtr->_pinmap);
}

void PwmOut::_call_pwmout_init(PwmOut *thisPtr)
{
pwmout_init(&thisPtr->_pwm, thisPtr->_pin);
}

void PwmOut::init()
{
core_util_critical_section_enter();

if (!_initialized) {
pwmout_init(&_pwm, _pin);

// Call either pwmout_init() or pwmout_init_direct(), depending on whether we have a PinName or a static pinmap
_init_func(this);

lock_deep_sleep();
_initialized = true;
}
Expand Down

0 comments on commit f442436

Please sign in to comment.