Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ 78b92b33

History | View | Annotate | Download (51.813 KB)

1 e545e620 Thomas Schöpping
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3 84f0ce9e Thomas Schöpping
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 e545e620 Thomas Schöpping

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19 53710ca3 Marc Rothmann
/**
20
 * @file    aos_main.cpp
21
 * @brief   Main function.
22
 * @details Main function with SSSP and initialization,
23
 *          extendable via hooks.
24
 *
25
 * @addtogroup aos_system
26
 * @{
27
 */
28
29 3940ba8a Thomas Schöpping
#include <amiroos.h>
30 e545e620 Thomas Schöpping
31 b6b45e4c Thomas Schöpping
/*
32
 * hook to add further includes
33
 */
34 512abac1 Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER)
35
#include AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER
36 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER) */
37 b6b45e4c Thomas Schöpping
38 f3ac1c96 Thomas Schöpping
/******************************************************************************/
39
/* LOCAL DEFINITIONS                                                          */
40
/******************************************************************************/
41
42 e545e620 Thomas Schöpping
/**
43 1a8fb642 Thomas Schöpping
 * @brief   Event mask to identify GPIO events.
44 e545e620 Thomas Schöpping
 */
45 1a8fb642 Thomas Schöpping
#define GPIOEVENT_MASK                          EVENT_MASK(0)
46 e545e620 Thomas Schöpping
47
/**
48
 * @brief   Event mask to identify OS events.
49
 */
50 6b53f6bf Thomas Schöpping
#define OSEVENT_MASK                            EVENT_MASK(1)
51 e545e620 Thomas Schöpping
52
/**
53 933df08e Thomas Schöpping
 * @brief   Event mask to idetify CAN events.
54
 */
55
#define CANEVENT_MASK                           EVENT_MASK(2)
56
57
/**
58
 * @brief   Event mask to idetify timeout events.
59
 */
60
#define TIMEOUTEVENT_MASK                       EVENT_MASK(3)
61
62
/**
63
 * @brief   Event mask to idetify signal delay events.
64
 */
65
#define DELAYEVENT_MASK                         EVENT_MASK(4)
66
67 75c1f470 Thomas Schöpping
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_CAN == TRUE)) || defined(__DOXYGEN__)
68
#define SSSP_STAGE3_ENABLE                      true
69
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_CAN == TRUE) */
70
#define SSSP_STAGE3_ENABLE                      false
71
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_CAN == TRUE) */
72
73
#if (SSSP_STAGE3_ENABLE == true) || defined(__DOXYGEN__)
74 9ebb11a9 Thomas Schöpping
75 933df08e Thomas Schöpping
/**
76
 * @brief   CAN message identifier for initialization of the SSSP stack initialization sequence.
77
 */
78
#define SSSP_STACKINIT_CANMSGID_INIT            0x003
79
80
/**
81
 * @brief   CAN message identifier for transmitting module IDs during the SSSP stack initialization sequence.
82
 */
83
#define SSSP_STACKINIT_CANMSGID_MODULEID        0x002
84
85
/**
86
 * @brief   CAN message identifier for abortion of the SSSP stack initialization sequence.
87
 */
88
#define SSSP_STACKINIT_CANMSGID_ABORT           0x001
89
90 75c1f470 Thomas Schöpping
#endif /* (SSSP_STAGE3_ENABLE == true) */
91 1d3e002f Thomas Schöpping
92 75c1f470 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_ENABLE != true) || defined(__DOXYGEN__)
93 1d3e002f Thomas Schöpping
/**
94
 * @brief   Default shutdown mode if SSSP is unavailable.
95
 */
96
#define AOS_SHUTDOWN_DEFAULT                    AOS_SHUTDOWN_DEEPSLEEP
97 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
98 9ebb11a9 Thomas Schöpping
99 75c1f470 Thomas Schöpping
#if (HAL_USE_CAN == TRUE) || defined(__DOXYGEN__)
100 933df08e Thomas Schöpping
/**
101 9461fadc Thomas Schöpping
 * @brief   CAN message identifier for calender synchronization message.
102
 */
103
#define CALENDERSYNC_CANMSGID                   0x004
104 75c1f470 Thomas Schöpping
#endif /* (HAL_USE_CAN == TRUE) */
105 9461fadc Thomas Schöpping
106 f3ac1c96 Thomas Schöpping
/******************************************************************************/
107
/* EXPORTED VARIABLES                                                         */
108
/******************************************************************************/
109
110
/******************************************************************************/
111
/* LOCAL TYPES                                                                */
112
/******************************************************************************/
113
114
/******************************************************************************/
115
/* LOCAL VARIABLES                                                            */
116
/******************************************************************************/
117
118 9461fadc Thomas Schöpping
/**
119 1a8fb642 Thomas Schöpping
 * @brief   Listener object for GPIO events.
120 e545e620 Thomas Schöpping
 */
121 1a8fb642 Thomas Schöpping
static event_listener_t _eventListenerGPIO;
122 e545e620 Thomas Schöpping
123
/**
124
 * @brief   Listener object for OS events.
125
 */
126
static event_listener_t _eventListenerOS;
127
128
#if defined(MODULE_HAL_PROGIF) || defined(__DOXYGEN__)
129 1a8fb642 Thomas Schöpping
130 e545e620 Thomas Schöpping
/**
131 ba516b61 Thomas Schöpping
 * @brief   I/O channel for the programmer interface.
132 e545e620 Thomas Schöpping
 */
133 ba516b61 Thomas Schöpping
static AosIOChannel _stdiochannel;
134
135 47e89ebf Thomas Schöpping
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
136
137 ba516b61 Thomas Schöpping
/**
138
 * @brief   I/O shell channel for the programmer interface.
139
 */
140
static AosShellChannel _stdshellchannel;
141 47e89ebf Thomas Schöpping
142
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
143 1d3e002f Thomas Schöpping
#endif /* defined(MODULE_HAL_PROGIF) */
144 e545e620 Thomas Schöpping
145 b6b45e4c Thomas Schöpping
/*
146
 * hook to add further static variables
147
 */
148
#if defined(AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES)
149
AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES
150 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES) */
151 b6b45e4c Thomas Schöpping
152 f3ac1c96 Thomas Schöpping
/******************************************************************************/
153
/* LOCAL FUNCTIONS                                                            */
154
/******************************************************************************/
155
156 e545e620 Thomas Schöpping
/**
157
 * @brief   Prints an error message about an unexpected event.
158
 *
159
 * @param[in] mask    The event mask.
160
 * @param[in] flags   The event flags.
161
 */
162 933df08e Thomas Schöpping
static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
163 e545e620 Thomas Schöpping
{
164 6b53f6bf Thomas Schöpping
#if (AMIROOS_CFG_DBG == true)
165 1e5f7648 Thomas Schöpping
  aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
166 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_DBG == true) */
167 933df08e Thomas Schöpping
  (void)(mask);
168
  (void)(flags);
169 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_DBG == true) */
170 3e1a9c79 Thomas Schöpping
  return;
171 933df08e Thomas Schöpping
}
172
173 75c1f470 Thomas Schöpping
#if (SSSP_STAGE3_ENABLE == true) || defined(__DOXYGEN__)
174 933df08e Thomas Schöpping
/**
175
 * @brief   Callback function to be used during SSSP stack initialization sequence.
176
 *
177
 * @param[in] par   A pointer to an @p event_source_t to be fired.
178
 */
179
static void _ssspTimerCallback(void* par)
180
{
181
  aosDbgCheck(par != NULL);
182
183
  chSysLockFromISR();
184
  chEvtBroadcastI((event_source_t*)par);
185
  chSysUnlockFromISR();
186
187 e545e620 Thomas Schöpping
  return;
188
}
189 75c1f470 Thomas Schöpping
#endif /* (SSSP_STAGE3_ENABLE == true) */
190 e545e620 Thomas Schöpping
191
/**
192 9461fadc Thomas Schöpping
 * @brief   Helper function to serialize data.
193 933df08e Thomas Schöpping
 *
194
 * @param[out]  dst   Pointer to the output buffer.
195 9461fadc Thomas Schöpping
 * @param[in]   src   Data to be serialized.
196
 * @param[in]   n     Number of bytes to serialize.
197 933df08e Thomas Schöpping
 */
