commit cda1472944648652764c6980f5ee3f3e91459ef3
Author: Thomas Schöpping <tschoepp@cit-ec.uni-bielefeld.de>
Date:   Mon Oct 28 11:15:03 2019 +0100

    Major SSSP overhaul:
    - SSSP no works even without Bootloader (AMiRo-OS implements startup and shutdown phases)
    - MSI and calendar synchronization are currently not available (WIP)
    - lots of minor changes

diff --git a/core/src/aos_main.cpp b/core/src/aos_main.cpp
index 37a8c1c..d404768 100644
--- a/core/src/aos_main.cpp
+++ b/core/src/aos_main.cpp
@@ -19,8 +19,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /**
  * @file    aos_main.cpp
  * @brief   Main function.
- * @details Main function with SSSP and initialization,
- *          extendable via hooks.
  *
  * @addtogroup aos_system
  * @{
@@ -40,69 +38,24 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /******************************************************************************/
 
 /**
- * @brief   Event mask to identify I/O events.
+ * @brief   Event mask to identify GPIO events.
  */
-#define IOEVENT_MASK                            EVENT_MASK(0)
+#define EVENTMASK_GPIO                          EVENT_MASK(0)
 
 /**
  * @brief   Event mask to identify OS events.
  */
-#define OSEVENT_MASK                            EVENT_MASK(1)
+#define EVENTMASK_OS                            EVENT_MASK(1)
 
-/**
- * @brief   Event mask to idetify CAN events.
- */
-#define CANEVENT_MASK                           EVENT_MASK(2)
-
-/**
- * @brief   Event mask to idetify timeout events.
- */
-#define TIMEOUTEVENT_MASK                       EVENT_MASK(3)
-
-/**
- * @brief   Event mask to idetify signal delay events.
- */
-#define DELAYEVENT_MASK                         EVENT_MASK(4)
-
-#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_CAN == TRUE)) || defined(__DOXYGEN__)
-#define SSSP_STAGE3_ENABLE                      true
-#else /* (AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_CAN == TRUE) */
-#define SSSP_STAGE3_ENABLE                      false
-#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_CAN == TRUE) */
-
-#if (SSSP_STAGE3_ENABLE == true) || defined(__DOXYGEN__)
-
-/**
- * @brief   CAN message identifier for initialization of the SSSP stack initialization sequence.
- */
-#define SSSP_STACKINIT_CANMSGID_INIT            0x003
-
-/**
- * @brief   CAN message identifier for transmitting module IDs during the SSSP stack initialization sequence.
- */
-#define SSSP_STACKINIT_CANMSGID_MODULEID        0x002
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
 
 /**
- * @brief   CAN message identifier for abortion of the SSSP stack initialization sequence.
+ * @brief   Event mask to identify SSSP timer events.
  */
-#define SSSP_STACKINIT_CANMSGID_ABORT           0x001
+#define EVENTMASK_SSSPTIMER                     EVENT_MASK(2)
 
-#endif /* (SSSP_STAGE3_ENABLE == true) */
-
-#if (AMIROOS_CFG_SSSP_ENABLE != true) || defined(__DOXYGEN__)
-/**
- * @brief   Default shutdown mode if SSSP is unavailable.
- */
-#define AOS_SHUTDOWN_DEFAULT                    AOS_SHUTDOWN_DEEPSLEEP
 #endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
 
-#if (HAL_USE_CAN == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief   CAN message identifier for calender synchronization message.
- */
-#define CALENDERSYNC_CANMSGID                   0x004
-#endif /* (HAL_USE_CAN == TRUE) */
-
 /******************************************************************************/
 /* EXPORTED VARIABLES                                                         */
 /******************************************************************************/
@@ -116,9 +69,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /******************************************************************************/
 
 /**
- * @brief   Listener object for I/O events.
+ * @brief   Listener object for GPIO events.
  */
-static event_listener_t _eventListenerIO;
+static event_listener_t _eventListenerGPIO;
 
 /**
  * @brief   Listener object for OS events.
@@ -126,17 +79,21 @@ static event_listener_t _eventListenerIO;
 static event_listener_t _eventListenerOS;
 
 #if defined(MODULE_HAL_PROGIF) || defined(__DOXYGEN__)
+
 /**
  * @brief   I/O channel for the programmer interface.
  */
 static AosIOChannel _stdiochannel;
 
-#if (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
+#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
+
+#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
+
 /**
  * @brief   I/O shell channel for the programmer interface.
  */
 static AosShellChannel _stdshellchannel;
-#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true)*/
+
 #endif /* defined(MODULE_HAL_PROGIF) */
 
 /*
@@ -167,24 +124,6 @@ static inline void _unexpectedEventError(const eventmask_t mask, const eventflag
   return;
 }
 
-#if (SSSP_STAGE3_ENABLE == true) || defined(__DOXYGEN__)
-/**
- * @brief   Callback function to be used during SSSP stack initialization sequence.
- *
- * @param[in] par   A pointer to an @p event_source_t to be fired.
- */
-static void _ssspTimerCallback(void* par)
-{
-  aosDbgCheck(par != NULL);
-
-  chSysLockFromISR();
-  chEvtBroadcastI((event_source_t*)par);
-  chSysUnlockFromISR();
-
-  return;
-}
-#endif /* (SSSP_STAGE3_ENABLE == true) */
-
 /**
  * @brief   Helper function to serialize data.
  *
@@ -286,615 +225,6 @@ inline void _U642TM(struct tm* dst, const uint64_t src)
 
 #endif /* (HAL_USE_RTC == TRUE) */
 
