Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ ed19a68b

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