198 9461fadc Thomas Schöpping
inline void _serialize(uint8_t* dst, const uint64_t src, const uint8_t n)
199 933df08e Thomas Schöpping
{
200
  aosDbgCheck(dst != NULL);
201 9461fadc Thomas Schöpping
  aosDbgCheck(n > 0 && n <= 8);
202 933df08e Thomas Schöpping
203 9461fadc Thomas Schöpping
  for (uint8_t byte = 0; byte < n; ++byte) {
204 933df08e Thomas Schöpping
    dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
205
  }
206
207
  return;
208
}
209
210
/**
211 9461fadc Thomas Schöpping
 * @brief   Helper function to deserialize data.
212 933df08e Thomas Schöpping
 *
213
 * @param[in] src   Pointer to the buffer of data to be deserialzed.
214 9461fadc Thomas Schöpping
 * @param[in] n     Number of bytes to deserialize.
215 933df08e Thomas Schöpping
 *
216
 * @return    The deserialized 32 bit data.
217
 */
218 9461fadc Thomas Schöpping
inline uint64_t _deserialize(uint8_t* src, const uint8_t n)
219 933df08e Thomas Schöpping
{
220
  aosDbgCheck(src != NULL);
221 9461fadc Thomas Schöpping
  aosDbgCheck(n > 0 && n <= 8);
222 933df08e Thomas Schöpping
223 9461fadc Thomas Schöpping
  uint64_t result = 0;
224
  for (uint8_t byte = 0; byte < n; ++byte) {
225
    result |= ((uint64_t)src[byte]) << (byte * 8);
226
  }
227
228
  return result;
229
}
230
231 23437e98 Thomas Schöpping
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
232
233 9461fadc Thomas Schöpping
/**
234
 * @brief   Converter function to encode a TM value to a single unsigned 64 bit integer.
235
 *
236
 * @details Contents of the TM struct are mapped as follows:
237
 *            bits  |63     62|61      53|52    50|49         26|25     22|21     17|16     12|11      6|5       0|
238
 *            #bits |       2 |        9 |      3 |          24 |       4 |       5 |       5 |       6 |       6 |
239
 *            value |   isdst |     yday |   wday |        year |     mon |    mday |    hour |     min |     sec |
240
 *            range | special | [0, 365] | [0, 6] | [1900, ...] | [0, 11] | [1, 31] | [0, 23] | [0, 59] | [0, 61] |
241
 *          The Daylight Saving Time Flag (isdsst) is encoded as follows:
242
 *            DST not in effect         -> 0
243
 *            DST in effect             -> 1
244
 *            no information available  -> 2
245
 *
246
 * @param[in] src   Pointer to the TM struct to encode.
247
 *
248
 * @return  An unsigned 64 bit integer, which holds the encoded time value.
249
 */
250
inline uint64_t _TM2U64(struct tm* src)
251
{
252
  aosDbgCheck(src != NULL);
253
254
  return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
255
          ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
256
          ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
257
          ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
258
          ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
259
          ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
260
          ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
261
          ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
262
          ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
263
}
264
265
/**
266
 * @brief   Converter functiomn to retrieve the encoded TM value from an unsigned 64 bit integer.
267
 *
268
 * @details For information on the encoding, please refer to @p _TM2U64 function.
269
 *
270
 * @param[out] dst  The TM struct to fill with the decoded values.
271
 * @param[in]  src  Unsigned 64 bit integer holding the encoded TM value.
272
 */
273
inline void _U642TM(struct tm* dst, const uint64_t src)
274
{
275
  aosDbgCheck(dst != NULL);
276
277
  dst->tm_sec  = (src >> 0)  & 0x0000003F;
278
  dst->tm_min  = (src >> 6)  & 0x0000003F;
279
  dst->tm_hour = (src >> 12) & 0x0000001F;
280
  dst->tm_mday = (src >> 17) & 0x0000001F;
281
  dst->tm_mon  = (src >> 22) & 0x0000000F;
282
  dst->tm_year = (src >> 26) & 0x00FFFFFF;
283
  dst->tm_wday = (src >> 50) & 0x00000007;
284
  dst->tm_yday = (src >> 53) & 0x000001FF;
285
  dst->tm_isdst = (((src >> 62) & 0x03) == 0) ? 0 : (((src >> 62) & 0x03) > 0) ? 1 : -1;
286
287
  return;
288 933df08e Thomas Schöpping
}
289
290 7de0cc90 Thomas Schöpping
#endif /* (HAL_USE_RTC == TRUE) */
291 23437e98 Thomas Schöpping
292 75c1f470 Thomas Schöpping
#if (SSSP_STAGE3_ENABLE) || defined(__DOXYGEN__)
293 933df08e Thomas Schöpping
/**
294
 * @brief   Implementation of the SSSP module stack initialization sequence (startup phase 3).
295
 *
296
 * @return Shutdown value.
297
 * @retval AOS_SHUTDOWN_NONE      No shutdown signal received
298
 * @retval AOS_SHUTDOWN_PASSIVE   Shutdown signal received.
299
 */
300
aos_shutdown_t _ssspModuleStackInitialization(void)
301
{
302
  // local types
303
  /**
304
   * @brief   States for the internal state machine to implement SSSP startup stage 3.
305
   */
306
  typedef enum {
307
    STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
308
    STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
309
    STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
310
    STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
311
    STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
312
    STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
313
    STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
314
    STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
315
  } sssp_modulestackinitstage_t;
316
317
  typedef struct {
318
    bool loop     : 1;
319
    bool wfe      : 1;
320
    bool wfe_next : 1;
321
  } flags_t;
322
323
  // local variables
324
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
325
  sssp_modulestackinitstage_t stage = STAGE_3_1;
326
  eventmask_t eventmask = 0;
327 1d3e002f Thomas Schöpping
  eventflags_t ioflags = 0;
328 933df08e Thomas Schöpping
  event_source_t eventSourceTimeout;
329
  event_source_t eventSourceDelay;
330
  event_listener_t eventListenerTimeout;
331
  event_listener_t eventListenerDelay;
332
  event_listener_t eventListenerCan;
333
  virtual_timer_t timerTimeout;
334
  virtual_timer_t timerDelay;
335
  CANTxFrame canTxFrame;
336
  CANRxFrame canRxFrame;
337
#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
338
  aos_ssspmoduleid_t lastid = 0;
339 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true) */
340 933df08e Thomas Schöpping
  flags_t flags;
341 1d3e002f Thomas Schöpping
  aos_timestamp_t uptime;
342 933df08e Thomas Schöpping
343
  // initialize local varibles
344
  chEvtObjectInit(&eventSourceTimeout);
345
  chEvtObjectInit(&eventSourceDelay);
346
  chVTObjectInit(&timerTimeout);
347
  chVTObjectInit(&timerDelay);
348
  canTxFrame.RTR = CAN_RTR_DATA;
349
  canTxFrame.IDE = CAN_IDE_STD;
350
  flags.loop = true;
351
  flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
352
  flags.wfe_next = true;
353
354
  // initialize system variables
355
  aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
356
  aos.sssp.moduleId = 0;
357
358
  // listen to events (timout, delay, CAN receive)
359
  chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
360
  chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
361
  chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
362
363
  /*
364
   * FSM in a loop.
365
   *
366
   * This is a fully event-based FSM for the module stack initialization
367
   * sequence, defined by SSSP as startup stage 3. There are five different
368
   * events that can occur at this point:
369
   *  I/O events: The input level of an input pin has changed. Such events must
370
   *              be handled differently depending on the current state. Most
371
   *              of the time, however, such events can be ignored.
372
   *  OS events:  Such events are only available after this stage completed and
373
   *              thus should never occur. However, there is an optional hook
374
   *              to handle such events, nevertheless.
375
   *  CAN events: At least one CAN message was received. Note that this event
376
   *              will only fire again if all input buffers have been cleared.
377
   *  timeouts:   If some module does not support the sequence of there is any
378
   *              issue, such a case is detected via timeouts and must be
379
   *              handled accordingly (see abort state). In some cases, it is
380
   *              possible that a timeout event occurres 'simultaneously' with
381
   *              some other event. This can be caused by several timing issues
382
   *              and is a valid situation. As a result, any other events
383
   *              should be handled before the timeout event. If the other
384
   *              events are expected and valid, this implementation requires
385
   *              the timeout event flag to be cleared explicitely. Otherwise
386
   *              it is evaluated at the end of each iteration of the loop.
387
   *  delays:     Depending on the current state, delays are required by SSSP
388
   *              for timing of the sequential activation of signals.
389
   */
