Statistics
| Branch: | Tag: | Revision:

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

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