/** * \file util.h * \brief Hilfsfunktionen */ #ifndef MY_UTIL_H_ #define MY_UTIL_H_ #ifndef F_CPU # error "F_CPU not defined" #endif #include #include #include #include #include #include #include /** \brief Gibt den kleinsten Wert der Parameter a und b zurueck. */ #define min(a, b) ({ \ __typeof__(a) __amin = (a); \ __typeof__(b) __bmin = (b); \ (__typeof__(a))(__amin < __bmin ? __amin : __bmin); \ }) /** \brief Gibt den groessten Wert der Parameter a und b zurueck. */ #define max(a, b) ({ \ __typeof__(a) __amax = (a); \ __typeof__(b) __bmax = (b); \ (__typeof__(a))(__amax > __bmax ? __amax : __bmax); \ }) /** \brief Begrenzt value zwischen min_val und max_val. */ #define clamp(value, min_val, max_val) \ max(min(value, max_val), min_val) #undef abs /** \brief Gibt den Absolutwert des val Parameters zurueck. */ #define abs(val) ({ \ __typeof__(val) __val = (val); \ __val >= 0 ? __val : -__val; \ }) /** \brief n auf ein Vielfaches von s aufrunden. */ #define round_up(n, s) ((((n) + (s) - 1) / (s)) * (s)) /** \brief x durch d teilen und aufrunden. */ #define div_round_up(x, d) (((x) + (d) - 1) / (d)) /** \brief Einen 8-Bit-Bitindex in eine 8-Bit-Bitmaske konvertieren. */ extern const uint8_t bit2mask_lt[]; #define BITMASK8(bitnr) \ (__builtin_constant_p(bitnr) ? \ (1u << (bitnr)) : \ bit2mask_lt[(bitnr)]) /** \brief Gibt die Groesse eines Arrays in Anzahl der Elemente zurueck. */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /** \brief Memory barrier. * Schraenkt die Compileroptimierung ueber den Aufrufspunkt * hinweg ein. */ #define mb() __asm__ __volatile__("" : : : "memory") #define noinline __attribute__((__noinline__)) /** \brief Interrupts global deaktivieren. * * Deaktiviert Interrupts und fuehrt eine Memory-Barrier durch. */ static inline void irq_disable(void) { cli(); mb(); } /** \brief Interrupts global aktivieren. * * Fuehrt eine Memory-Barrier durch und aktiviert Interrupts global. */ static inline void irq_enable(void) { mb(); sei(); } /** \brief Interrupts global deaktivieren und Status zurueckgeben. * * Deaktiviert Interrupts und fuehrt eine Memory-Barrier durch. * Gibt das vorherige SREG zurueck. */ static inline uint8_t irq_disable_save(void) { uint8_t sreg = SREG; cli(); mb(); return sreg; } /** \brief Interrupts wiederherstellen. * * Fuehrt eine Memory-Barrier durch und stellt Interrupts wieder her. */ static inline void irq_restore(uint8_t sreg_flags) { mb(); SREG = sreg_flags; } #endif /* MY_UTIL_H_ */