390
  aosDbgPrintf("SSSP stack initialization sequence:\n");
391
  while (flags.loop) {
392
#if (AMIROOS_CFG_DBG == true)
393
    switch (stage) {
394
      case STAGE_3_1:
395
        aosDbgPrintf(">>> 3-1\n");
396
        break;
397
      case STAGE_3_2:
398
        aosDbgPrintf(">>> 3-2\n");
399
        break;
400
      case STAGE_3_3_WAITFORFIRSTID:
401
        aosDbgPrintf(">>> 3-3 (1st ID)\n");
402
        break;
403
      case STAGE_3_3_WAITFORIDORSIG:
404
        aosDbgPrintf(">>> 3-3 (ID/sig)\n");
405
        break;
406
      case STAGE_3_3_WAITFORID:
407
        aosDbgPrintf(">>> 3-3 (ID)\n");
408
        break;
409
      case STAGE_3_4_FINISH:
410
        aosDbgPrintf(">>> 3-4 (finish)\n");
411
        break;
412
      case STAGE_3_4_ABORT_ACTIVE:
413 9461fadc Thomas Schöpping
        aosDbgPrintf(">>> 3-4 (active abort)\n");
414 933df08e Thomas Schöpping
        break;
415
      case STAGE_3_4_ABORT:
416
        aosDbgPrintf(">>> 3-4 (abort)\n");
417
        break;
418
    }
419 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_DBG == true) */
420 933df08e Thomas Schöpping
421
    // reset wfe flag for the next iteration
422
    flags.wfe_next = true;
423
424 1d3e002f Thomas Schöpping
    // waiting for events (may be skipped)
425 933df08e Thomas Schöpping
    if (flags.wfe) {
426
      // wait for any event to occur
427
      aosDbgPrintf("WFE...");
428 1e5f7648 Thomas Schöpping
      eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT));
429 933df08e Thomas Schöpping
      aosDbgPrintf("\t0x%08X", eventmask);
430
    } else {
431
      aosDbgPrintf("WFE skipped");
432 1d3e002f Thomas Schöpping
      eventmask = 0;
433 933df08e Thomas Schöpping
    }
434
    aosSysGetUptime(&uptime);
435 1d3e002f Thomas Schöpping
    aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
436 933df08e Thomas Schöpping
437
    /*
438
     * execute some general tasks and high priority events
439
     */
440
    // no event occurred at all
441
    if ((flags.wfe) && (eventmask == 0)) {
442
      aosDbgPrintf("ERR: no evt\n");
443
      // enforce timeout event
444
      chEvtBroadcast(&eventSourceTimeout);
445
      continue;
446
    }
447
    // if an IO event occurred
448 1a8fb642 Thomas Schöpping
    if (eventmask & _eventListenerGPIO.events) {
449
      ioflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
450 933df08e Thomas Schöpping
      aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
451
      // a power-down event occurred
452 1a8fb642 Thomas Schöpping
      if (ioflags & MODULE_SSSP_EVENTFLAG_PD) {
453 933df08e Thomas Schöpping
        aosDbgPrintf("PD evt\n");
454
        // deactivate S and UP
455 1d3e002f Thomas Schöpping
        aosDbgPrintf("disabling S\n");
456 1a8fb642 Thomas Schöpping
        apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
457 9ebb11a9 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_END != true)
458 1d3e002f Thomas Schöpping
        aosDbgPrintf("disabling UP\n");
459 1a8fb642 Thomas Schöpping
        apalControlGpioSet(&moduleSsspGpioUP, APAL_GPIO_OFF);
460 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
461 933df08e Thomas Schöpping
        // set shutdown flag and exit the loop
462
        shutdown = AOS_SHUTDOWN_PASSIVE;
463
        break;
464
      }
465
      // the S signal was deactivated
466 1a8fb642 Thomas Schöpping
      if (ioflags & MODULE_SSSP_EVENTFLAG_S) {
467 933df08e Thomas Schöpping
        apalControlGpioState_t sstate;
468 1a8fb642 Thomas Schöpping
        apalControlGpioGet(&moduleSsspGpioS, &sstate);
469 1d3e002f Thomas Schöpping
        if (sstate == APAL_GPIO_ON) {
470
          aosDbgPrintf("S evt (enabled)\n");
471
        } else {
472
          aosDbgPrintf("S evt (disabled)\n");
473 933df08e Thomas Schöpping
          // either finish or abort
474
          if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
475
            stage = STAGE_3_4_FINISH;
476
          } else if (stage != STAGE_3_4_ABORT) {
477
            stage = STAGE_3_4_ABORT_ACTIVE;
478
          }
479
        }
480
      }
481
    }
482
    // an OS event occurred
483 9461fadc Thomas Schöpping
    if (eventmask & _eventListenerOS.events) {
484 933df08e Thomas Schöpping
      aosDbgPrintf("WARN: OS evt\n");
485
      // get the flags
486
      eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
487
      // there should be no OS events at this point
488 7de0cc90 Thomas Schöpping
#if defined(MODULE_SSSP_STARTUP_3_OSEVENT_HOOK)
489 933df08e Thomas Schöpping
      MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
490 7de0cc90 Thomas Schöpping
#else /* defined(MODULE_SSSP_STARTUP_3_OSEVENT_HOOK) */
491 933df08e Thomas Schöpping
      _unexpectedEventError(eventmask, oseventflags);
492 7de0cc90 Thomas Schöpping
#endif /* defined(MODULE_SSSP_STARTUP_3_OSEVENT_HOOK) */
493 933df08e Thomas Schöpping
    }
494
    // if a CAN event occurred
495 9461fadc Thomas Schöpping
    if ((eventmask & eventListenerCan.events)) {
496 1d3e002f Thomas Schöpping
      aosDbgPrintf("CAN evt\n");
497 933df08e Thomas Schöpping
      // fetch message
498
      if (flags.wfe) {
499
        canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
500
        aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
501
      }
502
      // identify and handle abort messgaes
503
      if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
504
        stage = STAGE_3_4_ABORT;
505
      }
506
      // warn if a unexpected message was received
507
      else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
508
               (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
509
        aosDbgPrintf("WARN: unknown msg\n");
510
      }
511
      // any further pending messages are fetched at the end of the loop
512
    }
513
    // if a timeout event occurred
514 9461fadc Thomas Schöpping
    if (eventmask & eventListenerTimeout.events) {
515 1d3e002f Thomas Schöpping
      aosDbgPrintf("timeout evt\n");
516 933df08e Thomas Schöpping
      // is handled at the end of the loop (or must be cleared by FSM)
517
    }
518
    // if a delay event occurred
519 9461fadc Thomas Schöpping
    if (eventmask & eventListenerDelay.events) {
520 1d3e002f Thomas Schöpping
      aosDbgPrintf("delay evt\n");
521 933df08e Thomas Schöpping
      // is handled by FSM
522
    }
523
524
    /*
525
     * this is the actual FSM
526
     */
527
    switch (stage) {
528
      case STAGE_3_1:
529
      {
530
        aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
531
532
        // there was no event at all (skipped wfe)
533
        if (eventmask == 0 && flags.wfe == false) {
534
#if (AMIROOS_CFG_SSSP_MASTER == true)
535
          // initialize the stage by transmitting an according CAN message
536
          aosDbgPrintf("CAN -> init\n");
537
          canTxFrame.DLC = 0;
538
          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_INIT;
539
          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
540
            chEvtBroadcast(&eventSourceTimeout);
541
            break;
542
          }
543
          // activate S
544 1d3e002f Thomas Schöpping
          aosDbgPrintf("enabling S\n");
545 1a8fb642 Thomas Schöpping
          apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
546 933df08e Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_START == true)
547
          // proceed immediately
548
          stage = STAGE_3_2;
549
          flags.wfe_next = false;
550 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_SSSP_STACK_START == true) */
551 933df08e Thomas Schöpping
          // set the timeout timer
