util.h 4.6 KB

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