common_defines.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #pragma once
  2. #include <stdbool.h>
  3. #include <FreeRTOS.h>
  4. #include <task.h>
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. #include <cmsis_compiler.h>
  9. #ifndef MAX
  10. #define MAX(a, b) \
  11. ({ \
  12. __typeof__(a) _a = (a); \
  13. __typeof__(b) _b = (b); \
  14. _a > _b ? _a : _b; \
  15. })
  16. #endif
  17. #ifndef MIN
  18. #define MIN(a, b) \
  19. ({ \
  20. __typeof__(a) _a = (a); \
  21. __typeof__(b) _b = (b); \
  22. _a < _b ? _a : _b; \
  23. })
  24. #endif
  25. #ifndef ROUND_UP_TO
  26. #define ROUND_UP_TO(a, b) \
  27. ({ \
  28. __typeof__(a) _a = (a); \
  29. __typeof__(b) _b = (b); \
  30. _a / _b + !!(_a % _b); \
  31. })
  32. #endif
  33. #ifndef CLAMP
  34. #define CLAMP(x, upper, lower) (MIN(upper, MAX(x, lower)))
  35. #endif
  36. #ifndef COUNT_OF
  37. #define COUNT_OF(x) (sizeof(x) / sizeof(x[0]))
  38. #endif
  39. #ifndef FURI_SWAP
  40. #define FURI_SWAP(x, y) \
  41. do { \
  42. typeof(x) SWAP = x; \
  43. x = y; \
  44. y = SWAP; \
  45. } while(0)
  46. #endif
  47. #ifndef PLACE_IN_SECTION
  48. #define PLACE_IN_SECTION(x) __attribute__((section(x)))
  49. #endif
  50. #ifndef ALIGN
  51. #define ALIGN(n) __attribute__((aligned(n)))
  52. #endif
  53. #ifndef __weak
  54. #define __weak __attribute__((weak))
  55. #endif
  56. #ifndef UNUSED
  57. #define UNUSED(X) (void)(X)
  58. #endif
  59. #ifndef STRINGIFY
  60. #define STRINGIFY(x) #x
  61. #endif
  62. #ifndef TOSTRING
  63. #define TOSTRING(x) STRINGIFY(x)
  64. #endif
  65. #ifndef REVERSE_BYTES_U32
  66. #define REVERSE_BYTES_U32(x) \
  67. ((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \
  68. (((x)&0xFF000000) >> 24))
  69. #endif
  70. #ifndef FURI_BIT
  71. #define FURI_BIT(x, n) (((x) >> (n)) & 1)
  72. #endif
  73. #ifndef FURI_BIT_SET
  74. #define FURI_BIT_SET(x, n) ((x) |= (1 << (n)))
  75. #endif
  76. #ifndef FURI_BIT_CLEAR
  77. #define FURI_BIT_CLEAR(x, n) ((x) &= ~(1 << (n)))
  78. #endif
  79. #ifndef FURI_IS_IRQ_MASKED
  80. #define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
  81. #endif
  82. #ifndef FURI_IS_IRQ_MODE
  83. #define FURI_IS_IRQ_MODE() (__get_IPSR() != 0U)
  84. #endif
  85. #ifndef FURI_IS_ISR
  86. #define FURI_IS_ISR() (FURI_IS_IRQ_MODE() || FURI_IS_IRQ_MASKED())
  87. #endif
  88. #ifndef FURI_CRITICAL_ENTER
  89. #define FURI_CRITICAL_ENTER() \
  90. uint32_t __isrm = 0; \
  91. bool __from_isr = FURI_IS_ISR(); \
  92. bool __kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); \
  93. if(__from_isr) { \
  94. __isrm = taskENTER_CRITICAL_FROM_ISR(); \
  95. } else if(__kernel_running) { \
  96. taskENTER_CRITICAL(); \
  97. } else { \
  98. __disable_irq(); \
  99. }
  100. #endif
  101. #ifndef FURI_CRITICAL_EXIT
  102. #define FURI_CRITICAL_EXIT() \
  103. if(__from_isr) { \
  104. taskEXIT_CRITICAL_FROM_ISR(__isrm); \
  105. } else if(__kernel_running) { \
  106. taskEXIT_CRITICAL(); \
  107. } else { \
  108. __enable_irq(); \
  109. }
  110. #endif
  111. static inline bool furi_is_irq_context() {
  112. bool irq = false;
  113. BaseType_t state;
  114. if(FURI_IS_IRQ_MODE()) {
  115. /* Called from interrupt context */
  116. irq = true;
  117. } else {
  118. /* Get FreeRTOS scheduler state */
  119. state = xTaskGetSchedulerState();
  120. if(state != taskSCHEDULER_NOT_STARTED) {
  121. /* Scheduler was started */
  122. if(FURI_IS_IRQ_MASKED()) {
  123. /* Interrupts are masked */
  124. irq = true;
  125. }
  126. }
  127. }
  128. /* Return context, 0: thread context, 1: IRQ context */
  129. return (irq);
  130. }
  131. #ifdef __cplusplus
  132. }
  133. #endif