552 1e5f7648 Thomas Schöpping
          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
553 933df08e Thomas Schöpping
          // proceed
554
          stage = STAGE_3_3_WAITFORFIRSTID;
555 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
556
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
557 933df08e Thomas Schöpping
          // set the timeout timer
558 1e5f7648 Thomas Schöpping
          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
559 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
560 933df08e Thomas Schöpping
        }
561
562
#if (AMIROOS_CFG_SSSP_MASTER != true)
563
        // a CAN message was received
564 9461fadc Thomas Schöpping
        else if (eventmask & eventListenerCan.events) {
565 933df08e Thomas Schöpping
          // if an initiation message was received
566
          if (canRxFrame.DLC == 0 &&
567
              canRxFrame.RTR == CAN_RTR_DATA &&
568
              canRxFrame.IDE == CAN_IDE_STD &&
569
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_INIT) {
570
            aosDbgPrintf("init msg\n");
571
            // reset the timeout timer and clear pending flags
572
            chVTReset(&timerTimeout);
573 9461fadc Thomas Schöpping
            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
574
            eventmask &= ~(eventListenerTimeout.events);
575 933df08e Thomas Schöpping
            // activate S
576 1d3e002f Thomas Schöpping
            aosDbgPrintf("enabling S\n");
577 1a8fb642 Thomas Schöpping
            apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
578 933df08e Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_START == true)
579
            // proceed
580
            stage = STAGE_3_2;
581
            flags.wfe_next = false;
582 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_SSSP_STACK_START == true) */
583 933df08e Thomas Schöpping
            // set the timeout timer
584 1e5f7648 Thomas Schöpping
            chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
585 933df08e Thomas Schöpping
            // proceed
586
            stage = STAGE_3_3_WAITFORFIRSTID;
587 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
588 933df08e Thomas Schöpping
          }
589
        }
590 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */
591 933df08e Thomas Schöpping
592
        break;
593
      } /* end of STAGE_3_1 */
594
595
      case STAGE_3_2:
596
      {
597
#if (AMIROOS_CFG_SSSP_STACK_START == true)
598
        aos.sssp.stage = AOS_SSSP_STARTUP_3_2;
599
600
        // if this stage was just entered
601
        if (flags.wfe == false) {
602
          // set the module ID
603
          aos.sssp.moduleId = 1;
604
          // broadcast module ID
605
          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
606
          canTxFrame.DLC = 4;
607
          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
608 9461fadc Thomas Schöpping
          _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
609 933df08e Thomas Schöpping
          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
610
            chEvtBroadcast(&eventSourceTimeout);
611
            break;
612
          }
613 7de0cc90 Thomas Schöpping
#if (AMIROOS_CFG_DBG == true)
614 933df08e Thomas Schöpping
          lastid = aos.sssp.moduleId;
615 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_DBG == true) */
616 933df08e Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_END == true)
617
          // sequence is already over
618
          // deactivate S
619 1d3e002f Thomas Schöpping
          aosDbgPrintf("disabling S\n");
620 933df08e Thomas Schöpping
          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
621
          // proceed
622
          stage = STAGE_3_3_WAITFORID;
623 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_SSSP_STACK_END == true) */
624 933df08e Thomas Schöpping
          // set the delay timer so the UP signal is activated later
625 1e5f7648 Thomas Schöpping
          chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
626 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_END == true) */
627 933df08e Thomas Schöpping
        }
628
629
        // if a delay event occurred
630 9461fadc Thomas Schöpping
        if (eventmask & eventListenerDelay.events) {
631 933df08e Thomas Schöpping
          // activate UP
632 1d3e002f Thomas Schöpping
          aosDbgPrintf("enabling UP\n");
633 1a8fb642 Thomas Schöpping
          apalControlGpioSet(&moduleSsspGpioUP, APAL_GPIO_ON);
634 933df08e Thomas Schöpping
          // deactivate S
635 1d3e002f Thomas Schöpping
          aosDbgPrintf("disabling S\n");
636 1a8fb642 Thomas Schöpping
          apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
637 933df08e Thomas Schöpping
          // explicitely clear timeout event flag
638 9461fadc Thomas Schöpping
          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
639
          eventmask &= ~(eventListenerTimeout.events);
640 933df08e Thomas Schöpping
          // proceed
641
          stage = STAGE_3_3_WAITFORID;
642
        }
643 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
644 933df08e Thomas Schöpping
645
        break;
646
      } /* end of STAGE_3_2 */
647
648
      case STAGE_3_3_WAITFORFIRSTID:
649
      {
650
#if (AMIROOS_CFG_SSSP_STACK_START != true)
651
        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
652
653
        // a CAN message was received
654 9461fadc Thomas Schöpping
        if (eventmask & eventListenerCan.events) {
655 933df08e Thomas Schöpping
          // if an ID message was received
656
          if (canRxFrame.DLC == 4 &&
657
              canRxFrame.RTR == CAN_RTR_DATA &&
658
              canRxFrame.IDE == CAN_IDE_STD &&
659
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
660 9461fadc Thomas Schöpping
            aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
661 933df08e Thomas Schöpping
            // validate received ID
662 9461fadc Thomas Schöpping
            if (lastid < _deserialize(canRxFrame.data8, 4)) {
663 933df08e Thomas Schöpping
              // store received ID
664 9461fadc Thomas Schöpping
              lastid = _deserialize(canRxFrame.data8, 4);
665 933df08e Thomas Schöpping
              // restart timeout timer
666 1e5f7648 Thomas Schöpping
              chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
667 933df08e Thomas Schöpping
              // proceed
668
              stage = STAGE_3_3_WAITFORIDORSIG;
669
            } else {
670
              aosDbgPrintf("ERR: invalid ID\n");
671
              // abort
672
              stage = STAGE_3_4_ABORT_ACTIVE;
673
              flags.wfe_next = false;
674
            }
675
            // explicitely clear timeout event flag
676 9461fadc Thomas Schöpping
            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
677
            eventmask &= ~(eventListenerTimeout.events);
678 933df08e Thomas Schöpping
          }
679
        }
680 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
681 933df08e Thomas Schöpping
        break;
682
      } /* end of STAGE_3_3_WAITFORFIRSTID */
683
684
      case STAGE_3_3_WAITFORIDORSIG:
685
      {
686
#if (AMIROOS_CFG_SSSP_STACK_START != true)
687
        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
688
689
        // a CAN message was received
690 9461fadc Thomas Schöpping
        if (eventmask & eventListenerCan.events) {
691 933df08e Thomas Schöpping
          // if an ID message was received
692
          if (canRxFrame.DLC == 4 &&
693
              canRxFrame.RTR == CAN_RTR_DATA &&
694
              canRxFrame.IDE == CAN_IDE_STD &&
695
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
696 9461fadc Thomas Schöpping
            aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
697 933df08e Thomas Schöpping
            // validate received ID
698 9461fadc Thomas Schöpping
            if (lastid < _deserialize(canRxFrame.data8, 4)) {
699 933df08e Thomas Schöpping
              // store received ID
700 9461fadc Thomas Schöpping
              lastid = _deserialize(canRxFrame.data8, 4);
701 933df08e Thomas Schöpping
              // restart timeout timer
702 1e5f7648 Thomas Schöpping
              chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
703 933df08e Thomas Schöpping
            } else {
704
              aosDbgPrintf("ERR: invalid ID\n");
705
              // abort
706
              stage = STAGE_3_4_ABORT_ACTIVE;
707
              flags.wfe_next = false;
708
            }
709
            // explicitely clear timeout event flag
710 9461fadc Thomas Schöpping
            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
711
            eventmask &= ~(eventListenerTimeout.events);
712 933df08e Thomas Schöpping
          }
713
        }
714
715
        // if an IO event was received (DN signal)
716 1a8fb642 Thomas Schöpping
        if ((eventmask & _eventListenerGPIO.events) && (ioflags & MODULE_SSSP_EVENTFLAG_DN)) {
717 1d3e002f Thomas Schöpping
          aosDbgPrintf("DN evt\n");
718 933df08e Thomas Schöpping
          // reset timeout timer
719
          chVTReset(&timerTimeout);
720 9461fadc Thomas Schöpping
          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
721
          eventmask &= ~(eventListenerTimeout.events);
722 933df08e Thomas Schöpping
          // increment and broadcast ID
723
          aos.sssp.moduleId = lastid + 1;
724
          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
725
          canTxFrame.DLC = 4;
726
          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
727 9461fadc Thomas Schöpping
          _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
728 933df08e Thomas Schöpping
          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
729
            chEvtBroadcast(&eventSourceTimeout);
730
            break;
731
          }
732
          // set delay timer
733 1e5f7648 Thomas Schöpping
          chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
734 933df08e Thomas Schöpping
        }
