PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
4.1KB

  1. #ifndef __INC_ARBITER_NRF52
  2. #define __INC_ARBITER_NRF52
  3. #if defined(NRF52_SERIES)
  4. #include "led_sysdefs_arm_nrf52.h"
  5. //FASTLED_NAMESPACE_BEGIN
  6. typedef void (*FASTLED_NRF52_PWM_INTERRUPT_HANDLER)();
  7. // a trick learned from other embedded projects ..
  8. // use the enum as an index to a statically-allocated array
  9. // to store unique information for that instance.
  10. // also provides a count of how many instances were enabled.
  11. //
  12. // See led_sysdefs_arm_nrf52.h for selection....
  13. //
  14. typedef enum _FASTLED_NRF52_ENABLED_PWM_INSTANCE {
  15. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0)
  16. FASTLED_NRF52_PWM0_INSTANCE_IDX,
  17. #endif
  18. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1)
  19. FASTLED_NRF52_PWM1_INSTANCE_IDX,
  20. #endif
  21. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2)
  22. FASTLED_NRF52_PWM2_INSTANCE_IDX,
  23. #endif
  24. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3)
  25. FASTLED_NRF52_PWM3_INSTANCE_IDX,
  26. #endif
  27. FASTLED_NRF52_PWM_INSTANCE_COUNT
  28. } FASTLED_NRF52_ENABLED_PWM_INSTANCES;
  29. static_assert(FASTLED_NRF52_PWM_INSTANCE_COUNT > 0, "Instance count must be greater than zero -- define FASTLED_NRF52_ENABLE_PWM_INSTNACE[n] (replace `[n]` with digit)");
  30. template <uint32_t _PWM_ID>
  31. class PWM_Arbiter {
  32. private:
  33. static_assert(_PWM_ID < 32, "PWM_ID over 31 breaks current arbitration bitmask");
  34. //const uint32_t _ACQUIRE_MASK = (1u << _PWM_ID) ;
  35. //const uint32_t _CLEAR_MASK = ~((uint32_t)(1u << _PWM_ID));
  36. static uint32_t s_PwmInUse;
  37. static NRF_PWM_Type * const s_PWM;
  38. static IRQn_Type const s_PWM_IRQ;
  39. static FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile s_Isr;
  40. public:
  41. static void isr_handler() {
  42. return s_Isr();
  43. }
  44. FASTLED_NRF52_INLINE_ATTRIBUTE static bool isAcquired() {
  45. return (0u != (s_PwmInUse & 1u)); // _ACQUIRE_MASK
  46. }
  47. FASTLED_NRF52_INLINE_ATTRIBUTE static void acquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) {
  48. while (!tryAcquire(isr));
  49. }
  50. FASTLED_NRF52_INLINE_ATTRIBUTE static bool tryAcquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) {
  51. uint32_t oldValue = __sync_fetch_and_or(&s_PwmInUse, 1u); // _ACQUIRE_MASK
  52. if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK
  53. s_Isr = isr;
  54. return true;
  55. }
  56. return false;
  57. }
  58. FASTLED_NRF52_INLINE_ATTRIBUTE static void releaseFromIsr() {
  59. uint32_t oldValue = __sync_fetch_and_and(&s_PwmInUse, ~1u); // _CLEAR_MASK
  60. if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK
  61. // TODO: This should never be true... indicates was not held.
  62. // Assert here?
  63. (void)oldValue;
  64. }
  65. return;
  66. }
  67. FASTLED_NRF52_INLINE_ATTRIBUTE static NRF_PWM_Type * getPWM() {
  68. return s_PWM;
  69. }
  70. FASTLED_NRF52_INLINE_ATTRIBUTE static IRQn_Type getIRQn() { return s_PWM_IRQ; }
  71. };
  72. template <uint32_t _PWM_ID> NRF_PWM_Type * const PWM_Arbiter<_PWM_ID>::s_PWM =
  73. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0)
  74. (_PWM_ID == 0 ? NRF_PWM0 :
  75. #endif
  76. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1)
  77. (_PWM_ID == 1 ? NRF_PWM1 :
  78. #endif
  79. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2)
  80. (_PWM_ID == 2 ? NRF_PWM2 :
  81. #endif
  82. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3)
  83. (_PWM_ID == 3 ? NRF_PWM3 :
  84. #endif
  85. (NRF_PWM_Type*)-1
  86. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0)
  87. )
  88. #endif
  89. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1)
  90. )
  91. #endif
  92. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2)
  93. )
  94. #endif
  95. #if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3)
  96. )
  97. #endif
  98. ;
  99. template <uint32_t _PWM_ID> IRQn_Type const PWM_Arbiter<_PWM_ID>::s_PWM_IRQ = ((IRQn_Type)((uint8_t)((uint32_t)(s_PWM) >> 12)));
  100. template <uint32_t _PWM_ID> uint32_t PWM_Arbiter<_PWM_ID>::s_PwmInUse = 0;
  101. template <uint32_t _PWM_ID> FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile PWM_Arbiter<_PWM_ID>::s_Isr = NULL;
  102. //FASTLED_NAMESPACE_END
  103. #endif // NRF52_SERIES
  104. #endif // __INC_ARBITER_NRF52