Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ 7de0cc90

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