735
736
        // if a delay event occurred
737 9461fadc Thomas Schöpping
        if (eventmask & eventListenerDelay.events) {
738 933df08e Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_END != true)
739
          // activate UP
740 1d3e002f Thomas Schöpping
          aosDbgPrintf("enabling UP\n");
741 1a8fb642 Thomas Schöpping
          apalControlGpioSet(&moduleSsspGpioUP, APAL_GPIO_ON);
742 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
743 933df08e Thomas Schöpping
          // deactivate S
744 1d3e002f Thomas Schöpping
          aosDbgPrintf("disabling S\n");
745 1a8fb642 Thomas Schöpping
          apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
746 933df08e Thomas Schöpping
          // reset the timeout timer
747 1e5f7648 Thomas Schöpping
          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
748 9461fadc Thomas Schöpping
          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
749
          eventmask &= ~(eventListenerTimeout.events);
750 933df08e Thomas Schöpping
          // proceed
751
          stage = STAGE_3_3_WAITFORID;
752
        }
753 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
754 933df08e Thomas Schöpping
755
        break;
756
      } /* end of STAGE_3_3_WAITFORIDORSIG */
757
758
      case STAGE_3_3_WAITFORID:
759
      {
760
        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
761
762
#if (AMIROOS_CFG_SSSP_STACK_END != true)
763
        // a CAN message was received
764 9461fadc Thomas Schöpping
        if (eventmask & eventListenerCan.events) {
765 933df08e Thomas Schöpping
          // if an ID message was received
766
          if (canRxFrame.DLC == 4 &&
767
              canRxFrame.RTR == CAN_RTR_DATA &&
768
              canRxFrame.IDE == CAN_IDE_STD &&
769
              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
770
#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
771
            // Plausibility of the received ID is not checked at this point but is done by other modules still in a previous stage.
772 9461fadc Thomas Schöpping
            lastid = _deserialize(canRxFrame.data8, 4);
773 933df08e Thomas Schöpping
            aosDbgPrintf("ID (%u)\n", lastid);
774 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true) */
775 933df08e Thomas Schöpping
            // restart timeout timer
776 1e5f7648 Thomas Schöpping
            chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
777 9461fadc Thomas Schöpping
            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
778
            eventmask &= ~(eventListenerTimeout.events);
779 933df08e Thomas Schöpping
          }
780
        }
781 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
782 933df08e Thomas Schöpping
783
        break;
784
      } /* end of STAGE_3_3_WAITFORID */
785
786
      case STAGE_3_4_FINISH:
787
      {
788
        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
789
790
        // if an IO event was received (S signal)
791 1a8fb642 Thomas Schöpping
        if ((eventmask & _eventListenerGPIO.events) && (ioflags & MODULE_SSSP_EVENTFLAG_S)) {
792 933df08e Thomas Schöpping
          // reset the timeout timer
793
          chVTReset(&timerTimeout);
794 9461fadc Thomas Schöpping
          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
795
          eventmask &= ~(eventListenerTimeout.events);
796 933df08e Thomas Schöpping
          //set the delay timer
797 1e5f7648 Thomas Schöpping
          chVTSet(&timerDelay, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceDelay);
798 933df08e Thomas Schöpping
        }
799
800
        // if a CAN event was received
801 9461fadc Thomas Schöpping
        if (eventmask & eventListenerCan.events) {
802 933df08e Thomas Schöpping
          // if an abort message was received
803
          if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
804
            aosDbgPrintf("abort msg\n");
805
            // reset the delay timer
806
            chVTReset(&timerDelay);
807 9461fadc Thomas Schöpping
            chEvtWaitAnyTimeout(eventListenerDelay.events, TIME_IMMEDIATE);
808
            eventmask &= ~(eventListenerDelay.events);
809 933df08e Thomas Schöpping
            // proceed
810
            stage = STAGE_3_4_ABORT;
811
          }
812
        }
813
814
        // if a delay timer event occurred
815 9461fadc Thomas Schöpping
        if (eventmask & eventListenerDelay.events) {
816 933df08e Thomas Schöpping
          aosDbgPrintf("sequence sucessful\n");
817
          // sequence finished sucessfully
818
          flags.loop = false;
819
        }
820
821
        break;
822
      } /* end of STAGE_3_4_FINISH */
823
824
      case STAGE_3_4_ABORT_ACTIVE:
825
      {
826
        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
827
828
        // emit abort message
829
        canTxFrame.DLC = 0;
830
        canTxFrame.SID = SSSP_STACKINIT_CANMSGID_ABORT;
831
        canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_INFINITE);
832
        aosDbgPrintf("CAN -> abort\n");
833
        // clear timeout flag
834 9461fadc Thomas Schöpping
        eventmask &= ~(eventListenerTimeout.events);
835 933df08e Thomas Schöpping
        // proceed immediately
836
        stage = STAGE_3_4_ABORT;
837
        flags.wfe_next = false;
838
        break;
839
      } /* end of STAGE_3_4_ABORT_ACTIVE */
840
841
      case STAGE_3_4_ABORT:
842
      {
843
        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
844
845
        // deactivate S
846 1d3e002f Thomas Schöpping
        aosDbgPrintf("disabling SYNC\n");
847 1a8fb642 Thomas Schöpping
        apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
848 933df08e Thomas Schöpping
        // invalidate module ID
849
        aos.sssp.moduleId = 0;
850
851
        // if an IO event was received (S signal)
852 1a8fb642 Thomas Schöpping
        if ((eventmask & _eventListenerGPIO.events) && (ioflags & MODULE_SSSP_EVENTFLAG_S)) {
853 933df08e Thomas Schöpping
          aosDbgPrintf("sequence aborted\n");
854
          // exit the sequence
855
          flags.loop = false;
856
        }
857
858
        break;
859
      } /* end of STAGE_3_4_ABORT */
860 1d3e002f Thomas Schöpping
    } /* end of switch(stage) */
861 933df08e Thomas Schöpping
862
    // fetch pending CAN message (if any)
863 9461fadc Thomas Schöpping
    if ((eventmask & eventListenerCan.events) && (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE) == MSG_OK)) {
864 933df08e Thomas Schöpping
      aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
865
      flags.wfe_next = false;
866
    }
867
868
    // handle unhandled timeout events
869 9461fadc Thomas Schöpping
    if (eventmask & eventListenerTimeout.events) {
870 933df08e Thomas Schöpping
      aosDbgPrintf("ERR: timeout evt\n");
871
      // abort
872
      flags.wfe_next = false;
873
      stage = STAGE_3_4_ABORT_ACTIVE;
874
    }
875
876
    // apply wfe value for next iteration
877
    flags.wfe = flags.wfe_next;
878 1e5f7648 Thomas Schöpping
  } /* end of FSM loop */
879 933df08e Thomas Schöpping
880
  // unregister all events (timeout, delay, CAN receive)
881
  chEvtUnregister(&eventSourceTimeout, &eventListenerTimeout);
882
  chEvtUnregister(&eventSourceDelay, &eventListenerDelay);
883
  chEvtUnregister(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan);
884
  // clear any pending events (timeout, delay, CAN receive)
