Skip to content

Commit be9927e

Browse files
committed
Simplify by auto-detecting when called from ISR
Thanks to @hathach for recommendation: #496 (comment)
1 parent dd06e2f commit be9927e

File tree

3 files changed

+30
-22
lines changed

3 files changed

+30
-22
lines changed

cores/nRF5/HardwarePWM.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,34 @@ void HardwarePWM::DebugOutput(Stream& logger)
9797
// returns true ONLY when (1) no PWM channel has a pin, and (2) the owner token is nullptr
9898
bool HardwarePWM::takeOwnership(uintptr_t token)
9999
{
100+
bool notInIsr = !isInISR();
100101
if (token == 0) {
101-
LOG_LV1("HwPWM", "zero / nullptr is not a valid ownership token (attempted use in takeOwnership)");
102+
if (notInIsr) {
103+
LOG_LV1("HwPWM", "zero / nullptr is not a valid ownership token (attempted use in takeOwnership)");
104+
}
102105
return false; // cannot take ownership with nullptr
103106
}
104107
if (token == this->_owner_token) {
105-
LOG_LV1("HwPWM", "failing to acquire ownership because already owned by requesting token (cannot take ownership twice)");
108+
if (notInIsr) {
109+
LOG_LV1("HwPWM", "failing to acquire ownership because already owned by requesting token (cannot take ownership twice)");
110+
}
106111
}
107112
if (this->_owner_token != 0) {
108-
LOG_LV3("HwPWM", "failing to acquire ownership because already owned by other token");
113+
if (notInIsr) {
114+
LOG_LV3("HwPWM", "failing to acquire ownership because already owned by other token");
115+
}
109116
return false;
110117
}
111118
if (this->usedChannelCount() != 0) {
112-
LOG_LV3("HwPWM", "failing to acquire ownership because at least one channel connected");
119+
if (notInIsr) {
120+
LOG_LV3("HwPWM", "failing to acquire ownership because at least one channel connected");
121+
}
113122
return false;
114123
}
115124
if (this->enabled()) {
116-
LOG_LV3("HwPWM", "failing to acquire ownership because peripheral is already enabled");
125+
if (notInIsr) {
126+
LOG_LV3("HwPWM", "failing to acquire ownership because peripheral is already enabled");
127+
}
117128
return false;
118129
}
119130
// TODO: warn, but do not fail, if taking ownership with IRQs already enabled
@@ -126,20 +137,29 @@ bool HardwarePWM::takeOwnership(uintptr_t token)
126137
// returns true ONLY when (1) no PWM channel has a pin attached, and (2) the owner token matches
127138
bool HardwarePWM::releaseOwnership(uintptr_t token)
128139
{
140+
bool notInIsr = !isInISR();
129141
if (token == 0) {
130-
LOG_LV1("HwPWM", "zero / nullptr is not a valid ownership token (attempted use in releaseOwnership)");
142+
if (notInIsr) {
143+
LOG_LV1("HwPWM", "zero / nullptr is not a valid ownership token (attempted use in releaseOwnership)");
144+
}
131145
return false;
132146
}
133147
if (!this->isOwner(token)) {
134-
LOG_LV1("HwPWM", "attempt to release ownership when not the current owner");
148+
if (notInIsr) {
149+
LOG_LV1("HwPWM", "attempt to release ownership when not the current owner");
150+
}
135151
return false;
136152
}
137153
if (this->usedChannelCount() != 0) {
138-
LOG_LV1("HwPWM", "attempt to release ownership when at least on channel is still connected");
154+
if (notInIsr) {
155+
LOG_LV1("HwPWM", "attempt to release ownership when at least on channel is still connected");
156+
}
139157
return false;
140158
}
141159
if (this->enabled()) {
142-
LOG_LV1("HwPWM", "attempt to release ownership when PWM peripheral is still enabled");
160+
if (notInIsr) {
161+
LOG_LV1("HwPWM", "attempt to release ownership when PWM peripheral is still enabled");
162+
}
143163
return false; // if it's enabled, do not allow ownership to be released, even with no pins in use
144164
}
145165
// TODO: warn, but do not fail, if releasing ownership with IRQs enabled
@@ -153,16 +173,6 @@ bool HardwarePWM::releaseOwnership(uintptr_t token)
153173
}
154174
return result;
155175
}
156-
bool HardwarePWM::releaseOwnershipFromISR(uintptr_t token) {
157-
// Do not do any logging if called from ISR ...
158-
if (token == 0) return false; // cannot release ownership with nullptr
159-
if (!this->isOwner(token) ) return false; // don't even look at peripheral
160-
if ( this->usedChannelCount() != 0) return false; // fail if any channels still have pins
161-
if ( this->enabled() ) return false; // if it's enabled, do not allow ownership to be released, even with no pins in use
162-
// use gcc built-in intrinsic to ensure atomicity
163-
// See https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
164-
return __sync_bool_compare_and_swap(&(this->_owner_token), token, 0);
165-
}
166176

167177
HardwarePWM::HardwarePWM(NRF_PWM_Type* pwm) :
168178
_pwm(pwm)

cores/nRF5/HardwarePWM.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ class HardwarePWM
7474
bool takeOwnership (uintptr_t token);
7575
// returns true ONLY when (1) no PWM channel has a pin attached, and (2) the owner token matches
7676
bool releaseOwnership(uintptr_t token);
77-
// As above, but ensured safe to call from ISR
78-
bool releaseOwnershipFromISR(uintptr_t token);
7977

8078
// allows caller to verify that they own the peripheral
8179
__INLINE bool isOwner(uintptr_t token) const

cores/nRF5/Tone.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ void PWM2_IRQHandler(void){
156156
nrf_pwm_disable(NRF_PWM2);
157157
_PWMInstance->PSEL.OUT[0] = NRF_PWM_PIN_NOT_CONNECTED;
158158
NVIC_DisableIRQ(PWM2_IRQn);
159-
_HwPWM->releaseOwnershipFromISR(_toneToken);
159+
_HwPWM->releaseOwnership(_toneToken);
160160
} else {
161161
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
162162
}

0 commit comments

Comments
 (0)