Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ 891fd122

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