885
  chEvtWaitAllTimeout(TIMEOUTEVENT_MASK | DELAYEVENT_MASK | CANEVENT_MASK, TIME_IMMEDIATE);
886
887
  // reset all control signals
888
#if (AMIROOS_CFG_SSSP_STACK_END != true)
889 1d3e002f Thomas Schöpping
  aosDbgPrintf("disabling UP\n");
890 1a8fb642 Thomas Schöpping
  apalControlGpioSet(&moduleSsspGpioUP, APAL_GPIO_OFF);
891 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
892 1d3e002f Thomas Schöpping
  aosDbgPrintf("disabling S\n");
893 1a8fb642 Thomas Schöpping
  apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
894 1d3e002f Thomas Schöpping
  aosSysGetUptime(&uptime);
895
  aosDbgPrintf("done\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
896 933df08e Thomas Schöpping
897
  return shutdown;
898
}
899 75c1f470 Thomas Schöpping
#endif /* (SSSP_STAGE3_ENABLE == true) */
900 933df08e Thomas Schöpping
901
/**
902 e545e620 Thomas Schöpping
 * @brief   Application entry point.
903
 */
904
int main(void)
905
{
906
  // local variables
907
  eventmask_t eventmask = 0;
908
  eventflags_t eventflags = 0;
909 1a8fb642 Thomas Schöpping
  eventflags_t gpioeventflagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK;
910 e545e620 Thomas Schöpping
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
911 b6b45e4c Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES)
912
  AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES
913 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES) */
914 e545e620 Thomas Schöpping
915
  /*
916
   * ##########################################################################
917
   * # system initialization                                                  #
918
   * ##########################################################################
919
   */
920
921
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0)
922 b6b45e4c Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS)
923
  AMIROOS_CFG_MAIN_INIT_HOOK_0(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS);
924 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS) */
925 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_0();
926 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS) */
927
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_0) */
928 e545e620 Thomas Schöpping
929
  /* hardware, kernel, and operating system initialization */
930
  // ChibiOS/HAL and custom hal additions (if any)
931
  halInit();
932 7de0cc90 Thomas Schöpping
#if defined(MODULE_INIT_HAL_EXTRA)
933 e545e620 Thomas Schöpping
  MODULE_INIT_HAL_EXTRA();
934 7de0cc90 Thomas Schöpping
#endif /* defined(MODULE_INIT_HAL_EXTRA) */
935 e545e620 Thomas Schöpping
936
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1)
937
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS)
938
  AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
939 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
940 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_1();
941 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
942
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1) */
943 e545e620 Thomas Schöpping
944
  // ChibiOS/RT kernel and custom kernel additions (if any)
945
  chSysInit();
946 7de0cc90 Thomas Schöpping
#if defined(MODULE_INIT_KERNEL_EXTRA)
947 e545e620 Thomas Schöpping
  MODULE_INIT_KERNEL_EXTRA();
948 7de0cc90 Thomas Schöpping
#endif /* defined(MODULE_INIT_KERNEL_EXTRA) */
949 e545e620 Thomas Schöpping
950
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2)
951
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS)
952
  AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
953 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
954 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_2();
955 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
956
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2) */
957 e545e620 Thomas Schöpping
958 3106e8cc Thomas Schöpping
  // AMiRo-OS, additional interrupts and custom OS additions (if any)
959 47e89ebf Thomas Schöpping
#if (AMIROOS_CFG_SHELL_ENABLE == true)
960 6b53f6bf Thomas Schöpping
  aosSysInit(moduleShellPrompt);
961 47e89ebf Thomas Schöpping
#else /* (AMIROOS_CFG_SHELL_ENABLE == true) */
962
  aosSysInit(NULL);
963
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
964 3106e8cc Thomas Schöpping
#if defined(MODULE_INIT_INTERRUPTS)
965
  MODULE_INIT_INTERRUPTS();
966
#endif
967 7de0cc90 Thomas Schöpping
#if defined(MODULE_INIT_OS_EXTRA)
968 e545e620 Thomas Schöpping
  MODULE_INIT_OS_EXTRA();
969 7de0cc90 Thomas Schöpping
#endif /* defined(MODULE_INIT_OS_EXTRA) */
970 e545e620 Thomas Schöpping
971
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3)
972
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS)
973
  AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
974 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
975 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_3();
976 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
977
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3) */
978 e545e620 Thomas Schöpping
979
  /* event associations */
980 9ebb11a9 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_ENABLE == true)
981 1a8fb642 Thomas Schöpping
  gpioeventflagsmask |= MODULE_SSSP_EVENTFLAG_PD | MODULE_SSSP_EVENTFLAG_S;
982 2920c6b7 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_START != true)
983 1a8fb642 Thomas Schöpping
  gpioeventflagsmask |= MODULE_SSSP_EVENTFLAG_DN;
984 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
985 2920c6b7 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_STACK_END != true)
986 1a8fb642 Thomas Schöpping
  gpioeventflagsmask |= MODULE_SSSP_EVENTFLAG_UP;
987 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
988
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
989 1a8fb642 Thomas Schöpping
  if (gpioeventflagsmask != 0) {
990
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, GPIOEVENT_MASK, gpioeventflagsmask);
991 2920c6b7 Thomas Schöpping
  }
992 6b53f6bf Thomas Schöpping
  chEvtRegisterMask(&aos.events.os, &_eventListenerOS, OSEVENT_MASK);
993 e545e620 Thomas Schöpping
994 7de40828 Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
995
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS)
996
  AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
997 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
998 7de40828 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_4();
999 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
1000
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4) */
1001 e545e620 Thomas Schöpping
1002 4c72a54c Thomas Schöpping
  /* periphery communication interfaces initialization */
1003 e545e620 Thomas Schöpping
  // module specific initialization (if any)
1004 4c72a54c Thomas Schöpping
#if defined(MODULE_INIT_PERIPHERY_IF)
1005
  MODULE_INIT_PERIPHERY_IF();
1006
#endif /* defined(MODULE_INIT_PERIPHERY_IF) */
1007 3106e8cc Thomas Schöpping
#if ((SSSP_STAGE3_ENABLE == true) && (HAL_USE_CAN == TRUE))
1008 75c1f470 Thomas Schöpping
  // CAN
1009
  if (MODULE_HAL_CAN.state == CAN_STOP) {
1010
    canStart(&MODULE_HAL_CAN, &moduleHalCanConfig);
1011
  }
1012 3106e8cc Thomas Schöpping
#endif /* (SSSP_STAGE3_ENABLE == true) && (HAL_USE_CAN == TRUE) */
1013 e545e620 Thomas Schöpping
  // user interface (if any)
1014 7de0cc90 Thomas Schöpping
#if defined(MODULE_HAL_PROGIF)
1015 ba516b61 Thomas Schöpping
  aosIOChannelInit(&_stdiochannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
1016
  aosIOChannelOutputEnable(&_stdiochannel);
1017
  aosIOStreamAddChannel(&aos.iostream, &_stdiochannel);
1018 47e89ebf Thomas Schöpping
#if (AMIROOS_CFG_SHELL_ENABLE == true)
1019 dd8738ea Thomas Schöpping
  aosShellChannelInit(&_stdshellchannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
1020 ba516b61 Thomas Schöpping
  aosShellChannelInputEnable(&_stdshellchannel);
1021
  aosShellChannelOutputEnable(&_stdshellchannel);
1022 6b53f6bf Thomas Schöpping
  aosShellStreamAddChannel(&aos.shell.stream, &_stdshellchannel);
1023 47e89ebf Thomas Schöpping
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
1024 7de0cc90 Thomas Schöpping
#endif /* defined(MODULE_HAL_PROGIF) */
1025 e545e620 Thomas Schöpping
1026 7de40828 Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5)
1027
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS)
1028
  AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
1029 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
1030 7de40828 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_5();
1031 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
1032
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5) */
1033 e545e620 Thomas Schöpping
1034
  /* module is ready -> print welcome prompt */
1035
  aosprintf("\n");
1036
  aosprintf("######################################################################\n");
1037
  aosprintf("# AMiRo-OS is an operating system designed for the Autonomous Mini   #\n");
