amiro-blt / Target / Source / AMiRo / helper.c @ 72294488
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(¤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 | }  |