1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#ifndef UTIL_H_
#define UTIL_H_
#include "compat.h"
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <string.h>
/* Return the smaller value of 'a' and 'b'. */
#define min(a, b) ({ \
__typeof__(a) __amin = (a); \
__typeof__(b) __bmin = (b); \
(__typeof__(a))(__amin < __bmin ? __amin : __bmin); \
})
/* Return the bigger value of 'a' and 'b'. */
#define max(a, b) ({ \
__typeof__(a) __amax = (a); \
__typeof__(b) __bmax = (b); \
(__typeof__(a))(__amax > __bmax ? __amax : __bmax); \
})
/* Return 'value' clamped inbetween 'min_val' and 'max_val'. */
#define clamp(value, min_val, max_val) \
max(min(value, max_val), min_val)
/* Limit an unsigned integer to uint8_t/uint16_t range. */
#define lim_u8(v) ((uint8_t)clamp((v), (__typeof__(v))0, (__typeof__(v))UINT8_MAX))
#define lim_u16(v) ((uint16_t)clamp((v), (__typeof__(v))0, (__typeof__(v))UINT16_MAX))
/* Return the absolute value of 'val' */
#undef abs
#define abs(val) ({ \
__typeof__(val) __val = (val); \
__val >= 0 ? __val : -__val; \
})
/* Get the number of elements in a C array. */
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
/* Memory barrier. */
#define memory_barrier() __asm__ __volatile__("" : : : "memory")
/* Do-not-inline function attribute. */
#define noinline __attribute__((__noinline__))
/* Always-inline function attribute. */
#define alwaysinline inline __attribute__((__always_inline__))
/* Packed structure. */
#define _packed __attribute__((__packed__))
/* Build-time assertion.
* 'cond' must be a compile-time constant.
* Build will fail, if 'cond' is false.
*/
#define build_assert(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
/* Code flow attributes */
#define noreturn __attribute__((__noreturn__))
#define _mainfunc __attribute__((__OS_main__))
#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
# define unreachable() __builtin_unreachable()
#else
# define unreachable() while (1)
#endif
/* Code section attributes */
#define section_init3 __attribute__((naked, used, section(".init3")))
/* Data section attributes */
#define section_noinit __attribute__((section(".noinit")))
/* Disable interrupts globally. */
static alwaysinline void irq_disable(void)
{
cli();
memory_barrier();
}
/* Enable interrupts globally. */
static alwaysinline void irq_enable(void)
{
memory_barrier();
sei();
}
/* Save flags and disable interrupts globally. */
static alwaysinline uint8_t irq_disable_save(void)
{
uint8_t sreg = SREG;
irq_disable();
return sreg;
}
/* Restore interrupt flags. */
static alwaysinline void irq_restore(uint8_t sreg_flags)
{
memory_barrier();
SREG = sreg_flags;
}
#endif /* UTIL_H_ */
|