amiro-blt / Target / Source / helper.c @ ec50c96e
History | View | Annotate | Download (10.488 KB)
1 |
#include "helper.h" |
---|---|
2 |
|
3 |
#include "blt_conf.h" |
4 |
|
5 |
/*
|
6 |
* Initialized the system timer.
|
7 |
*/
|
8 |
void saTimerInit(void) { |
9 |
/* reset the timer configuration */
|
10 |
saTimerReset(); |
11 |
|
12 |
/* configure the systick frequency as a 1 ms event generator */
|
13 |
SysTick->LOAD = BOOT_CPU_SYSTEM_SPEED_KHZ - 1;
|
14 |
/* reset the current counter value */
|
15 |
SysTick->VAL = 0;
|
16 |
/* select core clock as source and enable the timer */
|
17 |
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; |
18 |
} |
19 |
|
20 |
/*
|
21 |
* Resets the systick status of the system timer.
|
22 |
*/
|
23 |
void saTimerReset(void) { |
24 |
/* set the systick's status and control register back into the default reset value */
|
25 |
SysTick->CTRL = 0;
|
26 |
} |
27 |
|
28 |
/*
|
29 |
* Updates the given timer variable.
|
30 |
* More specifically, the given variable in incremented if a millisecond event occurred.
|
31 |
*/
|
32 |
void saTimerUpdate(uint32_t* millisecond_counter) {
|
33 |
/* check if the millisecond event occurred */
|
34 |
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0) |
35 |
{ |
36 |
/* increment the millisecond counter */
|
37 |
++(*millisecond_counter); |
38 |
} |
39 |
|
40 |
return;
|
41 |
} |
42 |
|
43 |
/*
|
44 |
* Actively polls the standalone timer until the specified time has passed.
|
45 |
*/
|
46 |
void msleep(uint32_t ms)
|
47 |
{ |
48 |
uint32_t current; |
49 |
saTimerUpdate(¤t); |
50 |
uint32_t end = current + ms; |
51 |
|
52 |
while (current < end)
|
53 |
{ |
54 |
saTimerUpdate(¤t); |
55 |
} |
56 |
|
57 |
return;
|
58 |
} |
59 |
|
60 |
/*
|
61 |
* Actively reads the specified GPIO until it has the specified state.
|
62 |
*/
|
63 |
void waitForSignal(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction state) {
|
64 |
/* check whether the signal has been set */
|
65 |
while (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) != state) {
|
66 |
continue;
|
67 |
} |
68 |
return;
|
69 |
} |
70 |
|
71 |
/*
|
72 |
* Actively reads the specified GPIO until it has the specified state, or the specified time has passed.
|
73 |
*/
|
74 |
uint8_t waitForSignalTimeout(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction state, uint32_t timeout_ms) { |
75 |
uint32_t current_time; |
76 |
saTimerUpdate(¤t_time); |
77 |
uint32_t timeout_time = current_time + timeout_ms; |
78 |
while ((GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) != state) &&
|
79 |
(current_time < timeout_time)) { |
80 |
saTimerUpdate(¤t_time); |
81 |
} |
82 |
if (current_time < timeout_time) {
|
83 |
return 1; |
84 |
} else {
|
85 |
return 0; |
86 |
} |
87 |
} |
88 |
|
89 |
/*
|
90 |
* Turns the board LED or or off respectively.
|
91 |
* If the argument is zero, the LED is switched off.
|
92 |
* If the argument is not zero, the LED is switched on.
|
93 |
*/
|
94 |
void setLed(uint8_t on) {
|
95 |
|
96 |
#if defined(LED_GPIO) && defined(LED_PIN)
|
97 |
if (on == 0) { |
98 |
GPIO_SetBits(LED_GPIO, LED_PIN); |
99 |
} else {
|
100 |
GPIO_ResetBits(LED_GPIO, LED_PIN); |
101 |
} |
102 |
#endif
|
103 |
|
104 |
return;
|
105 |
} |
106 |
|
107 |
/*
|
108 |
* Makes the LED blink 'SOS' in morese code (... --- ...).
|
109 |
* If the specified number of loops is zero, the function will loop infinitely.
|
110 |
*/
|
111 |
void blinkSOS(uint32_t loops) {
|
112 |
/* initialize some variables and constants */
|
113 |
enum State {BLINK_ERROR_S1,
|
114 |
BLINK_ERROR_O, |
115 |
BLINK_ERROR_S2, |
116 |
BLINK_ERROR_BREAK |
117 |
} state = BLINK_ERROR_S1; |
118 |
uint8_t led = 0;
|
119 |
uint32_t loop = 0;
|
120 |
const uint32_t sigS = 50; |
121 |
const uint32_t sigL = 200; |
122 |
const uint32_t sigB = 100; |
123 |
const uint32_t letterBreakTime = 200; |
124 |
const uint32_t wordBreakTime = 1000; |
125 |
uint32_t stateStartTime = 0;
|
126 |
saTimerUpdate(&stateStartTime); |
127 |
uint32_t currentTime = stateStartTime; |
128 |
|
129 |
/* either loop the specified number, or infinitely */
|
130 |
while (loop < loops || loops == 0) { |
131 |
/* make the LED blink "SOS" (morse code: ... --- ...)*/
|
132 |
led = 0;
|
133 |
saTimerUpdate(¤tTime); |
134 |
switch (state) {
|
135 |
case BLINK_ERROR_S1:
|
136 |
case BLINK_ERROR_S2:
|
137 |
{ |
138 |
if (currentTime < stateStartTime + sigS) {
|
139 |
led = 1;
|
140 |
} else if (currentTime < stateStartTime + sigS+sigB) { |
141 |
led = 0;
|
142 |
} else if (currentTime < stateStartTime + sigS+sigB+sigS) { |
143 |
led = 1;
|
144 |
} else if (currentTime < stateStartTime + sigS+sigB+sigS+sigB) { |
145 |
led = 0;
|
146 |
} else if (currentTime < stateStartTime + sigS+sigB+sigS+sigB+sigS) { |
147 |
led = 1;
|
148 |
} else if (currentTime < stateStartTime + sigS+sigB+sigS+sigB+sigS+letterBreakTime) { |
149 |
led = 0;
|
150 |
} else {
|
151 |
if (state == BLINK_ERROR_S1) {
|
152 |
state = BLINK_ERROR_O; |
153 |
} else {
|
154 |
state = BLINK_ERROR_BREAK; |
155 |
++loop; |
156 |
} |
157 |
stateStartTime = currentTime; |
158 |
} |
159 |
break;
|
160 |
} |
161 |
case BLINK_ERROR_O:
|
162 |
{ |
163 |
if (currentTime < stateStartTime + sigL) {
|
164 |
led = 1;
|
165 |
} else if (currentTime < stateStartTime + sigL+sigB) { |
166 |
led = 0;
|
167 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL) { |
168 |
led = 1;
|
169 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL+sigB) { |
170 |
led = 0;
|
171 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL+sigB+sigL) { |
172 |
led = 1;
|
173 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL+sigB+sigL+letterBreakTime) { |
174 |
led = 0;
|
175 |
} else {
|
176 |
state = BLINK_ERROR_S2; |
177 |
stateStartTime = currentTime; |
178 |
} |
179 |
break;
|
180 |
} |
181 |
case BLINK_ERROR_BREAK:
|
182 |
{ |
183 |
if (currentTime >= stateStartTime + wordBreakTime) {
|
184 |
state = BLINK_ERROR_S1; |
185 |
stateStartTime = currentTime; |
186 |
} |
187 |
break;
|
188 |
} |
189 |
} |
190 |
|
191 |
setLed(led); |
192 |
} |
193 |
|
194 |
return;
|
195 |
} |
196 |
|
197 |
/*
|
198 |
* Shortcut to make the LED blink SOS infinitely.
|
199 |
*/
|
200 |
inline void blinkSOSinf() { |
201 |
blinkSOS(0);
|
202 |
return;
|
203 |
} |
204 |
|
205 |
/*
|
206 |
* Makes the LED blink 'OK' in morese code (... -.-).
|
207 |
* If the specified number of loops is zero, the function will loop infinitely.
|
208 |
*/
|
209 |
void blinkOK(uint32_t loops) {
|
210 |
/* initialize some variables and constants */
|
211 |
enum State {BLINK_SUCCESS_O,
|
212 |
BLINK_SUCCESS_K, |
213 |
BLINK_SUCCESS_BREAK |
214 |
} state = BLINK_SUCCESS_O; |
215 |
uint8_t led = 0;
|
216 |
uint32_t loop = 0;
|
217 |
const uint32_t sigS = 50; |
218 |
const uint32_t sigL = 200; |
219 |
const uint32_t sigB = 100; |
220 |
const uint32_t letterBreakTime = 200; |
221 |
const uint32_t wordBreakTime = 1000; |
222 |
uint32_t stateStartTime = 0;
|
223 |
saTimerUpdate(&stateStartTime); |
224 |
uint32_t currentTime = stateStartTime; |
225 |
|
226 |
/* either loop the specified number, or infinitely */
|
227 |
while (loop < loops || loops == 0) |
228 |
{ |
229 |
/* make the LED blink "OK" (morse code: --- -.-)*/
|
230 |
led = 0;
|
231 |
saTimerUpdate(¤tTime); |
232 |
switch (state) {
|
233 |
case BLINK_SUCCESS_O:
|
234 |
{ |
235 |
if (currentTime < stateStartTime + sigL) {
|
236 |
led = 1;
|
237 |
} else if (currentTime < stateStartTime + sigL+sigB) { |
238 |
led = 0;
|
239 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL) { |
240 |
led = 1;
|
241 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL+sigB) { |
242 |
led = 0;
|
243 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL+sigB+sigL) { |
244 |
led = 1;
|
245 |
} else if (currentTime < stateStartTime + sigL+sigB+sigL+sigB+sigL+letterBreakTime) { |
246 |
led = 0;
|
247 |
} else {
|
248 |
state = BLINK_SUCCESS_K; |
249 |
stateStartTime = currentTime; |
250 |
} |
251 |
break;
|
252 |
} |
253 |
case BLINK_SUCCESS_K:
|
254 |
{ |
255 |
if (currentTime < stateStartTime + sigL) {
|
256 |
led = 1;
|
257 |
} else if (currentTime < stateStartTime + sigL+sigB) { |
258 |
led = 0;
|
259 |
} else if (currentTime < stateStartTime + sigL+sigB+sigS) { |
260 |
led = 1;
|
261 |
} else if (currentTime < stateStartTime + sigL+sigB+sigS+sigB) { |
262 |
led = 0;
|
263 |
} else if (currentTime < stateStartTime + sigL+sigB+sigS+sigB+sigL) { |
264 |
led = 1;
|
265 |
} else if (currentTime < stateStartTime + sigL+sigB+sigS+sigB+sigL+letterBreakTime) { |
266 |
led = 0;
|
267 |
} else {
|
268 |
state = BLINK_SUCCESS_BREAK; |
269 |
++loop; |
270 |
stateStartTime = currentTime; |
271 |
} |
272 |
break;
|
273 |
} |
274 |
case BLINK_SUCCESS_BREAK:
|
275 |
{ |
276 |
if (currentTime >= stateStartTime + wordBreakTime) {
|
277 |
state = BLINK_SUCCESS_O; |
278 |
stateStartTime = currentTime; |
279 |
} |
280 |
break;
|
281 |
} |
282 |
} |
283 |
|
284 |
setLed(led); |
285 |
} |
286 |
|
287 |
return;
|
288 |
} |
289 |
|
290 |
/*
|
291 |
* Shortcut to make the LED blink OK infinitely.
|
292 |
*/
|
293 |
inline void blinkOKinf() { |
294 |
blinkOK(0);
|
295 |
return;
|
296 |
} |
297 |
|
298 |
/*
|
299 |
* Makes the LED visualize the specified data.
|
300 |
* Starting with the MSB of the first of the 'n' bytes, zeros are visualized as short flash and ones as long flash.
|
301 |
* If the specified number of loops is zero, the function will loop infinitely.
|
302 |
*/
|
303 |
void visualizeData(uint8_t* data, uint32_t bytes, uint32_t loops) {
|
304 |
/* initialize some variables and constants */
|
305 |
enum State {BLINK_DATA_BIT,
|
306 |
BLINK_DATA_BYTE_BREAK, |
307 |
BLINK_DATA_LOOP_BREAK |
308 |
} state = BLINK_DATA_BIT; |
309 |
uint8_t led = 0;
|
310 |
uint8_t mask = 0x80;
|
311 |
uint32_t byte = 0;
|
312 |
uint32_t loop = 0;
|
313 |
const uint32_t sigS = 50; |
314 |
const uint32_t sigL = 200; |
315 |
const uint32_t interBitBreak = 500; |
316 |
const uint32_t interByteBreak = 1000; |
317 |
const uint32_t interLoopBreak = 2500; |
318 |
uint32_t flash_dur = 0;
|
319 |
uint32_t stateStartTime = 0;
|
320 |
saTimerUpdate(&stateStartTime); |
321 |
uint32_t currentTime = stateStartTime; |
322 |
|
323 |
/* return immediately if the number of bytes is zero */
|
324 |
if (bytes == 0) { |
325 |
return;
|
326 |
} |
327 |
|
328 |
/* either loop the specified number, or infinetly */
|
329 |
while (loop < loops || loops == 0) { |
330 |
led = 0;
|
331 |
saTimerUpdate(¤tTime); |
332 |
switch (state) {
|
333 |
case BLINK_DATA_BIT:
|
334 |
{ |
335 |
if (data[byte] & mask) {
|
336 |
flash_dur = sigL; |
337 |
} else {
|
338 |
flash_dur = sigS; |
339 |
} |
340 |
if (currentTime < stateStartTime + flash_dur) {
|
341 |
led = 1;
|
342 |
} else if (currentTime < stateStartTime + flash_dur+interBitBreak) { |
343 |
led = 0;
|
344 |
} else {
|
345 |
mask = mask >> 1;
|
346 |
if (mask > 0) { |
347 |
state = BLINK_DATA_BIT; |
348 |
} else if (byte < bytes-1) { |
349 |
state = BLINK_DATA_BYTE_BREAK; |
350 |
} else {
|
351 |
state = BLINK_DATA_LOOP_BREAK; |
352 |
++loop; |
353 |
} |
354 |
stateStartTime = currentTime; |
355 |
} |
356 |
break;
|
357 |
} |
358 |
case BLINK_DATA_BYTE_BREAK:
|
359 |
{ |
360 |
if (currentTime >= stateStartTime + interByteBreak) {
|
361 |
mask = 0x80;
|
362 |
state = BLINK_DATA_BIT; |
363 |
++byte; |
364 |
stateStartTime = currentTime; |
365 |
} |
366 |
break;
|
367 |
} |
368 |
case BLINK_DATA_LOOP_BREAK:
|
369 |
{ |
370 |
if (currentTime >= stateStartTime + interLoopBreak) {
|
371 |
mask = 0x80;
|
372 |
state = BLINK_DATA_BIT; |
373 |
byte = 0;
|
374 |
stateStartTime = currentTime; |
375 |
} |
376 |
break;
|
377 |
} |
378 |
} |
379 |
|
380 |
setLed(led); |
381 |
} |
382 |
|
383 |
return;
|
384 |
} |
385 |
|
386 |
/*
|
387 |
* Makes the LED visualize the specified byte.
|
388 |
* Starting with the MSB, zeros are visualized as short flash and ones as long flash.
|
389 |
* If the specified number of loops is zero, the function will loop infinitely.
|
390 |
*/
|
391 |
void visualizeByte(uint8_t byte, uint32_t loops) {
|
392 |
visualizeData(&byte, 1, loops);
|
393 |
return;
|
394 |
} |
395 |
|