Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / helper.c @ ea906b44

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(&current);
50
  uint32_t end = current + ms;
51

    
52
  while (current < end)
53
  {
54
    saTimerUpdate(&current);
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(&current_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(&current_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(&currentTime);
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(&currentTime);
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(&currentTime);
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