commit c53ef0b19cb670c47c2e3d9390f62e7661659e32
Author: Thomas Schöpping <tschoepp@cit-ec.uni-bielefeld.de>
Date:   Mon Nov 11 16:33:58 2019 +0100

    MSI implemented

diff --git a/core/inc/aos_sssp.h b/core/inc/aos_sssp.h
index be5dc22..0fb8ea7 100644
--- a/core/inc/aos_sssp.h
+++ b/core/inc/aos_sssp.h
@@ -75,8 +75,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /* CHECKS                                                                     */
 /******************************************************************************/
 
-#if (AMIROOS_CFG_SSSP_MSI == true)
-  #error "SSSP module stack initialization (MSI not implemented yet"
+#if (!(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 8) &&                                \
+   !(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 16)  &&                                \
+   !(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 32)  &&                                \
+   !(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 64))
+  #error "AMIROOS_CFG_SSSP_MODULEIDWIDTH set to an invalid value."
 #endif
 
 /******************************************************************************/
@@ -87,30 +90,38 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * @brief   Enumeration of the several stages of SSSP.
  */
 typedef enum {
-  AOS_SSSP_STAGE_UNDEFINED    = 0x0000, /**< Identifier of yet undefined stage variable.  */
-  AOS_SSSP_STAGE_STARTUP      = 0x1000, /**< Identifier of SSSP startup phase.            */
-  AOS_SSSP_STAGE_STARTUP_1    = 0x1100, /**< Identifier of SSSP startup phase stage 1.    */
-  AOS_SSSP_STAGE_STARTUP_1_1  = 0x1110, /**< Identifier of SSSP startup phase stage 1-1.  */
-  AOS_SSSP_STAGE_STARTUP_1_2  = 0x1120, /**< Identifier of SSSP startup phase stage 1-2.  */
-  AOS_SSSP_STAGE_STARTUP_1_3  = 0x1130, /**< Identifier of SSSP startup phase stage 1-3.  */
-  AOS_SSSP_STAGE_STARTUP_2    = 0x1200, /**< Identifier of SSSP startup phase stage 2.    */
-  AOS_SSSP_STAGE_STARTUP_2_1  = 0x1210, /**< Identifier of SSSP startup phase stage 2-1.  */
-  AOS_SSSP_STAGE_STARTUP_2_2  = 0x1220, /**< Identifier of SSSP startup phase stage 2-2.  */
-  AOS_SSSP_STAGE_STARTUP_3    = 0x1300, /**< Identifier of SSSP startup phase stage 3.    */
-  AOS_SSSP_STAGE_STARTUP_3_1  = 0x1310, /**< Identifier of SSSP startup phase stage 3-1.  */
-  AOS_SSSP_STAGE_STARTUP_3_2  = 0x1320, /**< Identifier of SSSP startup phase stage 3-2.  */
-  AOS_SSSP_STAGE_STARTUP_3_3  = 0x1330, /**< Identifier of SSSP startup phase stage 3-3.  */
-  AOS_SSSP_STAGE_STARTUP_3_4  = 0x1340, /**< Identifier of SSSP startup phase stage 3-4.  */
-  AOS_SSSP_STAGE_OPERATION    = 0x2000, /**< Identifier of SSSP operation phase.          */
-  AOS_SSSP_STAGE_SHUTDOWN     = 0x3000, /**< Identifier of SSSP shutdown phase.           */
-  AOS_SSSP_STAGE_SHUTDOWN_1   = 0x3100, /**< Identifier of SSSP shutdown phase stage 1.   */
-  AOS_SSSP_STAGE_SHUTDOWN_1_1 = 0x3110, /**< Identifier of SSSP shutdown phase stage 1-1. */
-  AOS_SSSP_STAGE_SHUTDOWN_1_2 = 0x3120, /**< Identifier of SSSP shutdown phase stage 1-2. */
-  AOS_SSSP_STAGE_SHUTDOWN_1_3 = 0x3130, /**< Identifier of SSSP shutdown phase stage 1-3. */
-  AOS_SSSP_STAGE_SHUTDOWN_2   = 0x3200, /**< Identifier of SSSP shutdown phase stage 2.   */
-  AOS_SSSP_STAGE_SHUTDOWN_2_1 = 0x3210, /**< Identifier of SSSP shutdown phase stage 2-1. */
-  AOS_SSSP_STAGE_SHUTDOWN_2_2 = 0x3220, /**< Identifier of SSSP shutdown phase stage 2-2. */
-  AOS_SSSP_STAGE_SHUTDOWN_2_3 = 0x3230, /**< Identifier of SSSP shutdown phase stage 2-3. */
+  AOS_SSSP_STAGE_UNDEFINED                    = 0x00000000, /**< Identifier of yet undefined stage variable.                                          */
+  AOS_SSSP_STAGE_STARTUP                      = 0x10000000, /**< Identifier of SSSP startup phase.                                                    */
+  AOS_SSSP_STAGE_STARTUP_1                    = 0x11000000, /**< Identifier of SSSP startup phase stage 1.                                            */
+  AOS_SSSP_STAGE_STARTUP_1_1                  = 0x11100000, /**< Identifier of SSSP startup phase stage 1-1.                                          */
+  AOS_SSSP_STAGE_STARTUP_1_2                  = 0x11200000, /**< Identifier of SSSP startup phase stage 1-2.                                          */
+  AOS_SSSP_STAGE_STARTUP_1_3                  = 0x11300000, /**< Identifier of SSSP startup phase stage 1-3.                                          */
+  AOS_SSSP_STAGE_STARTUP_2                    = 0x12000000, /**< Identifier of SSSP startup phase stage 2.                                            */
+  AOS_SSSP_STAGE_STARTUP_2_1                  = 0x12100000, /**< Identifier of SSSP startup phase stage 2-1.                                          */
+  AOS_SSSP_STAGE_STARTUP_2_2                  = 0x12200000, /**< Identifier of SSSP startup phase stage 2-2.                                          */
+  AOS_SSSP_STAGE_STARTUP_3                    = 0x13000000, /**< Identifier of SSSP startup phase stage 3.                                            */
+  AOS_SSSP_STAGE_STARTUP_3_1                  = 0x13100000, /**< Identifier of SSSP startup phase stage 3-1.                                          */
+  AOS_SSSP_STAGE_STARTUP_3_1_BROADCASTINIT    = 0x13110001, /**< Identifier of SSSP startup phase stage 3-1 broadcast initialization (master only).   */
+  AOS_SSSP_STAGE_STARTUP_3_1_WAITFORINIT      = 0x13110002, /**< Identifier of SSSP startup phase stage 3-1 waiting for broadcast (non-master only).  */
+  AOS_SSSP_STAGE_STARTUP_3_2                  = 0x13200000, /**< Identifier of SSSP startup phase stage 3-2.                                          */
+  AOS_SSSP_STAGE_STARTUP_3_3                  = 0x13300000, /**< Identifier of SSSP startup phase stage 3-3.                                          */
+  AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT       = 0x13310000, /**< Identifier of SSSP startup phase stage 3-3 waiting for an event to occurr.           */
+  AOS_SSSP_STAGE_STARTUP_3_3_BROADCASTID      = 0x13320000, /**< Identifier of SSSP startup phase stage 3-3 broadcasting identifier.                  */
+  AOS_SSSP_STAGE_STARTUP_3_4                  = 0x13400000, /**< Identifier of SSSP startup phase stage 3-4.                                          */
+  AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION       = 0x13410000, /**< Identifier of SSSP startup phase stage 3-4 completion.                               */
+  AOS_SSSP_STAGE_STARTUP_3_4_ABORTION         = 0x13420000, /**< Identifier of SSSP startup phase stage 3-4 abortion.                                 */
+  AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT    = 0x13421000, /**< Identifier of SSSP startup phase stage 3-4 abortion initialization.                  */
+  AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_SYNC    = 0x13422000, /**< Identifier of SSSP startup phase stage 3-4 abortion synchronization.                 */
+  AOS_SSSP_STAGE_OPERATION                    = 0x20000000, /**< Identifier of SSSP operation phase.                                                  */
+  AOS_SSSP_STAGE_SHUTDOWN                     = 0x30000000, /**< Identifier of SSSP shutdown phase.                                                   */
+  AOS_SSSP_STAGE_SHUTDOWN_1                   = 0x31000000, /**< Identifier of SSSP shutdown phase stage 1.                                           */
+  AOS_SSSP_STAGE_SHUTDOWN_1_1                 = 0x31100000, /**< Identifier of SSSP shutdown phase stage 1-1.                                         */
+  AOS_SSSP_STAGE_SHUTDOWN_1_2                 = 0x31200000, /**< Identifier of SSSP shutdown phase stage 1-2.                                         */
+  AOS_SSSP_STAGE_SHUTDOWN_1_3                 = 0x31300000, /**< Identifier of SSSP shutdown phase stage 1-3.                                         */
+  AOS_SSSP_STAGE_SHUTDOWN_2                   = 0x32000000, /**< Identifier of SSSP shutdown phase stage 2.                                           */
+  AOS_SSSP_STAGE_SHUTDOWN_2_1                 = 0x32100000, /**< Identifier of SSSP shutdown phase stage 2-1.                                         */
+  AOS_SSSP_STAGE_SHUTDOWN_2_2                 = 0x32200000, /**< Identifier of SSSP shutdown phase stage 2-2.                                         */
+  AOS_SSSP_STAGE_SHUTDOWN_2_3                 = 0x32300000, /**< Identifier of SSSP shutdown phase stage 2-3.                                         */
 } aos_ssspstage_t;
 
 /**
@@ -122,8 +133,8 @@ typedef uint8_t aos_ssspmoduleid_t;
 typedef uint16_t aos_ssspmoduleid_t;
 #elif (AMIROOS_CFG_SSSP_MODULEIDWIDTH == 32)
 typedef uint32_t aos_ssspmoduleid_t;
-#else
-#error "AMIROOS_CFG_SSSP_MODULEIDWIDTH set to an invalid value."
+#elif (AMIROOS_CFG_SSSP_MODULEIDWIDTH == 64)
+typedef uint64_t aos_ssspmoduleid_t;
 #endif
 
 /**
@@ -135,19 +146,122 @@ typedef struct {
    */
   aos_ssspstage_t stage;
 
