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