Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ 3106e8cc

History | View | Annotate | Download (52.005 KB)

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

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

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

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