-#if (SSSP_STAGE3_ENABLE) || defined(__DOXYGEN__)
-/**
- * @brief   Implementation of the SSSP module stack initialization sequence (startup phase 3).
- *
- * @return Shutdown value.
- * @retval AOS_SHUTDOWN_NONE      No shutdown signal received
- * @retval AOS_SHUTDOWN_PASSIVE   Shutdown signal received.
- */
-aos_shutdown_t _ssspModuleStackInitialization(void)
-{
-  // local types
-  /**
-   * @brief   States for the internal state machine to implement SSSP startup stage 3.
-   */
-  typedef enum {
-    STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
-    STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
-    STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
-    STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
-    STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
-    STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
-    STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
-    STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
-  } sssp_modulestackinitstage_t;
-
-  typedef struct {
-    bool loop     : 1;
-    bool wfe      : 1;
-    bool wfe_next : 1;
-  } flags_t;
-
-  // local variables
-  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
-  sssp_modulestackinitstage_t stage = STAGE_3_1;
-  eventmask_t eventmask = 0;
-  eventflags_t ioflags = 0;
-  event_source_t eventSourceTimeout;
-  event_source_t eventSourceDelay;
-  event_listener_t eventListenerTimeout;
-  event_listener_t eventListenerDelay;
-  event_listener_t eventListenerCan;
-  virtual_timer_t timerTimeout;
-  virtual_timer_t timerDelay;
-  CANTxFrame canTxFrame;
-  CANRxFrame canRxFrame;
-#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
-  aos_ssspmoduleid_t lastid = 0;
-#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true) */
-  flags_t flags;
-  aos_timestamp_t uptime;
-
-  // initialize local varibles
-  chEvtObjectInit(&eventSourceTimeout);
-  chEvtObjectInit(&eventSourceDelay);
-  chVTObjectInit(&timerTimeout);
-  chVTObjectInit(&timerDelay);
-  canTxFrame.RTR = CAN_RTR_DATA;
-  canTxFrame.IDE = CAN_IDE_STD;
-  flags.loop = true;
-  flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
-  flags.wfe_next = true;
-
-  // initialize system variables
-  aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
-  aos.sssp.moduleId = 0;
-
-  // listen to events (timout, delay, CAN receive)
-  chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
-  chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
-  chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
-
-  /*
-   * FSM in a loop.
-   *
-   * This is a fully event-based FSM for the module stack initialization
-   * sequence, defined by SSSP as startup stage 3. There are five different
-   * events that can occur at this point:
-   *  I/O events: The input level of an input pin has changed. Such events must
-   *              be handled differently depending on the current state. Most
-   *              of the time, however, such events can be ignored.
-   *  OS events:  Such events are only available after this stage completed and
-   *              thus should never occur. However, there is an optional hook
-   *              to handle such events, nevertheless.
-   *  CAN events: At least one CAN message was received. Note that this event
-   *              will only fire again if all input buffers have been cleared.
-   *  timeouts:   If some module does not support the sequence of there is any
-   *              issue, such a case is detected via timeouts and must be
-   *              handled accordingly (see abort state). In some cases, it is
-   *              possible that a timeout event occurres 'simultaneously' with
-   *              some other event. This can be caused by several timing issues
-   *              and is a valid situation. As a result, any other events
-   *              should be handled before the timeout event. If the other
-   *              events are expected and valid, this implementation requires
-   *              the timeout event flag to be cleared explicitely. Otherwise
-   *              it is evaluated at the end of each iteration of the loop.
-   *  delays:     Depending on the current state, delays are required by SSSP
-   *              for timing of the sequential activation of signals.
-   */
-  aosDbgPrintf("SSSP stack initialization sequence:\n");
-  while (flags.loop) {
-#if (AMIROOS_CFG_DBG == true)
-    switch (stage) {
-      case STAGE_3_1:
-        aosDbgPrintf(">>> 3-1\n");
-        break;
-      case STAGE_3_2:
-        aosDbgPrintf(">>> 3-2\n");
-        break;
-      case STAGE_3_3_WAITFORFIRSTID:
-        aosDbgPrintf(">>> 3-3 (1st ID)\n");
-        break;
-      case STAGE_3_3_WAITFORIDORSIG:
-        aosDbgPrintf(">>> 3-3 (ID/sig)\n");
-        break;
-      case STAGE_3_3_WAITFORID:
-        aosDbgPrintf(">>> 3-3 (ID)\n");
-        break;
-      case STAGE_3_4_FINISH:
-        aosDbgPrintf(">>> 3-4 (finish)\n");
-        break;
-      case STAGE_3_4_ABORT_ACTIVE:
-        aosDbgPrintf(">>> 3-4 (active abort)\n");
-        break;
-      case STAGE_3_4_ABORT:
-        aosDbgPrintf(">>> 3-4 (abort)\n");
-        break;
-    }
-#endif /* (AMIROOS_CFG_DBG == true) */
-
-    // reset wfe flag for the next iteration
-    flags.wfe_next = true;
-
-    // waiting for events (may be skipped)
-    if (flags.wfe) {
-      // wait for any event to occur
-      aosDbgPrintf("WFE...");
-      eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT));
-      aosDbgPrintf("\t0x%08X", eventmask);
-    } else {
-      aosDbgPrintf("WFE skipped");
-      eventmask = 0;
-    }
-    aosSysGetUptime(&uptime);
-    aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
-
-    /*
-     * execute some general tasks and high priority events
-     */
-    // no event occurred at all
-    if ((flags.wfe) && (eventmask == 0)) {
-      aosDbgPrintf("ERR: no evt\n");
-      // enforce timeout event
-      chEvtBroadcast(&eventSourceTimeout);
-      continue;
-    }
-    // if an IO event occurred
-    if (eventmask & _eventListenerIO.events) {
-      ioflags = chEvtGetAndClearFlags(&_eventListenerIO);
-      aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
-      // a power-down event occurred
-      if (ioflags & MODULE_SSSP_EVENTFLAGS_PD) {
-        aosDbgPrintf("PD evt\n");
-        // deactivate S and UP
-        aosDbgPrintf("disabling S\n");
-        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-#if (AMIROOS_CFG_SSSP_STACK_END != true)
-        aosDbgPrintf("disabling UP\n");
-        apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
-#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
-        // set shutdown flag and exit the loop
-        shutdown = AOS_SHUTDOWN_PASSIVE;
-        break;
-      }
-      // the S signal was deactivated
-      if (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC) {
-        apalControlGpioState_t sstate;
-        apalControlGpioGet(&moduleSsspGpioSync, &sstate);
-        if (sstate == APAL_GPIO_ON) {
-          aosDbgPrintf("S evt (enabled)\n");
-        } else {
-          aosDbgPrintf("S evt (disabled)\n");
-          // either finish or abort
-          if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
-            stage = STAGE_3_4_FINISH;
-          } else if (stage != STAGE_3_4_ABORT) {
-            stage = STAGE_3_4_ABORT_ACTIVE;
-          }
-        }
-      }
-    }
-    // an OS event occurred
-    if (eventmask & _eventListenerOS.events) {
-      aosDbgPrintf("WARN: OS evt\n");
-      // get the flags
-      eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
-      // there should be no OS events at this point
-#if defined(MODULE_SSSP_STARTUP_3_OSEVENT_HOOK)
-      MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
-#else /* defined(MODULE_SSSP_STARTUP_3_OSEVENT_HOOK) */
-      _unexpectedEventError(eventmask, oseventflags);
-#endif /* defined(MODULE_SSSP_STARTUP_3_OSEVENT_HOOK) */
-    }
-    // if a CAN event occurred
-    if ((eventmask & eventListenerCan.events)) {
-      aosDbgPrintf("CAN evt\n");
-      // fetch message
-      if (flags.wfe) {
-        canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
-        aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
-      }
-      // identify and handle abort messgaes
-      if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
-        stage = STAGE_3_4_ABORT;
-      }
-      // warn if a unexpected message was received
-      else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
-               (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
-        aosDbgPrintf("WARN: unknown msg\n");
-      }
-      // any further pending messages are fetched at the end of the loop
-    }
-    // if a timeout event occurred
-    if (eventmask & eventListenerTimeout.events) {
-      aosDbgPrintf("timeout evt\n");
-      // is handled at the end of the loop (or must be cleared by FSM)
-    }
-    // if a delay event occurred
-    if (eventmask & eventListenerDelay.events) {
-      aosDbgPrintf("delay evt\n");
-      // is handled by FSM
-    }
-
-    /*
-     * this is the actual FSM
-     */
-    switch (stage) {
-      case STAGE_3_1:
-      {
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
-
-        // there was no event at all (skipped wfe)
-        if (eventmask == 0 && flags.wfe == false) {
-#if (AMIROOS_CFG_SSSP_MASTER == true)
-          // initialize the stage by transmitting an according CAN message
-          aosDbgPrintf("CAN -> init\n");
-          canTxFrame.DLC = 0;
-          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_INIT;
-          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
-            chEvtBroadcast(&eventSourceTimeout);
-            break;
-          }
-          // activate S
-          aosDbgPrintf("enabling S\n");
-          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
-#if (AMIROOS_CFG_SSSP_STACK_START == true)
-          // proceed immediately
-          stage = STAGE_3_2;
-          flags.wfe_next = false;
-#else /* (AMIROOS_CFG_SSSP_STACK_START == true) */
-          // set the timeout timer
-          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-          // proceed
-          stage = STAGE_3_3_WAITFORFIRSTID;
-#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
-#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
-          // set the timeout timer
-          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
-        }
-
-#if (AMIROOS_CFG_SSSP_MASTER != true)
-        // a CAN message was received
-        else if (eventmask & eventListenerCan.events) {
-          // if an initiation message was received
-          if (canRxFrame.DLC == 0 &&
-              canRxFrame.RTR == CAN_RTR_DATA &&
-              canRxFrame.IDE == CAN_IDE_STD &&
-              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_INIT) {
-            aosDbgPrintf("init msg\n");
-            // reset the timeout timer and clear pending flags
-            chVTReset(&timerTimeout);
-            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-            eventmask &= ~(eventListenerTimeout.events);
-            // activate S
-            aosDbgPrintf("enabling S\n");
-            apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
-#if (AMIROOS_CFG_SSSP_STACK_START == true)
-            // proceed
-            stage = STAGE_3_2;
-            flags.wfe_next = false;
-#else /* (AMIROOS_CFG_SSSP_STACK_START == true) */
-            // set the timeout timer
-            chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-            // proceed
-            stage = STAGE_3_3_WAITFORFIRSTID;
-#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
-          }
-        }
-#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */
-
-        break;
-      } /* end of STAGE_3_1 */
-
-      case STAGE_3_2:
-      {
-#if (AMIROOS_CFG_SSSP_STACK_START == true)
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_2;
-
-        // if this stage was just entered
-        if (flags.wfe == false) {
-          // set the module ID
-          aos.sssp.moduleId = 1;
-          // broadcast module ID
-          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
-          canTxFrame.DLC = 4;
-          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
-          _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
-          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
-            chEvtBroadcast(&eventSourceTimeout);
-            break;
-          }
-#if (AMIROOS_CFG_DBG == true)
-          lastid = aos.sssp.moduleId;
-#endif /* (AMIROOS_CFG_DBG == true) */
-#if (AMIROOS_CFG_SSSP_STACK_END == true)
-          // sequence is already over
-          // deactivate S
-          aosDbgPrintf("disabling S\n");
-          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-          // proceed
-          stage = STAGE_3_3_WAITFORID;
-#else /* (AMIROOS_CFG_SSSP_STACK_END == true) */
-          // set the delay timer so the UP signal is activated later
-          chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
-#endif /* (AMIROOS_CFG_SSSP_STACK_END == true) */
-        }
-
-        // if a delay event occurred
-        if (eventmask & eventListenerDelay.events) {
-          // activate UP
-          aosDbgPrintf("enabling UP\n");
-          apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
-          // deactivate S
-          aosDbgPrintf("disabling S\n");
-          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-          // explicitely clear timeout event flag
-          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-          eventmask &= ~(eventListenerTimeout.events);
-          // proceed
-          stage = STAGE_3_3_WAITFORID;
-        }
-#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
-
-        break;
-      } /* end of STAGE_3_2 */
-
-      case STAGE_3_3_WAITFORFIRSTID:
-      {
-#if (AMIROOS_CFG_SSSP_STACK_START != true)
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
-
-        // a CAN message was received
-        if (eventmask & eventListenerCan.events) {
-          // if an ID message was received
-          if (canRxFrame.DLC == 4 &&
-              canRxFrame.RTR == CAN_RTR_DATA &&
-              canRxFrame.IDE == CAN_IDE_STD &&
-              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
-            aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
-            // validate received ID
-            if (lastid < _deserialize(canRxFrame.data8, 4)) {
-              // store received ID
-              lastid = _deserialize(canRxFrame.data8, 4);
-              // restart timeout timer
-              chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-              // proceed
-              stage = STAGE_3_3_WAITFORIDORSIG;
-            } else {
-              aosDbgPrintf("ERR: invalid ID\n");
-              // abort
-              stage = STAGE_3_4_ABORT_ACTIVE;
-              flags.wfe_next = false;
-            }
-            // explicitely clear timeout event flag
-            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-            eventmask &= ~(eventListenerTimeout.events);
-          }
-        }
-#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
-        break;
-      } /* end of STAGE_3_3_WAITFORFIRSTID */
-
-      case STAGE_3_3_WAITFORIDORSIG:
-      {
-#if (AMIROOS_CFG_SSSP_STACK_START != true)
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
-
-        // a CAN message was received
-        if (eventmask & eventListenerCan.events) {
-          // if an ID message was received
-          if (canRxFrame.DLC == 4 &&
-              canRxFrame.RTR == CAN_RTR_DATA &&
-              canRxFrame.IDE == CAN_IDE_STD &&
-              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
-            aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
-            // validate received ID
-            if (lastid < _deserialize(canRxFrame.data8, 4)) {
-              // store received ID
-              lastid = _deserialize(canRxFrame.data8, 4);
-              // restart timeout timer
-              chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-            } else {
-              aosDbgPrintf("ERR: invalid ID\n");
-              // abort
-              stage = STAGE_3_4_ABORT_ACTIVE;
-              flags.wfe_next = false;
-            }
-            // explicitely clear timeout event flag
-            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-            eventmask &= ~(eventListenerTimeout.events);
-          }
-        }
-
-        // if an IO event was received (DN signal)
-        if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_DN)) {
-          aosDbgPrintf("DN evt\n");
-          // reset timeout timer
-          chVTReset(&timerTimeout);
-          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-          eventmask &= ~(eventListenerTimeout.events);
-          // increment and broadcast ID
-          aos.sssp.moduleId = lastid + 1;
-          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
-          canTxFrame.DLC = 4;
-          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
-          _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
-          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
-            chEvtBroadcast(&eventSourceTimeout);
-            break;
-          }
-          // set delay timer
-          chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
-        }
-
-        // if a delay event occurred
-        if (eventmask & eventListenerDelay.events) {
-#if (AMIROOS_CFG_SSSP_STACK_END != true)
-          // activate UP
-          aosDbgPrintf("enabling UP\n");
-          apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
-#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
-          // deactivate S
-          aosDbgPrintf("disabling S\n");
-          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-          // reset the timeout timer
-          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-          eventmask &= ~(eventListenerTimeout.events);
-          // proceed
-          stage = STAGE_3_3_WAITFORID;
-        }
-#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
-
-        break;
-      } /* end of STAGE_3_3_WAITFORIDORSIG */
-
-      case STAGE_3_3_WAITFORID:
-      {
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
-
-#if (AMIROOS_CFG_SSSP_STACK_END != true)
-        // a CAN message was received
-        if (eventmask & eventListenerCan.events) {
-          // if an ID message was received
-          if (canRxFrame.DLC == 4 &&
-              canRxFrame.RTR == CAN_RTR_DATA &&
-              canRxFrame.IDE == CAN_IDE_STD &&
-              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
-#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
-            // Plausibility of the received ID is not checked at this point but is done by other modules still in a previous stage.
-            lastid = _deserialize(canRxFrame.data8, 4);
-            aosDbgPrintf("ID (%u)\n", lastid);
-#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true) */
-            // restart timeout timer
-            chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-            eventmask &= ~(eventListenerTimeout.events);
-          }
-        }
-#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
-
-        break;
-      } /* end of STAGE_3_3_WAITFORID */
-
-      case STAGE_3_4_FINISH:
-      {
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
-
-        // if an IO event was received (S signal)
-        if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
-          // reset the timeout timer
-          chVTReset(&timerTimeout);
-          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-          eventmask &= ~(eventListenerTimeout.events);
-          //set the delay timer
-          chVTSet(&timerDelay, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceDelay);
-        }
-
-        // if a CAN event was received
-        if (eventmask & eventListenerCan.events) {
-          // if an abort message was received
-          if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
-            aosDbgPrintf("abort msg\n");
-            // reset the delay timer
-            chVTReset(&timerDelay);
-            chEvtWaitAnyTimeout(eventListenerDelay.events, TIME_IMMEDIATE);
-            eventmask &= ~(eventListenerDelay.events);
-            // proceed
-            stage = STAGE_3_4_ABORT;
-          }
-        }
-
-        // if a delay timer event occurred
-        if (eventmask & eventListenerDelay.events) {
-          aosDbgPrintf("sequence sucessful\n");
-          // sequence finished sucessfully
-          flags.loop = false;
-        }
-
-        break;
-      } /* end of STAGE_3_4_FINISH */
-
-      case STAGE_3_4_ABORT_ACTIVE:
-      {
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
-
-        // emit abort message
-        canTxFrame.DLC = 0;
-        canTxFrame.SID = SSSP_STACKINIT_CANMSGID_ABORT;
-        canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_INFINITE);
-        aosDbgPrintf("CAN -> abort\n");
-        // clear timeout flag
-        eventmask &= ~(eventListenerTimeout.events);
-        // proceed immediately
-        stage = STAGE_3_4_ABORT;
-        flags.wfe_next = false;
-        break;
-      } /* end of STAGE_3_4_ABORT_ACTIVE */
-
-      case STAGE_3_4_ABORT:
-      {
-        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
-
-        // deactivate S
-        aosDbgPrintf("disabling SYNC\n");
-        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-        // invalidate module ID
-        aos.sssp.moduleId = 0;
-
-        // if an IO event was received (S signal)
-        if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
-          aosDbgPrintf("sequence aborted\n");
-          // exit the sequence
-          flags.loop = false;
-        }
-
-        break;
-      } /* end of STAGE_3_4_ABORT */
-    } /* end of switch(stage) */
-
-    // fetch pending CAN message (if any)
-    if ((eventmask & eventListenerCan.events) && (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE) == MSG_OK)) {
-      aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
-      flags.wfe_next = false;
-    }
-
-    // handle unhandled timeout events
-    if (eventmask & eventListenerTimeout.events) {
-      aosDbgPrintf("ERR: timeout evt\n");
-      // abort
-      flags.wfe_next = false;
-      stage = STAGE_3_4_ABORT_ACTIVE;
-    }
-
-    // apply wfe value for next iteration
-    flags.wfe = flags.wfe_next;
-  } /* end of FSM loop */
-
-  // unregister all events (timeout, delay, CAN receive)
-  chEvtUnregister(&eventSourceTimeout, &eventListenerTimeout);
-  chEvtUnregister(&eventSourceDelay, &eventListenerDelay);
-  chEvtUnregister(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan);
-  // clear any pending events (timeout, delay, CAN receive)
-  chEvtWaitAllTimeout(TIMEOUTEVENT_MASK | DELAYEVENT_MASK | CANEVENT_MASK, TIME_IMMEDIATE);
-
-  // reset all control signals
-#if (AMIROOS_CFG_SSSP_STACK_END != true)
-  aosDbgPrintf("disabling UP\n");
-  apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
-#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
-  aosDbgPrintf("disabling S\n");
-  apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-  aosSysGetUptime(&uptime);
-  aosDbgPrintf("done\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
-
-  return shutdown;
-}
-#endif /* (SSSP_STAGE3_ENABLE == true) */
-
 /**
  * @brief   Application entry point.
  */
