File tree Expand file tree Collapse file tree 2 files changed +32
-0
lines changed Expand file tree Collapse file tree 2 files changed +32
-0
lines changed Original file line number Diff line number Diff line change @@ -53,6 +53,25 @@ HardwarePWM* HwPWMx[] =
53
53
#endif
54
54
};
55
55
56
+ // returns true ONLY when (1) no PWM channel has a pin, and (2) the owner token is nullptr
57
+ bool HardwarePWM::takeOwnership (uintptr_t token)
58
+ {
59
+ if (this ->_owner_token != 0 ) return false ; // doesn't matter if it's actually a match ... it's not legal to take ownership twice
60
+ if (this ->usedChannelCount () != 0 ) return false ; // at least one channel is already in use
61
+ // use gcc built-in intrinsic to ensure atomicity
62
+ // See https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
63
+ return __sync_bool_compare_and_swap (&(this ->_owner_token ), 0 , token);
64
+ }
65
+ // returns true ONLY when (1) no PWM channel has a pin attached, and (2) the owner token matches
66
+ bool HardwarePWM::releaseOwnership (uintptr_t token)
67
+ {
68
+ if (!this ->isOwner (token) ) return false ; // don't even look at peripheral
69
+ if ( this ->usedChannelCount () != 0 ) return false ; // fail if any channels still have pins
70
+ // use gcc built-in intrinsic to ensure atomicity
71
+ // See https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
72
+ return __sync_bool_compare_and_swap (&(this ->_owner_token ), token, 0 );
73
+ }
74
+
56
75
HardwarePWM::HardwarePWM (NRF_PWM_Type* pwm)
57
76
{
58
77
_pwm = pwm;
Original file line number Diff line number Diff line change @@ -50,6 +50,7 @@ class HardwarePWM
50
50
private:
51
51
enum { MAX_CHANNELS = 4 }; // Max channel per group
52
52
NRF_PWM_Type* _pwm;
53
+ uintptr_t _owner_token = 0 ;
53
54
54
55
uint16_t _seq0[MAX_CHANNELS];
55
56
@@ -67,6 +68,18 @@ class HardwarePWM
67
68
68
69
void setClockDiv (uint8_t div); // value is PWM_PRESCALER_PRESCALER_DIV_x, DIV1 is 16Mhz
69
70
71
+ // Cooperative ownership sharing
72
+
73
+ // returns true ONLY when (1) no PWM channel has a pin, and (2) the owner token is nullptr
74
+ bool takeOwnership (uintptr_t token);
75
+ // returns true ONLY when (1) no PWM channel has a pin attached, and (2) the owner token matches
76
+ bool releaseOwnership (uintptr_t token);
77
+ // allows caller to verify that they own the peripheral
78
+ __INLINE bool isOwner (uintptr_t token) __attribute__((__always_inline__))
79
+ {
80
+ return this ->_owner_token == token;
81
+ }
82
+
70
83
bool addPin (uint8_t pin);
71
84
bool removePin (uint8_t pin);
72
85
You can’t perform that action at this time.
0 commit comments