1038
  aosprintf("# Robot (AMiRo) platform.                                            #\n");
1039 84f0ce9e Thomas Schöpping
  aosprintf("# Copyright (C) 2016..2019  Thomas Schöpping et al.                  #\n");
1040 e545e620 Thomas Schöpping
  aosprintf("#                                                                    #\n");
1041
  aosprintf("# This is free software; see the source for copying conditions.      #\n");
1042
  aosprintf("# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n");
1043
  aosprintf("# A PARTICULAR PURPOSE.                                              #\n");
1044
  aosprintf("# The development of this software was supported by the Excellence   #\n");
1045
  aosprintf("# Cluster EXC 227 Cognitive Interaction Technology. The Excellence   #\n");
1046
  aosprintf("# Cluster EXC 227 is a grant of the Deutsche Forschungsgemeinschaft  #\n");
1047
  aosprintf("# (DFG) in the context of the German Excellence Initiative.          #\n");
1048
  aosprintf("######################################################################\n");
1049
  aosprintf("\n");
1050
1051 7de40828 Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6)
1052
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS)
1053
  AMIROOS_CFG_MAIN_INIT_HOOK_6(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS);
1054 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS) */
1055 7de40828 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_6();
1056 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS) */
1057
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_6) */
1058 7de40828 Thomas Schöpping
1059
#if (AMIROOS_CFG_TESTS_ENABLE == true)
1060
#if defined(MODULE_INIT_TESTS)
1061
  MODULE_INIT_TESTS();
1062 7de0cc90 Thomas Schöpping
#else /* defined(MODULE_INIT_TESTS) */
1063
  #warning "AMIROOS_CFG_TESTS_ENABLE set to true, but MODULE_INIT_TESTS() not defined"
1064
#endif /* defined(MODULE_INIT_TESTS) */
1065
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
1066 7de40828 Thomas Schöpping
1067 e545e620 Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7)
1068
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS)
1069
  AMIROOS_CFG_MAIN_INIT_HOOK_7(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS);
1070 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS) */
1071 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_7();
1072 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS) */
1073
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_7) */
1074 e545e620 Thomas Schöpping
1075 9ebb11a9 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_ENABLE == true)
1076 6b53f6bf Thomas Schöpping
  /* SSSP startup OS synchronization phase (end of startup stage 2) */
1077 1a8fb642 Thomas Schöpping
  while ((shutdown == AOS_SHUTDOWN_NONE) && (eventmask = aosSysSsspStartupOsInitSyncCheck(&_eventListenerGPIO)) != 0) {
1078 e545e620 Thomas Schöpping
    /*
1079
     * This code is executed if the received event was not about the SYS_SYNC control signal.
1080
     * The returned event could be caused by any listener (not only the argument).
1081
     */
1082 1a8fb642 Thomas Schöpping
    // GPIO event
1083
    if (eventmask & _eventListenerGPIO.events) {
1084
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
1085 9461fadc Thomas Schöpping
      // PD event
1086 1a8fb642 Thomas Schöpping
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
1087 9461fadc Thomas Schöpping
        shutdown = AOS_SHUTDOWN_PASSIVE;
1088
      } else {
1089 7de0cc90 Thomas Schöpping
#if defined(MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK)
1090 9461fadc Thomas Schöpping
        MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(eventmask, eventflags);
1091 7de0cc90 Thomas Schöpping
#else /* defined(MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK) */
1092 9461fadc Thomas Schöpping
        // ignore any other IO events
1093 7de0cc90 Thomas Schöpping
#endif /* defined(MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK) */
1094 9461fadc Thomas Schöpping
      }
1095 e545e620 Thomas Schöpping
    }
1096 9461fadc Thomas Schöpping
    // OS event
1097 e545e620 Thomas Schöpping
    else if (eventmask & _eventListenerOS.events) {
1098
      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
1099
      _unexpectedEventError(eventmask, eventflags);
1100
    }
1101 9461fadc Thomas Schöpping
    // unknown event
1102 e545e620 Thomas Schöpping
    else {
1103 933df08e Thomas Schöpping
      _unexpectedEventError(eventmask, 0);
1104 e545e620 Thomas Schöpping
    }
1105
  }
1106
1107 75c1f470 Thomas Schöpping
#if (HAL_USE_CAN == TRUE)
1108
1109 933df08e Thomas Schöpping
  /*
1110
   * There must be no delays at this point, thus no hook is allowed.
1111
   */
1112
1113
  /* SSSP startup stage 3 (module stack initialization) */
1114 9461fadc Thomas Schöpping
  if (shutdown == AOS_SHUTDOWN_NONE) {
1115
    shutdown = _ssspModuleStackInitialization();
1116
  }
1117
1118
  /*
1119
   * There must be no delays at this point, thus no hook is allowed.
1120
   */
1121
1122 75c1f470 Thomas Schöpping
#if (HAL_USE_RTC == TRUE)
1123 9ebb11a9 Thomas Schöpping
  /* synchronize calendars */
1124 9461fadc Thomas Schöpping
  if (shutdown == AOS_SHUTDOWN_NONE) {
1125
#if (AMIROOS_CFG_SSSP_MASTER == true)
1126
    CANTxFrame frame;
1127
    struct tm t;
1128
    uint64_t encoded;
1129
1130
    frame.DLC = 8;
1131
    frame.RTR = CAN_RTR_DATA;
1132
    frame.IDE = CAN_IDE_STD;
1133
    frame.SID = CALENDERSYNC_CANMSGID;
1134
1135
    aosDbgPrintf("transmitting current date/time...\t");
1136
    // get current date & time
1137
    aosSysGetDateTime(&t);
1138
    // encode
1139
    encoded = _TM2U64(&t);
1140
    // serialize
1141
    _serialize(frame.data8, encoded, 8);
1142
    // transmit
1143
    canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, TIME_IMMEDIATE);
1144
1145
    aosDbgPrintf("done\n");
1146 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
1147 9461fadc Thomas Schöpping
    CANRxFrame frame;
1148
    uint64_t encoded;
1149
    struct tm t;
1150
1151
    aosDbgPrintf("receiving current date/time...\t");
1152
    // receive message
1153 0278542c Thomas Schöpping
#if (AMIROOS_CFG_DBG == true)
1154
    // increase timeout in debug mode due to additional delays introduced by the many prinf() calls
1155
    if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(10 * AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
1156 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_DBG == true) */
1157 1e5f7648 Thomas Schöpping
    if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
1158 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_DBG == true) */
1159 9461fadc Thomas Schöpping
      // validate message
1160
      if (frame.DLC == 8 &&
1161
          frame.RTR == CAN_RTR_DATA &&
1162
          frame.IDE == CAN_IDE_STD &&
1163
          frame.SID == CALENDERSYNC_CANMSGID) {
1164
        // deserialize
1165
        encoded = _deserialize(frame.data8, 8);
1166
        // decode
1167
        _U642TM(&t, encoded);
1168
        // set current date & time
1169
        aosSysSetDateTime(&t);
1170
        aosDbgPrintf("success\n");
1171
      } else {
1172
        aosDbgPrintf("fail (invalid message)\n");
1173
      }
1174
    } else {
1175
      aosDbgPrintf("fail (timeout)\n");
1176
    }
1177 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
1178 9461fadc Thomas Schöpping
    aosDbgPrintf("\n");
1179
  }
1180 75c1f470 Thomas Schöpping
#endif /* (HAL_USE_RTC == TRUE) */
1181
#endif /* (HAL_USE_CAN == TRUE) */
1182
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
1183 933df08e Thomas Schöpping
1184 e545e620 Thomas Schöpping
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8)
1185
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS)
1186
  AMIROOS_CFG_MAIN_INIT_HOOK_8(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS);
1187 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS) */
1188 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_8();
1189 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS) */
1190
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_8) */
1191 e545e620 Thomas Schöpping
1192
  /* completely start AMiRo-OS */
1193 933df08e Thomas Schöpping
  if (shutdown == AOS_SHUTDOWN_NONE) {
1194
    aosSysStart();
1195
  }