@@ -903,7 +233,6 @@ int main(void)
   // local variables
   eventmask_t eventmask = 0;
   eventflags_t eventflags = 0;
-  eventflags_t ioeventflagsmask = AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK;
   aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
 #if defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES)
   AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES
@@ -915,14 +244,6 @@ int main(void)
    * ##########################################################################
    */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_0(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_0();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_0) */
-
   /* hardware, kernel, and operating system initialization */
   // ChibiOS/HAL and custom hal additions (if any)
   halInit();
@@ -930,34 +251,18 @@ int main(void)
   MODULE_INIT_HAL_EXTRA();
 #endif /* defined(MODULE_INIT_HAL_EXTRA) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_1();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1) */
-
   // ChibiOS/RT kernel and custom kernel additions (if any)
   chSysInit();
 #if defined(MODULE_INIT_KERNEL_EXTRA)
   MODULE_INIT_KERNEL_EXTRA();
 #endif /* defined(MODULE_INIT_KERNEL_EXTRA) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_2();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2) */
-
   // AMiRo-OS, additional interrupts and custom OS additions (if any)
-#if (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true)
+#if (AMIROOS_CFG_SHELL_ENABLE == true)
   aosSysInit(moduleShellPrompt);
-#else /* (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true) */
+#else /* (AMIROOS_CFG_SHELL_ENABLE == true) */
   aosSysInit();
