util.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #ifndef MY_UTIL_H_
  2. #define MY_UTIL_H_
  3. #ifndef F_CPU
  4. # warning "F_CPU not defined"
  5. #endif
  6. #include <util/delay.h>
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include <stdbool.h>
  10. #include <avr/interrupt.h>
  11. #include <avr/pgmspace.h>
  12. #include <avr/cpufunc.h>
  13. #include <avr/eeprom.h>
  14. /* Return the smaller value of 'a' and 'b'. */
  15. #define min(a, b) ({ \
  16. __typeof__(a) __amin = (a); \
  17. __typeof__(b) __bmin = (b); \
  18. (__typeof__(a))(__amin < __bmin ? __amin : __bmin); \
  19. })
  20. /* Return the bigger value of 'a' and 'b'. */
  21. #define max(a, b) ({ \
  22. __typeof__(a) __amax = (a); \
  23. __typeof__(b) __bmax = (b); \
  24. (__typeof__(a))(__amax > __bmax ? __amax : __bmax); \
  25. })
  26. /* Return 'value' clamped inbetween 'min_val' and 'max_val'. */
  27. #define clamp(value, min_val, max_val) \
  28. max(min(value, max_val), min_val)
  29. /* Return the absolute value of 'val' */
  30. #undef abs
  31. #define abs(val) ({ \
  32. __typeof__(val) __val = (val); \
  33. __val >= 0 ? __val : -__val; \
  34. })
  35. /* Round an unsigned integer 'n' up to a multiple of 's'. */
  36. #define round_up(n, s) ((((n) + (s) - 1) / (s)) * (s))
  37. /* Perform a signed ceiling division of 'x' / 'd'. */
  38. #define sdiv_round_up(x, d) ({ \
  39. __typeof__(x) __r, __x = (x); \
  40. __typeof__(d) __d = (d); \
  41. if ((__x < 0) ^ (__d < 0)) \
  42. __r = __x / __d; \
  43. else if ((__x < 0) && (__d < 0)) \
  44. __r = (__x + __d + 1) / __d; \
  45. else \
  46. __r = (__x + __d - 1) / __d; \
  47. __r; \
  48. })
  49. /* Perform an unsigned ceiling division of 'x' / 'd'. */
  50. #define udiv_round_up(x, d) ({ \
  51. __typeof__(x) __x = (x); \
  52. __typeof__(d) __d = (d); \
  53. (__x + __d - 1) / __d; \
  54. })
  55. /* Divide signed integer x by signed integer d and
  56. * round to the closest result. */
  57. #define sdiv_round(x, d) ({ \
  58. __typeof__(x) __r, __x = (x); \
  59. __typeof__(d) __d = (d); \
  60. if ((__x < 0) ^ (__d < 0)) \
  61. __r = (__x - (__d / 2)) / __d; \
  62. else \
  63. __r = (__x + (__d / 2)) / __d; \
  64. __r; \
  65. })
  66. /* Divide unsigned integer x by unsigned integer d and
  67. * round to the closest result. */
  68. #define udiv_round(x, d) ({ \
  69. __typeof__(x) __x = (x); \
  70. __typeof__(d) __d = (d); \
  71. (__x + (__d / 2)) / __d; \
  72. })
  73. /* Swap values 'a' and 'b' in place.
  74. * Also checks whether 'a' and 'b' are of the same type. */
  75. #define swap_values(a, b) do { \
  76. __typeof__(a) __a = (a); \
  77. __typeof__(b) __b = (b); \
  78. __typeof__(a) __tmp = __a; \
  79. (void)((&__a) == (&__b)); \
  80. (a) = __b; \
  81. (b) = __tmp; \
  82. } while (0)
  83. /* Return the number of elements in a C array. */
  84. #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  85. /* Full memory barrier. */
  86. #define memory_barrier() __asm__ __volatile__("" : : : "memory")
  87. /* Do-not-inline function attribute. */
  88. #define noinline __attribute__((__noinline__))
  89. /* Pure-function attribute. */
  90. #define pure_fn __attribute__((__pure__))
  91. /* Const-function attribute. */
  92. #define const_fn __attribute__((__const__))
  93. /* Data structure packing attribute. */
  94. #define _packed __attribute__((__packed__))
  95. /* Naked functions. */
  96. #define _naked __attribute__((__naked__))
  97. /* Suppress 'unused' warnings. */
  98. #define _used __attribute__((__used__))
  99. /* Build-time assertion.
  100. * 'cond' must be a compile-time constant.
  101. * Build will fail, if 'cond' is false.
  102. */
  103. #define build_assert(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
  104. /* Code flow attributes */
  105. #define noreturn __attribute__((__noreturn__))
  106. #define _mainfunc __attribute__((__OS_main__))
  107. #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
  108. # define unreachable() __builtin_unreachable()
  109. #else
  110. # define unreachable() do {} while (1)
  111. #endif
  112. /* Mark branches as likely/unlikely. */
  113. #ifdef __GNUC__
  114. # define likely(cond) __builtin_expect(!!(cond), 1)
  115. # define unlikely(cond) __builtin_expect(!!(cond), 0)
  116. #else
  117. # define likely(cond) (!!(cond))
  118. # define unlikely(cond) (!!(cond))
  119. #endif
  120. /* Convert something to a string. */
  121. #define _tostr(x) #x
  122. #define tostr(x) _tostr(x)
  123. /* Non-standard integer types. */
  124. typedef __int24 int24_t;
  125. typedef __uint24 uint24_t;
  126. /* Disable interrupts globally. */
  127. static inline void irq_disable(void)
  128. {
  129. cli();
  130. memory_barrier();
  131. }
  132. /* Enable interrupts globally. */
  133. static inline void irq_enable(void)
  134. {
  135. memory_barrier();
  136. sei();
  137. }
  138. /* Save flags and disable interrupts globally. */
  139. static inline uint8_t irq_disable_save(void)
  140. {
  141. uint8_t sreg = SREG;
  142. cli();
  143. memory_barrier();
  144. return sreg;
  145. }
  146. /* Restore interrupt flags. */
  147. static inline void irq_restore(uint8_t sreg_flags)
  148. {
  149. memory_barrier();
  150. SREG = sreg_flags;
  151. }
  152. /* Check whether the interrupt-enable flag is set in 'sreg_flags' */
  153. static inline bool __irqs_enabled(uint8_t sreg_flags)
  154. {
  155. return !!(sreg_flags & (1 << SREG_I));
  156. }
  157. /* Check whether interrupts are enabled globally. */
  158. static inline bool irqs_enabled(void)
  159. {
  160. return __irqs_enabled(SREG);
  161. }
  162. /* Indirect special function register access. */
  163. typedef uint16_t sfr_addr_t;
  164. #define SFR_ADDR(sfr) _SFR_ADDR(sfr)
  165. #define SFR_BYTE(sfr_addr) _MMIO_BYTE(sfr_addr)
  166. #endif /* MY_UTIL_H_ */