| 41 | |
| 42 | template <fl::u32 _PWM_ID> |
| 43 | class PWM_Arbiter { |
| 44 | private: |
| 45 | FL_STATIC_ASSERT(_PWM_ID < 32, "PWM_ID over 31 breaks current arbitration bitmask"); |
| 46 | //const uint32_t _ACQUIRE_MASK = (1u << _PWM_ID) ; |
| 47 | //const uint32_t _CLEAR_MASK = ~((uint32_t)(1u << _PWM_ID)); |
| 48 | static fl::u32 s_PwmInUse; |
| 49 | static NRF_PWM_Type * const s_PWM; |
| 50 | static IRQn_Type const s_PWM_IRQ; |
| 51 | static FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile s_Isr; |
| 52 | |
| 53 | public: |
| 54 | static void isr_handler() FL_NOEXCEPT { |
| 55 | return s_Isr(); |
| 56 | } |
| 57 | FASTLED_NRF52_INLINE_ATTRIBUTE static bool isAcquired() FL_NOEXCEPT { |
| 58 | return (0u != (s_PwmInUse & 1u)); // _ACQUIRE_MASK |
| 59 | } |
| 60 | FASTLED_NRF52_INLINE_ATTRIBUTE static void acquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) FL_NOEXCEPT { |
| 61 | while (!tryAcquire(isr)); |
| 62 | } |
| 63 | FASTLED_NRF52_INLINE_ATTRIBUTE static bool tryAcquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) FL_NOEXCEPT { |
| 64 | fl::u32 oldValue = __sync_fetch_and_or(&s_PwmInUse, 1u); // _ACQUIRE_MASK |
| 65 | if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK |
| 66 | s_Isr = isr; |
| 67 | return true; |
| 68 | } |
| 69 | return false; |
| 70 | } |
| 71 | FASTLED_NRF52_INLINE_ATTRIBUTE static void releaseFromIsr() FL_NOEXCEPT { |
| 72 | fl::u32 oldValue = __sync_fetch_and_and(&s_PwmInUse, ~1u); // _CLEAR_MASK |
| 73 | if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK |
| 74 | // TODO: This should never be true... indicates was not held. |
| 75 | // Assert here? |
| 76 | (void)oldValue; |
| 77 | } |
| 78 | return; |
| 79 | } |
| 80 | FASTLED_NRF52_INLINE_ATTRIBUTE static NRF_PWM_Type * getPWM() FL_NOEXCEPT { |
| 81 | return s_PWM; |
| 82 | } |
| 83 | FASTLED_NRF52_INLINE_ATTRIBUTE static IRQn_Type getIRQn() { return s_PWM_IRQ; } |
| 84 | }; |
| 85 | template <fl::u32 _PWM_ID> NRF_PWM_Type * const PWM_Arbiter<_PWM_ID>::s_PWM = |
| 86 | #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0) |