-#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true) */
+#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
 #if defined(MODULE_INIT_INTERRUPTS)
   MODULE_INIT_INTERRUPTS();
 #endif
@@ -965,68 +270,213 @@ int main(void)
   MODULE_INIT_OS_EXTRA();
 #endif /* defined(MODULE_INIT_OS_EXTRA) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_3();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3) */
-
   /* event associations */
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
-  ioeventflagsmask |= MODULE_SSSP_EVENTFLAGS_PD | MODULE_SSSP_EVENTFLAGS_SYNC;
+  {
+    eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | MODULE_SSSP_EVENTFLAG_PD | MODULE_SSSP_EVENTFLAG_S;
 #if (AMIROOS_CFG_SSSP_STACK_START != true)
-  ioeventflagsmask |= MODULE_SSSP_EVENTFLAGS_DN;
+    flagsmask |= MODULE_SSSP_EVENTFLAG_DN;
 #endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
 #if (AMIROOS_CFG_SSSP_STACK_END != true)
-  ioeventflagsmask |= MODULE_SSSP_EVENTFLAGS_UP;
+    flagsmask |= MODULE_SSSP_EVENTFLAG_UP;
 #endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
+    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, flagsmask);
+  }
+#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
+  if (AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK) {
+    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK);
+  }
 #endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
