Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / AMiRo / helper.c @ 6feb42c8

History | View | Annotate | Download (10.77 KB)

1 69661903 Thomas Schöpping
#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(&current);
49
  uint32_t end = current + ms;
50
51
  while (current < end)
52
  {
53
    saTimerUpdate(&current);
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(&current_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(&current_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(&currentTime);
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(&currentTime);
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(&currentTime);
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
}