@@ -75,10 +75,8 @@ void HardwarePWM::DebugOutput(Stream& logger)
75
75
logger.printf (" || %d:" , i);
76
76
if (can_stringify_token (token)) {
77
77
uint8_t * t = (uint8_t *)(&token);
78
- static_assert (sizeof (uintptr_t ) == 4 );
79
78
logger.printf (" \" %c%c%c%c\" " , t[0 ], t[1 ], t[2 ], t[3 ] );
80
79
} else {
81
- static_assert (sizeof (uintptr_t ) == 4 );
82
80
logger.printf (" %08x" , token);
83
81
}
84
82
for (size_t j = 0 ; j < MAX_CHANNELS; j++) {
@@ -96,76 +94,6 @@ void HardwarePWM::DebugOutput(Stream& logger)
96
94
void HardwarePWM::DebugOutput (Stream& logger) {}
97
95
#endif // CFG_DEBUG
98
96
99
- // returns true ONLY when (1) no PWM channel has a pin, and (2) the owner token is nullptr
100
- bool HardwarePWM::takeOwnership (uintptr_t token)
101
- {
102
- bool notInIsr = !isInISR ();
103
- if (token == 0 ) {
104
- if (notInIsr) {
105
- LOG_LV1 (" HwPWM" , " zero / nullptr is not a valid ownership token (attempted use in takeOwnership)" );
106
- }
107
- return false ; // cannot take ownership with nullptr
108
- }
109
- if (token == this ->_owner_token ) {
110
- if (notInIsr) {
111
- LOG_LV1 (" HwPWM" , " failing to acquire ownership because already owned by requesting token (cannot take ownership twice)" );
112
- }
113
- }
114
- if (this ->_owner_token != 0 ) {
115
- return false ;
116
- }
117
- if (this ->usedChannelCount () != 0 ) {
118
- return false ;
119
- }
120
- if (this ->enabled ()) {
121
- return false ;
122
- }
123
- // TODO: warn, but do not fail, if taking ownership with IRQs already enabled
124
- // NVIC_GetActive
125
-
126
- // Use C++11 atomic CAS operation
127
- uintptr_t newValue = 0U ;
128
- return this ->_owner_token .compare_exchange_strong (newValue, token);
129
- }
130
- // returns true ONLY when (1) no PWM channel has a pin attached, and (2) the owner token matches
131
- bool HardwarePWM::releaseOwnership (uintptr_t token)
132
- {
133
- bool notInIsr = !isInISR ();
134
- if (token == 0 ) {
135
- if (notInIsr) {
136
- LOG_LV1 (" HwPWM" , " zero / nullptr is not a valid ownership token (attempted use in releaseOwnership)" );
137
- }
138
- return false ;
139
- }
140
- if (!this ->isOwner (token)) {
141
- if (notInIsr) {
142
- LOG_LV1 (" HwPWM" , " attempt to release ownership when not the current owner" );
143
- }
144
- return false ;
145
- }
146
- if (this ->usedChannelCount () != 0 ) {
147
- if (notInIsr) {
148
- LOG_LV1 (" HwPWM" , " attempt to release ownership when at least on channel is still connected" );
149
- }
150
- return false ;
151
- }
152
- if (this ->enabled ()) {
153
- if (notInIsr) {
154
- LOG_LV1 (" HwPWM" , " attempt to release ownership when PWM peripheral is still enabled" );
155
- }
156
- return false ; // if it's enabled, do not allow ownership to be released, even with no pins in use
157
- }
158
- // TODO: warn, but do not fail, if releasing ownership with IRQs enabled
159
- // NVIC_GetActive
160
-
161
- // Use C++11 atomic CAS operation
162
- bool result = this ->_owner_token .compare_exchange_strong (token, 0U );
163
- if (!result) {
164
- LOG_LV1 (" HwPWM" , " race condition resulted in failure to acquire ownership" );
165
- }
166
- return result;
167
- }
168
-
169
97
HardwarePWM::HardwarePWM (NRF_PWM_Type* pwm) :
170
98
_pwm(pwm)
171
99
{
@@ -350,3 +278,72 @@ uint8_t HardwarePWM::freeChannelCount(void) const
350
278
return MAX_CHANNELS - usedChannelCount ();
351
279
}
352
280
281
+ // returns true ONLY when (1) no PWM channel has a pin, and (2) the owner token is nullptr
282
+ bool HardwarePWM::takeOwnership (uintptr_t token)
283
+ {
284
+ if (token == 0 ) {
285
+ LOG_LV1 (" HwPWM" , " zero / nullptr is not a valid ownership token (attempted use in takeOwnership)" );
286
+ return false ;
287
+ }
288
+
289
+ if (token == this ->_owner_token ) {
290
+ LOG_LV1 (" HwPWM" , " failing to acquire ownership because already owned by requesting token (cannot take ownership twice)" );
291
+ return false ;
292
+ }
293
+
294
+ if (this ->_owner_token != 0 ) return false ;
295
+ if (this ->usedChannelCount () != 0 ) return false ;
296
+ if (this ->enabled ()) return false ;
297
+
298
+ if (isInISR ())
299
+ {
300
+ UBaseType_t intr_status = taskENTER_CRITICAL_FROM_ISR ();
301
+ _owner_token = token;
302
+ taskEXIT_CRITICAL_FROM_ISR (intr_status);
303
+ }else
304
+ {
305
+ taskENTER_CRITICAL ();
306
+ _owner_token = token;
307
+ taskEXIT_CRITICAL ();
308
+ }
309
+
310
+ return true ;
311
+ }
312
+
313
+ // returns true ONLY when (1) no PWM channel has a pin attached, and (2) the owner token matches
314
+ bool HardwarePWM::releaseOwnership (uintptr_t token)
315
+ {
316
+ if (token == 0 ) {
317
+ LOG_LV1 (" HwPWM" , " zero / nullptr is not a valid ownership token (attempted use in releaseOwnership)" );
318
+ return false ;
319
+ }
320
+
321
+ if (!this ->isOwner (token)) {
322
+ LOG_LV1 (" HwPWM" , " attempt to release ownership when not the current owner" );
323
+ return false ;
324
+ }
325
+
326
+ if (this ->usedChannelCount () != 0 ) {
327
+ LOG_LV1 (" HwPWM" , " attempt to release ownership when at least on channel is still connected" );
328
+ return false ;
329
+ }
330
+
331
+ if (this ->enabled ()) {
332
+ LOG_LV1 (" HwPWM" , " attempt to release ownership when PWM peripheral is still enabled" );
333
+ return false ; // if it's enabled, do not allow ownership to be released, even with no pins in use
334
+ }
335
+
336
+ if (isInISR ())
337
+ {
338
+ UBaseType_t intr_status = taskENTER_CRITICAL_FROM_ISR ();
339
+ _owner_token = 0 ;
340
+ taskEXIT_CRITICAL_FROM_ISR (intr_status);
341
+ }else
342
+ {
343
+ taskENTER_CRITICAL ();
344
+ _owner_token = 0 ;
345
+ taskEXIT_CRITICAL ();
346
+ }
347
+
348
+ return true ;
349
+ }
0 commit comments