-  if (ioeventflagsmask != 0) {
-    chEvtRegisterMaskWithFlags(&aos.events.io, &_eventListenerIO, IOEVENT_MASK, ioeventflagsmask);
+  chEvtRegisterMask(&aos.events.os, &_eventListenerOS, EVENTMASK_OS);
+
+#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_STARTUP == true)
+
+  /* perform SSSP basic initialization stage */
+
+#if defined(MODULE_SSSP_BASICINIT_HOOK)
+#if defined(MODULE_SSSP_BASICINIT_HOOK_ARGS)
+  MODULE_SSSP_BASICINIT_HOOK(MODULE_SSSP_BASICINIT_HOOK_ARGS);
+#else /* defined(MODULE_SSSP_BASICINIT_HOOK_ARGS) */
+  MODULE_SSSP_BASICINIT_HOOK();
+#endif /* defined(MODULE_SSSP_BASICINIT_HOOK_ARGS) */
+#endif /* defined(MODULE_SSSP_BASICINIT_HOOK) */
+
+  // proceed to startup stage 1.2
+#if (AMIROOS_CFG_SSSP_MASTER == true)
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
+    /*
+     * This code is executed if the received event was not about the delay.
+     * The received event could be casued by any listener.
+     */
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+      // PD event
+      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
+        shutdown = AOS_SHUTDOWN_PASSIVE;
+      } else {
+#if defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK)
+        MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK) */
+      }
+    }
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
   }
-  chEvtRegisterMask(&aos.events.os, &_eventListenerOS, OSEVENT_MASK);
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_2);
+  }
+#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    aosSsspProceed(NULL, 0, 0, NULL);
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_2);
+  }
+#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_4();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4) */
+  // proceed to startup stage 1.3
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
+    /*
+     * This code is executed if the received event was not about a deactivation of the snychronization signal.
+     * The received event could be caused by any listener.
+     */
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+      // PD event
+      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
+        shutdown = AOS_SHUTDOWN_PASSIVE;
+      } else {
+#if defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK)
+        MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
+      }
+    }
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
+  }
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_3);
+  }
+
+  // proceed to startup stage 2.1
+#if (AMIROOS_CFG_SSSP_MASTER == true)
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
+    /*
+     * This code is executed if the received event was not about the delay.
+     * The received event could be caused by any listener.
+     */
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+      // PD event
+      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
+        shutdown = AOS_SHUTDOWN_PASSIVE;
+      } else {
+#if defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK)
+        MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
+      }
+    }
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
+  }
+#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCES)) {
+    /*
+     * This code is executed if the received event was not about a deactivation of the snychronization signal.
+     * The received event could be caused by any listener.
+     */
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+      // PD event
+      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
+        shutdown = AOS_SHUTDOWN_PASSIVE;
+      } else {
+#if defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK)
+        MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK) */
+      }
+    }
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
+  }
+#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_1);
+  }
+
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_STARTUP == true) */
+
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1)
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS)
+  AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
+  AMIROOS_CFG_MAIN_INIT_HOOK_1();
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_1) */
 
   /* periphery communication interfaces initialization */