-#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
-
   /**
    * @brief   Module identifier.
    * @details A value of @p AOS_SSSP_MODULEID_INVALID indicates an uninitialized ID.
-   *          The values @p AOS_SSSP_MODULEID_INVALID and @p AOS_SSSP_MODULEID_ALL are reserved and must not be set.
    */
   aos_ssspmoduleid_t moduleId;
 
-#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
-
 } aos_ssspdata_t;
 
+#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
+
+/**
+ * @brief   Type to qualify attempts to transmitt/receive mesages via BCB.
+ */
+typedef enum {
+  AOS_SSSP_BCB_SUCCESS,     /**< BCB access was sucessfull. */
+  AOS_SSSP_BCB_ERROR,       /**< BCB access failed or no message was available. */
+  AOS_SSSP_BCB_INVALIDMSG,  /**< Invalid BCB message detected. */
+} aos_ssspbcbstatus_t;
+
+/**
+ * @brief   Data structure to be transmitted via BCB during module stack initialization (MSI).
+ */
+typedef struct {
+
+  /**
+   * @brief   Type of the message.
+   */
+  uint8_t type;
+
+  /**
+   * @brief   Message payload.
+   * @details Payload depends on message type.
+   */
+  union {
+    /**
+     * @brief   Transmitted ID.
+     * @details This field is only used for @p SSSP_MSI_ID type messages.
+     */
+    aos_ssspmoduleid_t id;
+  } payload PACKED_VAR;
+
+} aos_ssspbcbmessage_t;
+
+/*
+ * Available BCB messages:
+ */
+#define AOS_SSSP_BCBMESSAGE_INVALID             0   /**< Invalid BCB message.         */
+#define AOS_SSSP_BCBMESSAGE_MSIINIT             1   /**< MSI initialization message.  */
+#define AOS_SSSP_BCBMESSAGE_MSIID               2   /**< MSI identifier message.      */
+#define AOS_SSSP_BCBMESSAGE_MSIABORT            3   /**< MSI abort message.           */
+
+/**
+ * @brief   Data structure required for the module stack initialization (MSI) phase.
+ */
+typedef struct {
+
+  /**
+   * @brief   Timout related data.
+   */
+  struct {
+    /**
+     * @brief   Timer to trigger potential timeouts.
+     * @details This timer must not be an AMiRo-OS timer, since delays occurr before system is initialized.
+     */
+    virtual_timer_t timer;
+
+    /**
+     * @brief   Event source to be triggered on timeout.
+     */
+    event_source_t eventsource;
+
+    /**
+     * @brief   Event listener to inform the MSI thread about timeout events.
+     */
+    event_listener_t eventlistener;
+  } timeout;
+
+  /**
+   * @brief   Signal related data.
+   */
+  struct {
+    /**
+     * @brief   Pointer to an existing event listener, which informs about GPIO signal events.
+     */
+    event_listener_t* eventlistener;
+  } signals;
+
+  /**
+   * @brief   BCB related data.
+   */
+  struct {
+    /**
+     * @brief   Message object.
+     */
+    aos_ssspbcbmessage_t message;
+
+    /**
+     * @brief   Buffer for (de)serialization BCB messages.
+     */
+    uint8_t buffer[sizeof(aos_ssspbcbmessage_t)];
+
+    /**
+     * @brief   Return status of last BCB access.
+     */
+    aos_ssspbcbstatus_t status;
+
+    /**
+     * @brief   The most recently received identifier.
+     */
+    aos_ssspmoduleid_t lastid;
+  } bcb;
+
+} aos_ssspmsidata_t;
+
+#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
+
 /******************************************************************************/
 /* MACROS                                                                     */
 /******************************************************************************/