1196 e545e620 Thomas Schöpping
1197
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9)
1198
#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS)
1199
  AMIROOS_CFG_MAIN_INIT_HOOK_9(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS);
1200 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS) */
1201 e545e620 Thomas Schöpping
  AMIROOS_CFG_MAIN_INIT_HOOK_9();
1202 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS) */
1203
#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_9) */
1204 e545e620 Thomas Schöpping
1205
  /*
1206
   * ##########################################################################
1207
   * # infinite loop                                                          #
1208
   * ##########################################################################
1209
   */
1210
1211
  // sleep until a shutdown event is received
1212
  while (shutdown == AOS_SHUTDOWN_NONE) {
1213
    // wait for an event
1214
#if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0)
1215 1e5f7648 Thomas Schöpping
    eventmask = chEvtWaitOneTimeout(ALL_EVENTS, chTimeUS2I(AMIROOS_CFG_MAIN_LOOP_TIMEOUT));
1216 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0) */
1217 e545e620 Thomas Schöpping
    eventmask = chEvtWaitOne(ALL_EVENTS);
1218 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0) */
1219 e545e620 Thomas Schöpping
1220
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0)
1221
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS)
1222
    AMIROOS_CFG_MAIN_LOOP_HOOK_0(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS);
1223 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS) */
1224 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_LOOP_HOOK_0();
1225 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS) */
1226
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0) */
1227 e545e620 Thomas Schöpping
1228
    switch (eventmask) {
1229 1a8fb642 Thomas Schöpping
      // if this was an GPIO event
1230
      case GPIOEVENT_MASK:
1231 e545e620 Thomas Schöpping
        // evaluate flags
1232 1a8fb642 Thomas Schöpping
        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
1233 9ebb11a9 Thomas Schöpping
#if (AMIROOS_CFG_SSSP_ENABLE == true)
1234 e545e620 Thomas Schöpping
        // PD event
1235 1a8fb642 Thomas Schöpping
        if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
1236 e545e620 Thomas Schöpping
          shutdown = AOS_SHUTDOWN_PASSIVE;
1237
        }
1238
        // all other events
1239 1a8fb642 Thomas Schöpping
#if defined(MODULE_MAIN_LOOP_GPIOEVENT)
1240 e545e620 Thomas Schöpping
        else {
1241 1a8fb642 Thomas Schöpping
          MODULE_MAIN_LOOP_GPIOEVENT(eventflags);
1242 e545e620 Thomas Schöpping
        }
1243 1a8fb642 Thomas Schöpping
#endif /* defined(MODULE_MAIN_LOOP_GPIOEVENT) */
1244 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
1245 1a8fb642 Thomas Schöpping
#if defined(MODULE_MAIN_LOOP_GPIOEVENT)
1246
        MODULE_MAIN_LOOP_GPIOEVENT(eventflags);
1247
#endif /* defined(MODULE_MAIN_LOOP_GPIOEVENT) */
1248 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
1249 e545e620 Thomas Schöpping
        break;
1250
1251
      // if this was an OS event
1252 6b53f6bf Thomas Schöpping
      case OSEVENT_MASK:
1253 e545e620 Thomas Schöpping
        // evaluate flags
1254
        eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
1255
        switch (eventflags) {
1256 1d3e002f Thomas Schöpping
#if (AMIROOS_CFG_SSSP_ENABLE == true)
1257 e4379628 Thomas Schöpping
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_HIBERNATE:
1258 e545e620 Thomas Schöpping
            shutdown = AOS_SHUTDOWN_HIBERNATE;
1259
            break;
1260 e4379628 Thomas Schöpping
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_DEEPSLEEP:
1261 e545e620 Thomas Schöpping
            shutdown = AOS_SHUTDOWN_DEEPSLEEP;
1262
            break;
1263 e4379628 Thomas Schöpping
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_TRANSPORTATION:
1264 e545e620 Thomas Schöpping
            shutdown = AOS_SHUTDOWN_TRANSPORTATION;
1265
            break;
1266 e4379628 Thomas Schöpping
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_RESTART:
1267 e545e620 Thomas Schöpping
            shutdown = AOS_SHUTDOWN_RESTART;
1268
            break;
1269 7de0cc90 Thomas Schöpping
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
1270 e4379628 Thomas Schöpping
          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_MASK:
1271 1d3e002f Thomas Schöpping
            shutdown = AOS_SHUTDOWN_DEFAULT;
1272
            break;
1273 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
1274 e545e620 Thomas Schöpping
          default:
1275
            _unexpectedEventError(eventmask, eventflags);
1276
            break;
1277
        }
1278
        break;
1279
1280
      // if this was any other event (should be impossible to occur)
1281
      default:
1282
        eventflags = 0;
1283 41fc7088 Thomas Schöpping
#if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT == 0)
1284 e545e620 Thomas Schöpping
        _unexpectedEventError(eventmask, eventflags);
1285 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT == 0) */
1286 e545e620 Thomas Schöpping
        break;
1287
    }
1288
1289
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1)
1290
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS)
1291
    AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
1292 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
1293 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_LOOP_HOOK_1();
1294 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
1295
#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1) */
1296 e545e620 Thomas Schöpping
  }
1297
1298
  /*
1299
   * ##########################################################################
1300
   * # system shutdown                                                        #
1301
   * ##########################################################################
1302
   */
1303
1304
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0)
1305
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS)
1306
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS);
1307 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS) */
1308 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0();
1309 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS) */
1310
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0) */
1311 e545e620 Thomas Schöpping
1312
  // initialize/acknowledge shutdown
1313
  aosSysShutdownInit(shutdown);
1314
1315
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1)
1316
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS)
1317
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS);
1318 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS) */
1319 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1();
1320 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS) */
1321
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1) */
1322 e545e620 Thomas Schöpping
1323
  // stop system threads
1324
  aosSysStop();
1325
1326
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2)
1327
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS)
1328
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS);
1329 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS) */
1330 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2();
1331 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS) */
1332
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2) */
1333 e545e620 Thomas Schöpping
1334
  // deinitialize system
1335
  aosSysDeinit();
1336
1337
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3)
1338
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS)
1339
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS);
1340 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS) */
1341 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3();
1342 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS) */
1343
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3) */
1344 e545e620 Thomas Schöpping
1345 4c72a54c Thomas Schöpping
  /* stop all periphery communication interfaces */
1346
#if defined(MODULE_SHUTDOWN_PERIPHERY_IF)
1347
  MODULE_SHUTDOWN_PERIPHERY_IF();
1348
#endif /* defined(MODULE_SHUTDOWN_PERIPHERY_IF) */
1349 75c1f470 Thomas Schöpping
#if (HAL_USE_CAN == TRUE)
1350
  if (MODULE_HAL_CAN.state != CAN_STOP) {
1351
    canStop(&MODULE_HAL_CAN);
1352
  }
1353
#endif /* (HAL_USE_CAN == TRUE) */
1354 e545e620 Thomas Schöpping
1355
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4)
1356
#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS)
1357
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS);
1358 7de0cc90 Thomas Schöpping
#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS) */
1359 e545e620 Thomas Schöpping
    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4();
1360 7de0cc90 Thomas Schöpping
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS) */
1361
#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4) */
1362 e545e620 Thomas Schöpping
1363
  // finally hand over to bootloader
1364 1e5f7648 Thomas Schöpping
  aosSysShutdownFinal(shutdown);
1365 e545e620 Thomas Schöpping
1366
  /*
1367
   * ##########################################################################
1368
   * # after shutdown/restart                                                 #
1369
   * ##########################################################################
1370
   *
1371
   * NOTE: This code will not be executed, since the bootloader callbacks will stop/restart the MCU.
1372
   *       It is included nevertheless for the sake of completeness and to explicitely indicate,
1373
   *       which subsystems should NOT be shut down.
1374
   */
1375
1376
  // return an error, since this code should not be executed
1377
  return -1;
1378
}
1379 53710ca3 Marc Rothmann
1380 f3ac1c96 Thomas Schöpping
/******************************************************************************/
1381
/* EXPORTED FUNCTIONS                                                         */
1382
/******************************************************************************/
1383
1384 53710ca3 Marc Rothmann
/** @} */