-  // module specific initialization (if any)
 #if defined(MODULE_INIT_PERIPHERY_IF)
+  // module specific initialization
   MODULE_INIT_PERIPHERY_IF();
 #endif /* defined(MODULE_INIT_PERIPHERY_IF) */
-#if ((SSSP_STAGE3_ENABLE == true) && (HAL_USE_CAN == TRUE))
-  // CAN
-  if (MODULE_HAL_CAN.state == CAN_STOP) {
-    canStart(&MODULE_HAL_CAN, &moduleHalCanConfig);
-  }
-#endif /* (SSSP_STAGE3_ENABLE == true) && (HAL_USE_CAN == TRUE) */
-  // user interface (if any)
 #if defined(MODULE_HAL_PROGIF)
+  // user interface
   aosIOChannelInit(&_stdiochannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
   aosIOChannelOutputEnable(&_stdiochannel);
   aosIOStreamAddChannel(&aos.iostream, &_stdiochannel);
-#if (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true)
+#if (AMIROOS_CFG_SHELL_ENABLE == true)
   aosShellChannelInit(&_stdshellchannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
   aosShellChannelInputEnable(&_stdshellchannel);
   aosShellChannelOutputEnable(&_stdshellchannel);
   aosShellStreamAddChannel(&aos.shell.stream, &_stdshellchannel);
-#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true) */
+#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
 #endif /* defined(MODULE_HAL_PROGIF) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_5();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5) */
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2)
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS)
+  AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
+  AMIROOS_CFG_MAIN_INIT_HOOK_2();
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_2) */
 
   /* module is ready -> print welcome prompt */
   aosprintf("\n");
@@ -1045,13 +495,13 @@ int main(void)
   aosprintf("######################################################################\n");
   aosprintf("\n");
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_6(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_6();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_6) */
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3)
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS)
+  AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
+  AMIROOS_CFG_MAIN_INIT_HOOK_3();
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_3) */
 
 #if (AMIROOS_CFG_TESTS_ENABLE == true)
 #if defined(MODULE_INIT_TESTS)
@@ -1061,33 +511,35 @@ int main(void)
 #endif /* defined(MODULE_INIT_TESTS) */
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_7(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_7();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_7) */
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS)
+  AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
+  AMIROOS_CFG_MAIN_INIT_HOOK_4();
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_4) */
 
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
-  /* SSSP startup OS synchronization phase (end of startup stage 2) */
-  while ((shutdown == AOS_SHUTDOWN_NONE) && (eventmask = aosSysSsspStartupOsInitSyncCheck(&_eventListenerIO)) != 0) {
+
+  // proceed to startup stage 2.2
+#if (AMIROOS_CFG_SSSP_MASTER == true)
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
     /*
-     * This code is executed if the received event was not about the SYS_SYNC control signal.
-     * The returned event could be caused by any listener (not only the argument).
+     * This code is executed if the received event was not about the delay.
+     * The received event could be caused by any listener.
      */
-    // IO event
-    if (eventmask & _eventListenerIO.events) {
-      eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
       // PD event
-      if (eventflags & MODULE_SSSP_EVENTFLAGS_PD) {
+      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
         shutdown = AOS_SHUTDOWN_PASSIVE;
       } else {
-#if defined(MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK)
-        MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(eventmask, eventflags);
-#else /* defined(MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK) */
-        // ignore any other IO events
-#endif /* defined(MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK) */
+#if defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK)
+        MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK) */
       }
     }
     // OS event
@@ -1100,104 +552,81 @@ int main(void)
       _unexpectedEventError(eventmask, 0);
     }
   }
-
-#if (HAL_USE_CAN == TRUE)
-
-  /*
-   * There must be no delays at this point, thus no hook is allowed.
-   */
-
-  /* SSSP startup stage 3 (module stack initialization) */
   if (shutdown == AOS_SHUTDOWN_NONE) {
-    shutdown = _ssspModuleStackInitialization();
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_2);
   }
-
-  /*
-   * There must be no delays at this point, thus no hook is allowed.
-   */
-
-#if (HAL_USE_RTC == TRUE)
-  /* synchronize calendars */
-  if (shutdown == AOS_SHUTDOWN_NONE) {
-#if (AMIROOS_CFG_SSSP_MASTER == true)
-    CANTxFrame frame;
-    struct tm t;
-    uint64_t encoded;
-
-    frame.DLC = 8;
-    frame.RTR = CAN_RTR_DATA;
-    frame.IDE = CAN_IDE_STD;
-    frame.SID = CALENDERSYNC_CANMSGID;
-
-    aosDbgPrintf("transmitting current date/time...\t");
-    // get current date & time
-    aosSysGetDateTime(&t);
-    // encode
-    encoded = _TM2U64(&t);
-    // serialize
-    _serialize(frame.data8, encoded, 8);
-    // transmit
-    canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, TIME_IMMEDIATE);
-
-    aosDbgPrintf("done\n");
 #else /* (AMIROOS_CFG_SSSP_MASTER == true) */
-    CANRxFrame frame;
-    uint64_t encoded;
-    struct tm t;
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    aosSsspProceed(NULL, 0, 0, NULL);
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_2);
+  }
+#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
 