@@ -159,16 +273,120 @@ typedef struct {
 #if defined(__cplusplus)
 extern "C" {
 #endif /* defined(__cplusplus) */
+
+  /*
+   * module specific interface functions
+   */
+#if !defined(moduleSsspSignalPD) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the control GPIO object for the PD signal.
+   * @return  Pounter to the control GPIO object.
+   */
+  apalControlGpio_t* moduleSsspSignalPD(void);
+#endif /* !defined(moduleSsspSignalPD) */
+#if !defined(moduleSsspEventflagPD) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the GPIO event flag set by a PD signal edge.
+   * @return  Eventflag set on PD events.
+   */
+  eventflags_t moduleSsspEventflagPD(void);
+#endif /* !defined(moduleSsspEventflagPD) */
+
+#if !defined(moduleSsspSignalS) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the control GPIO object for the S signal.
+   * @return  Pounter to the control GPIO object.
+   */
+  apalControlGpio_t* moduleSsspSignalS(void);
+#endif /* !defined(moduleSsspSignalS) */
+#if !defined(moduleSsspEventflagS) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the GPIO event flag set by a S signal edge.
+   * @return  Eventflag set on S events.
+   */
+  eventflags_t moduleSsspEventflagS(void);
+#endif /* !defined(moduleSsspEventflagS) */
+
+#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
+
+#if (AMIROOS_CFG_SSSP_STACK_START != true) || defined(__DOXYGEN__)
+#if !defined(moduleSsspSignalDN) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the control GPIO object for the DN signal.
+   * @return  Pounter to the control GPIO object.
+   */
+  apalControlGpio_t* moduleSsspSignalDN(void);
+#endif /* !defined(moduleSsspSignalDN) */
+#if !defined(moduleSsspEventflagDN) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the GPIO event flag set by a DN signal edge.
+   * @return  Eventflag set on DN events.
+   */
+  eventflags_t moduleSsspEventflagDN(void);
+#endif /* !defined(moduleSsspEventflagDN) */
+#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
+
+#if (AMIROOS_CFG_SSSP_STACK_END != true) || defined(__DOXYGEN__)
+#if !defined(moduleSsspSignalUP) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the control GPIO object for the UP signal.
+   * @return  Pounter to the control GPIO object.
+   */
+  apalControlGpio_t* moduleSsspSignalUP(void);
+#endif /* !defined(moduleSsspSignalUP) */
+#if !defined(moduleSsspEventflagUP) || defined(__DOXYGEN__)
+  /**
+   * @brief   Retreive the GPIO event flag set by a UP signal edge.
+   * @return  Eventflag set on UP events.
+   */
+  eventflags_t moduleSsspEventflagUP(void);
+#endif /* !defined(moduleSsspEventflagUP) */
+#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
+
+#if !defined(moduleSsspBcbTransmit) || defined(__DOXYGEN__)
+  /**
+   * @brief   Transmit data via BCB.
+   *
+   * @param[in] buffer    Pointer to a buffer, that holds the data to be sent.
+   * @param[in] length    Length of the buffer in bytes.
+   *
+   * @return  Status value, indicating whether the operation was successful.
+   */
+  aos_ssspbcbstatus_t moduleSsspBcbTransmit(const uint8_t* buffer, size_t length);
+
+  /**
+   * @brief   Receive a message from BCB.
+   * @note    If a message is received, which is not defined by SSSP, the data may be irreversibly discarded by this function.
+   *
+   * @param[out]    buffer  Pointer to a buffer to store the received data to.
+   * @param[in]     length  Number of expected bytes to receive.
+   *                        Obviously, the buffer must be large enough.
+   *
+   * @return  Status value, indicating whether the operation was successful.
+   */
+  aos_ssspbcbstatus_t moduleSsspBcbReceive(uint8_t* buffer, size_t length);
+#endif /* !defined(moduleSsspBcbTransmit) */
+
+#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
+
+  /*
+   * API functions
+   */
   void aosSsspInit(aos_timestamp_t* system_uptime);
-  aos_status_t aosSsspProceed(event_listener_t* listener, eventflags_t flags, eventmask_t mask, eventmask_t* received);
+  aos_status_t aosSsspProceed(event_listener_t* listener, eventmask_t mask, eventmask_t* received);
+#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
+  void aosSsspMsiInit(aos_ssspmsidata_t* msidata, eventmask_t delayMask, eventmask_t timeoutMask, event_listener_t* gpioListener);
+  void aosSsspMsi(aos_ssspmsidata_t* msidata, eventmask_t* received);
+#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
+#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
+  float aosSsspGetSyncSkew(void);
+#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
   void aosSsspShutdownInit(bool active);
 #if (AMIROOS_CFG_SSSP_SHUTDOWN == true) || defined(__DOXYGEN__)
   void aosSsspShutdownBroadcastIdentifier(unsigned int identifier);
   eventmask_t aosSsspShutdownWaitForIdentifierPulse(event_listener_t* gpiolistener, eventflags_t sflags, eventmask_t timermask, unsigned int* identifier);
 #endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
-#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
-  float aosSsspGetSyncSkew(void);
-#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
+
 #if defined(__cplusplus)
 }
 #endif /* defined(__cplusplus) */
