-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathutils.h
156 lines (131 loc) · 5.07 KB
/
utils.h
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma once
#include <stdlib.h>
#include <libopencm3/cm3/dwt.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#ifdef STM32F1
#define U_ID_PTR (0x1FFFF7E8)
#define U_ID_0 (*(uint32_t *)(U_ID_PTR))
#define U_ID_1 (*(uint32_t *)(U_ID_PTR + 4))
#define U_ID_2 (*(uint32_t *)(U_ID_PTR + 8))
#else
#define U_ID_0 0xFFFFFFFF
#define U_ID_1 0xFFFFFFFF
#define U_ID_2 0xFFFFFFFF
#endif
#ifndef LED_INDICATOR
#define LED_INDICATOR 1
#endif
typedef struct {
uint32_t port;
uint16_t gpio;
} pin;
typedef struct {
// pin to monitor
pin pin;
// internal counter
uint16_t cnt;
// threshold - when `cnt` will reach this value, new state will be updated
uint16_t threshold;
// current state
bool state;
// last known state - this value is set by external app, debounce functions
// won't touch it
bool known_state;
} debounce;
typedef enum {
E_SUCCESS = 0,
// returned when a pointer was expected but it was empty
E_NULL_PTR,
// returned when provided argument has incorrect value
E_VALUE_INVALID,
// problem with I2C communication
E_I2C_TIMEOUT,
// returned when value is too big
E_VALUE_TOO_BIG,
// other error, unspecified
E_UNSPECIFIED = 255,
} error_t;
// Set precision for systick (low = 100 ms, medium = 10 ms, high = 1 ms)
#define PRECISION_LOW 0
#define PRECISION_MEDIUM 1
#define PRECISION_HIGH 2
#define sizeof_a(a) (sizeof(a) / sizeof(a[0]))
void hacf(void) __attribute__((__noreturn__));
// void rtc_setup(void);
void systick_setup(uint8_t precision);
uint32_t get_system_millis(void);
void delay_ms(uint32_t time);
void led_init(void);
void led_toggle(void);
void led_set(bool new_state);
void setup_delay_timer(uint32_t timer);
void delay_us(uint32_t timer, uint16_t us);
void trace_init(void);
#define trace_start() (DWT_CYCCNT = 0)
#define trace_stop() (DWT_CYCCNT)
error_t debounce_init(debounce *config, const pin *pin, uint16_t threshold);
error_t debounce_get_state(debounce *config);
uint8_t sadd8(uint8_t a, uint8_t b);
uint16_t sadd16(uint16_t a, uint16_t b);
uint32_t sadd32(uint32_t a, uint32_t b);
/**
* Saturated add and sub
*/
#define sadd(a, b) \
_Generic((a), uint8_t : sadd8, uint16_t : sadd16, uint32_t : sadd32)(a, b)
#define ssub(a, b) \
({ \
__typeof__(a) _c = a > b ? a - b : 0; \
_c; \
})
uint8_t check_bit(uint32_t variable, uint8_t pos);
int32_t fast_int_pow(int32_t base, uint32_t exponent);
#define fast_abs(x) \
_Generic((x), int8_t \
: fast_abs8, int16_t \
: fast_abs16, int32_t \
: fast_abs32, int \
: fast_abs32)(x)
inline uint8_t fast_abs8(int8_t i) {
if (i < 0)
i = -i;
return (uint8_t)i;
}
inline uint16_t fast_abs16(int16_t i) {
if (i < 0)
i = -i;
return (uint16_t)i;
}
inline uint32_t fast_abs32(int32_t i) {
if (i < 0)
i = -i;
return (uint32_t)i;
}
#define check_error(e) \
do { \
if (e != E_SUCCESS) { \
return e; \
} \
} while (0)
#define halt_on_error(e) \
do { \
if (e != E_SUCCESS) { \
hacf(); \
} \
} while (0)
#define max(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define min(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})