-    aosDbgPrintf("receiving current date/time...\t");
-    // receive message
-#if (AMIROOS_CFG_DBG == true)
-    // increase timeout in debug mode due to additional delays introduced by the many prinf() calls
-    if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(10 * AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
-#else /* (AMIROOS_CFG_DBG == true) */
-    if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
-#endif /* (AMIROOS_CFG_DBG == true) */
-      // validate message
-      if (frame.DLC == 8 &&
-          frame.RTR == CAN_RTR_DATA &&
-          frame.IDE == CAN_IDE_STD &&
-          frame.SID == CALENDERSYNC_CANMSGID) {
-        // deserialize
-        encoded = _deserialize(frame.data8, 8);
-        // decode
-        _U642TM(&t, encoded);
-        // set current date & time
-        aosSysSetDateTime(&t);
-        aosDbgPrintf("success\n");
+  // proceed to startup stage 3 (MSI is enabled), or to operation phase (no MSI)
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
+    /*
+     * This code is executed if the received event was not about a deactivation of the snychronization signal.
+     * The received event could be caused by any listener.
+     */
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+      // PD event
+      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
+        shutdown = AOS_SHUTDOWN_PASSIVE;
       } else {
-        aosDbgPrintf("fail (invalid message)\n");
+#if defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK)
+        MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK) */
       }
-    } else {
-      aosDbgPrintf("fail (timeout)\n");
     }
-#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
-    aosDbgPrintf("\n");
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
+  }
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+#if (AMIROOS_CFG_SSSP_MSI == true)
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_1);
+#else /* (AMIROOS_CFG_SSSP_MSI == true) */
+    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_OPERATION);
+#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
   }
-#endif /* (HAL_USE_RTC == TRUE) */
-#endif /* (HAL_USE_CAN == TRUE) */
-#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_8(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_8();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_8) */
+  // start the internal system uptime counter
+  aosSysStartUptime();
+
+  /*
+   * There must be no delays at this point, thus no hook allowed.
+   */
+
+#if (AMIROOS_CFG_SSSP_MSI == true)
+
+  //TODO
+
+#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
+
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
 
   /* completely start AMiRo-OS */
   if (shutdown == AOS_SHUTDOWN_NONE) {
     aosSysStart();
   }
 
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9)
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS)
-  AMIROOS_CFG_MAIN_INIT_HOOK_9(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS) */
-  AMIROOS_CFG_MAIN_INIT_HOOK_9();
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_9) */
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5)
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS)
+  AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
+  AMIROOS_CFG_MAIN_INIT_HOOK_5();
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_INIT_HOOK_5) */
 
   /*
    * ##########################################################################
@@ -1214,60 +643,64 @@ int main(void)
     eventmask = chEvtWaitOne(ALL_EVENTS);
 #endif /* (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0) */
 
-#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0)
-#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS)
-    AMIROOS_CFG_MAIN_LOOP_HOOK_0(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS) */
-    AMIROOS_CFG_MAIN_LOOP_HOOK_0();
-#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0) */
+#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1)
+#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS)
+    AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
+    AMIROOS_CFG_MAIN_LOOP_HOOK_1();
+#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1) */
 
     switch (eventmask) {
-      // if this was an I/O event
-      case IOEVENT_MASK:
+      // if this was an GPIO event
+      case EVENTMASK_GPIO:
         // evaluate flags
-        eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
+        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
         // PD event
-        if (eventflags & MODULE_SSSP_EVENTFLAGS_PD) {
+        if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
+          aosSsspShutdownInit();
           shutdown = AOS_SHUTDOWN_PASSIVE;
         }
         // all other events
-#if defined(MODULE_MAIN_LOOP_IO_EVENT)
+#if defined(MODULE_MAIN_LOOP_GPIOEVENT)
         else {
-          MODULE_MAIN_LOOP_IO_EVENT(eventflags);
+          MODULE_MAIN_LOOP_GPIOEVENT(eventflags);
         }
-#endif /* defined(MODULE_MAIN_LOOP_IO_EVENT) */
+#endif /* defined(MODULE_MAIN_LOOP_GPIOEVENT) */
 #else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
-#if defined(MODULE_MAIN_LOOP_IO_EVENT)
-        MODULE_MAIN_LOOP_IO_EVENT(eventflags);
-#endif /* defined(MODULE_MAIN_LOOP_IO_EVENT) */
+#if defined(MODULE_MAIN_LOOP_GPIOEVENT)
+        MODULE_MAIN_LOOP_GPIOEVENT(eventflags);
+#endif /* defined(MODULE_MAIN_LOOP_GPIOEVENT) */
 #endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
         break;
 
       // if this was an OS event
-      case OSEVENT_MASK:
+      case EVENTMASK_OS:
         // evaluate flags
         eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
         switch (eventflags) {
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-          case AOS_SYSTEM_EVENTFLAGS_HIBERNATE:
+#if (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_NONE)
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_MASK:
+            shutdown = AOS_SHUTDOWN_ACTIVE;
+            break;
+#elif (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_AMiRoBLT)
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_HIBERNATE:
             shutdown = AOS_SHUTDOWN_HIBERNATE;
             break;
-          case AOS_SYSTEM_EVENTFLAGS_DEEPSLEEP:
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_DEEPSLEEP:
             shutdown = AOS_SHUTDOWN_DEEPSLEEP;
             break;
-          case AOS_SYSTEM_EVENTFLAGS_TRANSPORTATION:
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_TRANSPORTATION:
             shutdown = AOS_SHUTDOWN_TRANSPORTATION;
             break;
-          case AOS_SYSTEM_EVENTFLAGS_RESTART:
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_RESTART:
             shutdown = AOS_SHUTDOWN_RESTART;
             break;
-#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
-          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN:
-            shutdown = AOS_SHUTDOWN_DEFAULT;
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN_PASSIVE:
+            _unexpectedEventError(eventmask, eventflags);
             break;
-#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
+#endif /* (AMIROOS_CFG_BOOTLOADER == X) */
           default:
             _unexpectedEventError(eventmask, eventflags);
             break;
@@ -1283,13 +716,13 @@ int main(void)
         break;
     }
 
-#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1)
-#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS)
-    AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
-    AMIROOS_CFG_MAIN_LOOP_HOOK_1();
-#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1) */
+#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2)
+#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS)
+    AMIROOS_CFG_MAIN_LOOP_HOOK_2(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS);
+#else /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS) */
+    AMIROOS_CFG_MAIN_LOOP_HOOK_2();
+#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS) */
+#endif /* defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2) */
   }
 
   /*
@@ -1298,33 +731,30 @@ int main(void)
    * ##########################################################################
    */
 
-#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0)
-#if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS)
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS);
-#else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS) */
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0();
-#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0_ARGS) */
-#endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_0) */
+  aosDbgAssert(shutdown != AOS_SHUTDOWN_NONE);
 
   // initialize/acknowledge shutdown
   aosSysShutdownInit(shutdown);
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
+  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_1_2);
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS)
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS);
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS);
 #else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS) */
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1();
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1();
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS) */
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1) */
 
