Skip to content

Commit f442436

Browse files
author
Jamie Smith
authored
Fix PwmOut::resume() for static pinmap usage (ARMmbed#281)
* Fix PwmOut::resume() for static pinmap usage * Use function pointers, like SPI does * Fix style * Remove "static" * Revert "Remove "static"" This reverts commit c009297.
1 parent 47ee2ce commit f442436

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

drivers/include/drivers/PwmOut.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class PwmOut {
6363

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

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

205214
/** Power down this instance */
206215
void deinit();
207216

208217
pwmout_t _pwm;
209-
PinName _pin;
218+
219+
const PinName _pin; // Pin, NC if using static pinmap
220+
PinMap const *const _pinmap; // Static pinmap, nullptr if not used
221+
222+
/* Pointer to HAL init function */
223+
void (*_init_func)(PwmOut *);
224+
210225
bool _deep_sleep_locked;
211226
bool _initialized;
212227
float _duty_cycle;

drivers/source/PwmOut.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace mbed {
2828

2929
PwmOut::PwmOut(PinName pin) :
3030
_pin(pin),
31+
_pinmap(nullptr),
32+
_init_func(_call_pwmout_init),
3133
_deep_sleep_locked(false),
3234
_initialized(false),
3335
_duty_cycle(0),
@@ -36,11 +38,16 @@ PwmOut::PwmOut(PinName pin) :
3638
PwmOut::init();
3739
}
3840

39-
PwmOut::PwmOut(const PinMap &pinmap) : _deep_sleep_locked(false)
41+
PwmOut::PwmOut(const PinMap &pinmap) :
42+
_pin(NC),
43+
_pinmap(&pinmap),
44+
_init_func(_call_pwmout_init_direct),
45+
_deep_sleep_locked(false),
46+
_initialized(false),
47+
_duty_cycle(0),
48+
_period_us(0)
4049
{
41-
core_util_critical_section_enter();
42-
pwmout_init_direct(&_pwm, &pinmap);
43-
core_util_critical_section_exit();
50+
PwmOut::init();
4451
}
4552

4653
PwmOut::~PwmOut()
@@ -164,12 +171,25 @@ void PwmOut::unlock_deep_sleep()
164171
}
165172
}
166173

174+
void PwmOut::_call_pwmout_init_direct(PwmOut *thisPtr)
175+
{
176+
pwmout_init_direct(&thisPtr->_pwm, thisPtr->_pinmap);
177+
}
178+
179+
void PwmOut::_call_pwmout_init(PwmOut *thisPtr)
180+
{
181+
pwmout_init(&thisPtr->_pwm, thisPtr->_pin);
182+
}
183+
167184
void PwmOut::init()
168185
{
169186
core_util_critical_section_enter();
170187

171188
if (!_initialized) {
172-
pwmout_init(&_pwm, _pin);
189+
190+
// Call either pwmout_init() or pwmout_init_direct(), depending on whether we have a PinName or a static pinmap
191+
_init_func(this);
192+
173193
lock_deep_sleep();
174194
_initialized = true;
175195
}

0 commit comments

Comments
 (0)