-  // stop system threads
+  // wait for all threads to terminate
   aosSysStop();
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS)
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS);
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS);
 #else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS) */
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2();
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2();
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS) */
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2) */
 
@@ -1333,9 +763,9 @@ int main(void)
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS)
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS);
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS);
 #else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS) */
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3();
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3();
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS) */
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3) */
 
@@ -1343,35 +773,155 @@ int main(void)
 #if defined(MODULE_SHUTDOWN_PERIPHERY_IF)
   MODULE_SHUTDOWN_PERIPHERY_IF();
 #endif /* defined(MODULE_SHUTDOWN_PERIPHERY_IF) */
-#if (HAL_USE_CAN == TRUE)
-  if (MODULE_HAL_CAN.state != CAN_STOP) {
-    canStop(&MODULE_HAL_CAN);
-  }
-#endif /* (HAL_USE_CAN == TRUE) */
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS)
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS);
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS);
 #else /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS) */
-    AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4();
+  AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4();
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4_ARGS) */
 #endif /* defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4) */
 
-  // finally hand over to bootloader
-  aosSysShutdownFinal(shutdown);
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
+
+  // proceed to SSSP shutdown stage 1.3
+  aosSsspProceed(NULL, 0, 0, NULL);
+  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_1_3);
+
+#if (AMIROOS_CFG_SSSP_SHUTDOWN == true)
+
+  /* AMiRo-OS performs SSSP shutdown phase
+   * NOTE:
+   * The initiating module could deactivate PD at this point to indicate a restart rather than a shutdown request.
+   * AMiRo-OS does not support restart though, thus the signal is not changed.
+   */
+
+  // proceed to SSSP shutdown stage 2.1
+  while (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS) {
+    /*
+     * This code is executed if the received event was not about a deactivation of the synchronization signal.
+     * The received event could be caused by any listener.
+     */
+    // GPIO event
+    if (eventmask & _eventListenerGPIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+#if defined(MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK)
+        MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_SHUTDOWN_1_3_GPIOEVENT_HOOK) */
+    }
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
+  }
+  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_1);
+
+  // proceed to SSSP shutdown stage 2.2
+  aosSsspProceed(NULL, 0, 0, &eventmask);
+  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_2);
+  if (shutdown == AOS_SHUTDOWN_PASSIVE) {
+    aosDbgPrintf("%s request received\n", eventmask ? "shutdown" : "restart");
+  }
+  /* NOTE:
+   * Actually the call of aosSsspProceed() returned an indicator, whether a shutdown or restart has been initiated.
+   * Since AMiRo-OS does not support restart, this return value is ignored and shutdown is assumed.
+   */
+
+  // the initiating module broadcasts the shutdown identifier
+  if (shutdown != AOS_SHUTDOWN_PASSIVE) {
+    // since AMiRo-OS does not support multiple ways to shutdown or restart, the special identifier 0 is broadcasted.
+    aosSsspShutdownBroadcastIdentifier(0);
+  }
+  // passive modules receive the broadcasted identifier
+  else {
+    unsigned int identifier = 0;
+
+    // receive the identifier, which specifies the type of shutdown/restart
+    while ((eventmask = aosSsspShutdownWaitForIdentifierPulse(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_SSSPTIMER, &identifier)) != EVENTMASK_SSSPTIMER) {
+      // GPIO event
+      if (eventmask & _eventListenerGPIO.events) {
+        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
+#if defined(MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK)
+        MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK(eventmask, eventflags);
+#else /* defined(MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK) */
+        /* silently ignore any other GPIO events */
+#endif /* defined(MODULE_SSSP_SHUTDOWN_2_2_GPIOEVENT_HOOK) */
+        /* silently ignore any GPIO events */
+      }
+      // OS event
+      else if (eventmask & _eventListenerOS.events) {
+        eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+        _unexpectedEventError(eventmask, eventflags);
+      }
+      // unknown event
+      else {
+        _unexpectedEventError(eventmask, 0);
+      }
+    }
+
+    // Since AMiRo-OS does not support multiple ways to shutdown or restart, the identifier is ignored.
+  }
+
+  // proceed to SSSP shutdown stage 2.3
+  aosSsspProceed(NULL, 0, 0, NULL);
+  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_3);
 
   /*
-   * ##########################################################################
-   * # after shutdown/restart                                                 #
-   * ##########################################################################
-   *
-   * NOTE: This code will not be executed, since the bootloader callbacks will stop/restart the MCU.
-   *       It is included nevertheless for the sake of completeness and to explicitely indicate,
-   *       which subsystems should NOT be shut down.
+   * Since AMiRo-OS does only support one basic shutdown and no restart at all, the final shutdown is kept very simple.
    */
 
-  // return an error, since this code should not be executed
-  return -1;
+  // disable interrupts
+  irqDeinit();
+  chSysDisable();
+
+  chThdExit(MSG_OK);
+  return MSG_OK;
+
+#else /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
+
+  /* hand over to the bootloader to perform SSSP shutdown phase */
+  aosSysShutdownToBootloader(shutdown);
+
+  aosDbgAssertMsg(false, "AMiRo-OS must not proceed to this point!");
+  chThdExit(MSG_RESET);
+  return MSG_RESET;
+
+#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
+
+#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
+
+  /*
+   * Depending on the configured bootloader, trivial shutdown is either executed by AMiRo-OS or by that bootloader.
+   */
+#if (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_NONE)
+
+  /* AMiRo-OS performs trivial shutdown */
+
+  // disable interrupts
+  irqDeinit();
+  chSysDisable();
+
+  chThdExit(MSG_OK);
+  return MSG_OK;
+
+#elif (AMIROOS_CFG_BOOTLOADER == AOS_BOOTLOADER_AMiRoBLT)
+
+  /* AMiRo-BLT performns shutdown */
+  aosSysShutdownToBootloader(shutdown);
+
+  aosDbgAssertMsg(false, "AMiRo-OS must not proceed to this point!");
+  chThdExit(MSG_RESET);
+  return MSG_RESET;
+
+#endif /* (AMIROOS_CFG_BOOTLOADER == X) */
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
 }
 
 /******************************************************************************/
