Revision c53ef0b1

View differences:

core/inc/aos_sssp.h
75 75
/* CHECKS                                                                     */
76 76
/******************************************************************************/
77 77

  
78
#if (AMIROOS_CFG_SSSP_MSI == true)
79
  #error "SSSP module stack initialization (MSI not implemented yet"
78
#if (!(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 8) &&                                \
79
   !(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 16)  &&                                \
80
   !(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 32)  &&                                \
81
   !(AMIROOS_CFG_SSSP_MODULEIDWIDTH == 64))
82
  #error "AMIROOS_CFG_SSSP_MODULEIDWIDTH set to an invalid value."
80 83
#endif
81 84

  
82 85
/******************************************************************************/
......
87 90
 * @brief   Enumeration of the several stages of SSSP.
88 91
 */
89 92
typedef enum {
90
  AOS_SSSP_STAGE_UNDEFINED    = 0x0000, /**< Identifier of yet undefined stage variable.  */
91
  AOS_SSSP_STAGE_STARTUP      = 0x1000, /**< Identifier of SSSP startup phase.            */
92
  AOS_SSSP_STAGE_STARTUP_1    = 0x1100, /**< Identifier of SSSP startup phase stage 1.    */
93
  AOS_SSSP_STAGE_STARTUP_1_1  = 0x1110, /**< Identifier of SSSP startup phase stage 1-1.  */
94
  AOS_SSSP_STAGE_STARTUP_1_2  = 0x1120, /**< Identifier of SSSP startup phase stage 1-2.  */
95
  AOS_SSSP_STAGE_STARTUP_1_3  = 0x1130, /**< Identifier of SSSP startup phase stage 1-3.  */
96
  AOS_SSSP_STAGE_STARTUP_2    = 0x1200, /**< Identifier of SSSP startup phase stage 2.    */
97
  AOS_SSSP_STAGE_STARTUP_2_1  = 0x1210, /**< Identifier of SSSP startup phase stage 2-1.  */
98
  AOS_SSSP_STAGE_STARTUP_2_2  = 0x1220, /**< Identifier of SSSP startup phase stage 2-2.  */
99
  AOS_SSSP_STAGE_STARTUP_3    = 0x1300, /**< Identifier of SSSP startup phase stage 3.    */
100
  AOS_SSSP_STAGE_STARTUP_3_1  = 0x1310, /**< Identifier of SSSP startup phase stage 3-1.  */
101
  AOS_SSSP_STAGE_STARTUP_3_2  = 0x1320, /**< Identifier of SSSP startup phase stage 3-2.  */
102
  AOS_SSSP_STAGE_STARTUP_3_3  = 0x1330, /**< Identifier of SSSP startup phase stage 3-3.  */
103
  AOS_SSSP_STAGE_STARTUP_3_4  = 0x1340, /**< Identifier of SSSP startup phase stage 3-4.  */
104
  AOS_SSSP_STAGE_OPERATION    = 0x2000, /**< Identifier of SSSP operation phase.          */
105
  AOS_SSSP_STAGE_SHUTDOWN     = 0x3000, /**< Identifier of SSSP shutdown phase.           */
106
  AOS_SSSP_STAGE_SHUTDOWN_1   = 0x3100, /**< Identifier of SSSP shutdown phase stage 1.   */
107
  AOS_SSSP_STAGE_SHUTDOWN_1_1 = 0x3110, /**< Identifier of SSSP shutdown phase stage 1-1. */
108
  AOS_SSSP_STAGE_SHUTDOWN_1_2 = 0x3120, /**< Identifier of SSSP shutdown phase stage 1-2. */
109
  AOS_SSSP_STAGE_SHUTDOWN_1_3 = 0x3130, /**< Identifier of SSSP shutdown phase stage 1-3. */
110
  AOS_SSSP_STAGE_SHUTDOWN_2   = 0x3200, /**< Identifier of SSSP shutdown phase stage 2.   */
111
  AOS_SSSP_STAGE_SHUTDOWN_2_1 = 0x3210, /**< Identifier of SSSP shutdown phase stage 2-1. */
112
  AOS_SSSP_STAGE_SHUTDOWN_2_2 = 0x3220, /**< Identifier of SSSP shutdown phase stage 2-2. */
113
  AOS_SSSP_STAGE_SHUTDOWN_2_3 = 0x3230, /**< Identifier of SSSP shutdown phase stage 2-3. */
93
  AOS_SSSP_STAGE_UNDEFINED                    = 0x00000000, /**< Identifier of yet undefined stage variable.                                          */
94
  AOS_SSSP_STAGE_STARTUP                      = 0x10000000, /**< Identifier of SSSP startup phase.                                                    */
95
  AOS_SSSP_STAGE_STARTUP_1                    = 0x11000000, /**< Identifier of SSSP startup phase stage 1.                                            */
96
  AOS_SSSP_STAGE_STARTUP_1_1                  = 0x11100000, /**< Identifier of SSSP startup phase stage 1-1.                                          */
97
  AOS_SSSP_STAGE_STARTUP_1_2                  = 0x11200000, /**< Identifier of SSSP startup phase stage 1-2.                                          */
98
  AOS_SSSP_STAGE_STARTUP_1_3                  = 0x11300000, /**< Identifier of SSSP startup phase stage 1-3.                                          */
99
  AOS_SSSP_STAGE_STARTUP_2                    = 0x12000000, /**< Identifier of SSSP startup phase stage 2.                                            */
100
  AOS_SSSP_STAGE_STARTUP_2_1                  = 0x12100000, /**< Identifier of SSSP startup phase stage 2-1.                                          */
101
  AOS_SSSP_STAGE_STARTUP_2_2                  = 0x12200000, /**< Identifier of SSSP startup phase stage 2-2.                                          */
102
  AOS_SSSP_STAGE_STARTUP_3                    = 0x13000000, /**< Identifier of SSSP startup phase stage 3.                                            */
103
  AOS_SSSP_STAGE_STARTUP_3_1                  = 0x13100000, /**< Identifier of SSSP startup phase stage 3-1.                                          */
104
  AOS_SSSP_STAGE_STARTUP_3_1_BROADCASTINIT    = 0x13110001, /**< Identifier of SSSP startup phase stage 3-1 broadcast initialization (master only).   */
105
  AOS_SSSP_STAGE_STARTUP_3_1_WAITFORINIT      = 0x13110002, /**< Identifier of SSSP startup phase stage 3-1 waiting for broadcast (non-master only).  */
106
  AOS_SSSP_STAGE_STARTUP_3_2                  = 0x13200000, /**< Identifier of SSSP startup phase stage 3-2.                                          */
107
  AOS_SSSP_STAGE_STARTUP_3_3                  = 0x13300000, /**< Identifier of SSSP startup phase stage 3-3.                                          */
108
  AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT       = 0x13310000, /**< Identifier of SSSP startup phase stage 3-3 waiting for an event to occurr.           */
109
  AOS_SSSP_STAGE_STARTUP_3_3_BROADCASTID      = 0x13320000, /**< Identifier of SSSP startup phase stage 3-3 broadcasting identifier.                  */
110
  AOS_SSSP_STAGE_STARTUP_3_4                  = 0x13400000, /**< Identifier of SSSP startup phase stage 3-4.                                          */
111
  AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION       = 0x13410000, /**< Identifier of SSSP startup phase stage 3-4 completion.                               */
112
  AOS_SSSP_STAGE_STARTUP_3_4_ABORTION         = 0x13420000, /**< Identifier of SSSP startup phase stage 3-4 abortion.                                 */
113
  AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT    = 0x13421000, /**< Identifier of SSSP startup phase stage 3-4 abortion initialization.                  */
114
  AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_SYNC    = 0x13422000, /**< Identifier of SSSP startup phase stage 3-4 abortion synchronization.                 */
115
  AOS_SSSP_STAGE_OPERATION                    = 0x20000000, /**< Identifier of SSSP operation phase.                                                  */
116
  AOS_SSSP_STAGE_SHUTDOWN                     = 0x30000000, /**< Identifier of SSSP shutdown phase.                                                   */
117
  AOS_SSSP_STAGE_SHUTDOWN_1                   = 0x31000000, /**< Identifier of SSSP shutdown phase stage 1.                                           */
118
  AOS_SSSP_STAGE_SHUTDOWN_1_1                 = 0x31100000, /**< Identifier of SSSP shutdown phase stage 1-1.                                         */
119
  AOS_SSSP_STAGE_SHUTDOWN_1_2                 = 0x31200000, /**< Identifier of SSSP shutdown phase stage 1-2.                                         */
120
  AOS_SSSP_STAGE_SHUTDOWN_1_3                 = 0x31300000, /**< Identifier of SSSP shutdown phase stage 1-3.                                         */
121
  AOS_SSSP_STAGE_SHUTDOWN_2                   = 0x32000000, /**< Identifier of SSSP shutdown phase stage 2.                                           */
122
  AOS_SSSP_STAGE_SHUTDOWN_2_1                 = 0x32100000, /**< Identifier of SSSP shutdown phase stage 2-1.                                         */
123
  AOS_SSSP_STAGE_SHUTDOWN_2_2                 = 0x32200000, /**< Identifier of SSSP shutdown phase stage 2-2.                                         */
124
  AOS_SSSP_STAGE_SHUTDOWN_2_3                 = 0x32300000, /**< Identifier of SSSP shutdown phase stage 2-3.                                         */
114 125
} aos_ssspstage_t;
115 126

  
116 127
/**
......
122 133
typedef uint16_t aos_ssspmoduleid_t;
123 134
#elif (AMIROOS_CFG_SSSP_MODULEIDWIDTH == 32)
124 135
typedef uint32_t aos_ssspmoduleid_t;
125
#else
126
#error "AMIROOS_CFG_SSSP_MODULEIDWIDTH set to an invalid value."
136
#elif (AMIROOS_CFG_SSSP_MODULEIDWIDTH == 64)
137
typedef uint64_t aos_ssspmoduleid_t;
127 138
#endif
128 139

  
129 140
/**
......
135 146
   */
136 147
  aos_ssspstage_t stage;
137 148

  
138
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
139

  
140 149
  /**
141 150
   * @brief   Module identifier.
142 151
   * @details A value of @p AOS_SSSP_MODULEID_INVALID indicates an uninitialized ID.
143
   *          The values @p AOS_SSSP_MODULEID_INVALID and @p AOS_SSSP_MODULEID_ALL are reserved and must not be set.
144 152
   */
145 153
  aos_ssspmoduleid_t moduleId;
146 154

  
147
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
148

  
149 155
} aos_ssspdata_t;
150 156

  
157
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
158

  
159
/**
160
 * @brief   Type to qualify attempts to transmitt/receive mesages via BCB.
161
 */
162
typedef enum {
163
  AOS_SSSP_BCB_SUCCESS,     /**< BCB access was sucessfull. */
164
  AOS_SSSP_BCB_ERROR,       /**< BCB access failed or no message was available. */
165
  AOS_SSSP_BCB_INVALIDMSG,  /**< Invalid BCB message detected. */
166
} aos_ssspbcbstatus_t;
167

  
168
/**
169
 * @brief   Data structure to be transmitted via BCB during module stack initialization (MSI).
170
 */
171
typedef struct {
172

  
173
  /**
174
   * @brief   Type of the message.
175
   */
176
  uint8_t type;
177

  
178
  /**
179
   * @brief   Message payload.
180
   * @details Payload depends on message type.
181
   */
182
  union {
183
    /**
184
     * @brief   Transmitted ID.
185
     * @details This field is only used for @p SSSP_MSI_ID type messages.
186
     */
187
    aos_ssspmoduleid_t id;
188
  } payload PACKED_VAR;
189

  
190
} aos_ssspbcbmessage_t;
191

  
192
/*
193
 * Available BCB messages:
194
 */
195
#define AOS_SSSP_BCBMESSAGE_INVALID             0   /**< Invalid BCB message.         */
196
#define AOS_SSSP_BCBMESSAGE_MSIINIT             1   /**< MSI initialization message.  */
197
#define AOS_SSSP_BCBMESSAGE_MSIID               2   /**< MSI identifier message.      */
198
#define AOS_SSSP_BCBMESSAGE_MSIABORT            3   /**< MSI abort message.           */
199

  
200
/**
201
 * @brief   Data structure required for the module stack initialization (MSI) phase.
202
 */
203
typedef struct {
204

  
205
  /**
206
   * @brief   Timout related data.
207
   */
208
  struct {
209
    /**
210
     * @brief   Timer to trigger potential timeouts.
211
     * @details This timer must not be an AMiRo-OS timer, since delays occurr before system is initialized.
212
     */
213
    virtual_timer_t timer;
214

  
215
    /**
216
     * @brief   Event source to be triggered on timeout.
217
     */
218
    event_source_t eventsource;
219

  
220
    /**
221
     * @brief   Event listener to inform the MSI thread about timeout events.
222
     */
223
    event_listener_t eventlistener;
224
  } timeout;
225

  
226
  /**
227
   * @brief   Signal related data.
228
   */
229
  struct {
230
    /**
231
     * @brief   Pointer to an existing event listener, which informs about GPIO signal events.
232
     */
233
    event_listener_t* eventlistener;
234
  } signals;
235

  
236
  /**
237
   * @brief   BCB related data.
238
   */
239
  struct {
240
    /**
241
     * @brief   Message object.
242
     */
243
    aos_ssspbcbmessage_t message;
244

  
245
    /**
246
     * @brief   Buffer for (de)serialization BCB messages.
247
     */
248
    uint8_t buffer[sizeof(aos_ssspbcbmessage_t)];
249

  
250
    /**
251
     * @brief   Return status of last BCB access.
252
     */
253
    aos_ssspbcbstatus_t status;
254

  
255
    /**
256
     * @brief   The most recently received identifier.
257
     */
258
    aos_ssspmoduleid_t lastid;
259
  } bcb;
260

  
261
} aos_ssspmsidata_t;
262

  
263
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
264

  
151 265
/******************************************************************************/
152 266
/* MACROS                                                                     */
153 267
/******************************************************************************/
......
159 273
#if defined(__cplusplus)
160 274
extern "C" {
161 275
#endif /* defined(__cplusplus) */
276

  
277
  /*
278
   * module specific interface functions
279
   */
280
#if !defined(moduleSsspSignalPD) || defined(__DOXYGEN__)
281
  /**
282
   * @brief   Retreive the control GPIO object for the PD signal.
283
   * @return  Pounter to the control GPIO object.
284
   */
285
  apalControlGpio_t* moduleSsspSignalPD(void);
286
#endif /* !defined(moduleSsspSignalPD) */
287
#if !defined(moduleSsspEventflagPD) || defined(__DOXYGEN__)
288
  /**
289
   * @brief   Retreive the GPIO event flag set by a PD signal edge.
290
   * @return  Eventflag set on PD events.
291
   */
292
  eventflags_t moduleSsspEventflagPD(void);
293
#endif /* !defined(moduleSsspEventflagPD) */
294

  
295
#if !defined(moduleSsspSignalS) || defined(__DOXYGEN__)
296
  /**
297
   * @brief   Retreive the control GPIO object for the S signal.
298
   * @return  Pounter to the control GPIO object.
299
   */
300
  apalControlGpio_t* moduleSsspSignalS(void);
301
#endif /* !defined(moduleSsspSignalS) */
302
#if !defined(moduleSsspEventflagS) || defined(__DOXYGEN__)
303
  /**
304
   * @brief   Retreive the GPIO event flag set by a S signal edge.
305
   * @return  Eventflag set on S events.
306
   */
307
  eventflags_t moduleSsspEventflagS(void);
308
#endif /* !defined(moduleSsspEventflagS) */
309

  
310
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
311

  
312
#if (AMIROOS_CFG_SSSP_STACK_START != true) || defined(__DOXYGEN__)
313
#if !defined(moduleSsspSignalDN) || defined(__DOXYGEN__)
314
  /**
315
   * @brief   Retreive the control GPIO object for the DN signal.
316
   * @return  Pounter to the control GPIO object.
317
   */
318
  apalControlGpio_t* moduleSsspSignalDN(void);
319
#endif /* !defined(moduleSsspSignalDN) */
320
#if !defined(moduleSsspEventflagDN) || defined(__DOXYGEN__)
321
  /**
322
   * @brief   Retreive the GPIO event flag set by a DN signal edge.
323
   * @return  Eventflag set on DN events.
324
   */
325
  eventflags_t moduleSsspEventflagDN(void);
326
#endif /* !defined(moduleSsspEventflagDN) */
327
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
328

  
329
#if (AMIROOS_CFG_SSSP_STACK_END != true) || defined(__DOXYGEN__)
330
#if !defined(moduleSsspSignalUP) || defined(__DOXYGEN__)
331
  /**
332
   * @brief   Retreive the control GPIO object for the UP signal.
333
   * @return  Pounter to the control GPIO object.
334
   */
335
  apalControlGpio_t* moduleSsspSignalUP(void);
336
#endif /* !defined(moduleSsspSignalUP) */
337
#if !defined(moduleSsspEventflagUP) || defined(__DOXYGEN__)
338
  /**
339
   * @brief   Retreive the GPIO event flag set by a UP signal edge.
340
   * @return  Eventflag set on UP events.
341
   */
342
  eventflags_t moduleSsspEventflagUP(void);
343
#endif /* !defined(moduleSsspEventflagUP) */
344
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
345

  
346
#if !defined(moduleSsspBcbTransmit) || defined(__DOXYGEN__)
347
  /**
348
   * @brief   Transmit data via BCB.
349
   *
350
   * @param[in] buffer    Pointer to a buffer, that holds the data to be sent.
351
   * @param[in] length    Length of the buffer in bytes.
352
   *
353
   * @return  Status value, indicating whether the operation was successful.
354
   */
355
  aos_ssspbcbstatus_t moduleSsspBcbTransmit(const uint8_t* buffer, size_t length);
356

  
357
  /**
358
   * @brief   Receive a message from BCB.
359
   * @note    If a message is received, which is not defined by SSSP, the data may be irreversibly discarded by this function.
360
   *
361
   * @param[out]    buffer  Pointer to a buffer to store the received data to.
362
   * @param[in]     length  Number of expected bytes to receive.
363
   *                        Obviously, the buffer must be large enough.
364
   *
365
   * @return  Status value, indicating whether the operation was successful.
366
   */
367
  aos_ssspbcbstatus_t moduleSsspBcbReceive(uint8_t* buffer, size_t length);
368
#endif /* !defined(moduleSsspBcbTransmit) */
369

  
370
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
371

  
372
  /*
373
   * API functions
374
   */
162 375
  void aosSsspInit(aos_timestamp_t* system_uptime);
163
  aos_status_t aosSsspProceed(event_listener_t* listener, eventflags_t flags, eventmask_t mask, eventmask_t* received);
376
  aos_status_t aosSsspProceed(event_listener_t* listener, eventmask_t mask, eventmask_t* received);
377
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
378
  void aosSsspMsiInit(aos_ssspmsidata_t* msidata, eventmask_t delayMask, eventmask_t timeoutMask, event_listener_t* gpioListener);
379
  void aosSsspMsi(aos_ssspmsidata_t* msidata, eventmask_t* received);
380
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
381
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
382
  float aosSsspGetSyncSkew(void);
383
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
164 384
  void aosSsspShutdownInit(bool active);
165 385
#if (AMIROOS_CFG_SSSP_SHUTDOWN == true) || defined(__DOXYGEN__)
166 386
  void aosSsspShutdownBroadcastIdentifier(unsigned int identifier);
167 387
  eventmask_t aosSsspShutdownWaitForIdentifierPulse(event_listener_t* gpiolistener, eventflags_t sflags, eventmask_t timermask, unsigned int* identifier);
168 388
#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
169
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
170
  float aosSsspGetSyncSkew(void);
171
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
389

  
172 390
#if defined(__cplusplus)
173 391
}
174 392
#endif /* defined(__cplusplus) */
core/inc/aos_types.h
46 46
/******************************************************************************/
47 47

  
48 48
/**
49
 * @brief   Error and status type generally used in AMiRo-OS.
49
 * @brief   Status type generally used in AMiRo-OS.
50
 * @details By definition, the most significant bit (MSB) indicates whether an error occurred (e.g. the function call failed).
51
 *          All other bits can be used to specify the issue in more detail.
52
 *          If the MSB is unset, all other bits can still be used to indicate and specify non-critical warnings.
53
 *          As a result, a value of 0 (no bit set) indicates a flawles success.
50 54
 */
51 55
typedef uint8_t aos_status_t;
52 56

  
......
58 62
/**
59 63
 * @brief   Success: no error or warning occurred.
60 64
 */
61
#define AOS_SUCCESS                             ((aos_status_t)0x00u)
65
#define AOS_SUCCESS                             AOS_OK
62 66

  
63 67
/**
64 68
 * @brief   Some unspecified waring occurred.
......
73 77
/**
74 78
 * @brief   An error occurred.
75 79
 */
76
#define AOS_ERROR                               ((aos_status_t)0x80u)
80
#define AOS_ERROR                               ((aos_status_t)(1 << ((sizeof(aos_status_t) * 8) - 1)))
77 81

  
78 82
/**
79 83
 * @brief   An error occurred.
80 84
 */
81
#define AOS_FAILURE                             ((aos_status_t)0x80u)
85
#define AOS_FAILURE                             AOS_ERROR
82 86

  
83 87
/******************************************************************************/
84 88
/* MACROS                                                                     */
core/src/aos_main.cpp
49 49

  
50 50
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
51 51

  
52

  
53
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
54

  
55
/**
56
 * @brief   Event mask to identify SSSP timeout events (MSI only).
57
 */
58
#define EVENTMASK_SSSPTIMEOUT                   EVENT_MASK(2)
59

  
60
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
61

  
52 62
/**
53
 * @brief   Event mask to identify SSSP timer events.
63
 * @brief   Event mask to identify SSSP delay events.
54 64
 */
55
#define EVENTMASK_SSSPTIMER                     EVENT_MASK(2)
65
#define EVENTMASK_SSSPDELAY                     EVENT_MASK(3)
56 66

  
57 67
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
58 68

  
......
273 283
  /* event associations */
274 284
#if (AMIROOS_CFG_SSSP_ENABLE == true)
275 285
  {
276
    eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | MODULE_SSSP_EVENTFLAG_PD | MODULE_SSSP_EVENTFLAG_S;
286
    eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | moduleSsspEventflagPD() | moduleSsspEventflagS();
277 287
#if (AMIROOS_CFG_SSSP_MSI == true)
278 288
#if (AMIROOS_CFG_SSSP_STACK_START != true)
279
    flagsmask |= MODULE_SSSP_EVENTFLAG_DN;
289
    flagsmask |= moduleSsspEventflagDN();
280 290
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
281 291
#if (AMIROOS_CFG_SSSP_STACK_END != true)
282
    flagsmask |= MODULE_SSSP_EVENTFLAG_UP;
292
    flagsmask |= moduleSsspEventflagUP();
283 293
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
284 294
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
285 295
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, flagsmask);
......
305 315

  
306 316
  // proceed to startup stage 1.2
307 317
#if (AMIROOS_CFG_SSSP_MASTER == true)
308
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
318
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, EVENTMASK_SSSPDELAY, &eventmask) != AOS_SUCCESS)) {
309 319
    /*
310 320
     * This code is executed if the received event was not about the delay.
311 321
     * The received event could be casued by any listener.
......
314 324
    if (eventmask & _eventListenerGPIO.events) {
315 325
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
316 326
      // PD event
317
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
327
      if (eventflags & moduleSsspEventflagPD()) {
318 328
        shutdown = AOS_SHUTDOWN_PASSIVE;
319 329
      } else {
320 330
#if defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK)
......
339 349
  }
340 350
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
341 351
  if (shutdown == AOS_SHUTDOWN_NONE) {
342
    aosSsspProceed(NULL, 0, 0, NULL);
352
    aosSsspProceed(NULL, 0, NULL);
343 353
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_1_2);
344 354
  }
345 355
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
346 356

  
347 357
  // proceed to startup stage 1.3
348
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
358
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
349 359
    /*
350 360
     * This code is executed if the received event was not about a deactivation of the snychronization signal.
351 361
     * The received event could be caused by any listener.
......
354 364
    if (eventmask & _eventListenerGPIO.events) {
355 365
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
356 366
      // PD event
357
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
367
      if (eventflags & moduleSsspEventflagPD()) {
358 368
        shutdown = AOS_SHUTDOWN_PASSIVE;
359 369
      } else {
360 370
#if defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK)
......
380 390

  
381 391
  // proceed to startup stage 2.1
382 392
#if (AMIROOS_CFG_SSSP_MASTER == true)
383
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
393
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, EVENTMASK_SSSPDELAY, &eventmask) != AOS_SUCCESS)) {
384 394
    /*
385 395
     * This code is executed if the received event was not about the delay.
386 396
     * The received event could be caused by any listener.
......
389 399
    if (eventmask & _eventListenerGPIO.events) {
390 400
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
391 401
      // PD event
392
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
402
      if (eventflags & moduleSsspEventflagPD()) {
393 403
        shutdown = AOS_SHUTDOWN_PASSIVE;
394 404
      } else {
395 405
#if defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK)
......
410 420
    }
411 421
  }
412 422
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
413
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
423
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
414 424
    /*
415 425
     * This code is executed if the received event was not about a deactivation of the snychronization signal.
416 426
     * The received event could be caused by any listener.
......
419 429
    if (eventmask & _eventListenerGPIO.events) {
420 430
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
421 431
      // PD event
422
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
432
      if (eventflags & moduleSsspEventflagPD()) {
423 433
        shutdown = AOS_SHUTDOWN_PASSIVE;
424 434
      } else {
425 435
#if defined(MODULE_SSSP_STARTUP_1_2_GPIOEVENT_HOOK)
......
525 535

  
526 536
  // proceed to startup stage 2.2
527 537
#if (AMIROOS_CFG_SSSP_MASTER == true)
528
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, 0, EVENTMASK_SSSPTIMER, &eventmask) != AOS_SUCCESS)) {
538
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, EVENTMASK_SSSPDELAY, &eventmask) != AOS_SUCCESS)) {
529 539
    /*
530 540
     * This code is executed if the received event was not about the delay.
531 541
     * The received event could be caused by any listener.
......
534 544
    if (eventmask & _eventListenerGPIO.events) {
535 545
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
536 546
      // PD event
537
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
547
      if (eventflags & moduleSsspEventflagPD()) {
538 548
        shutdown = AOS_SHUTDOWN_PASSIVE;
539 549
      } else {
540 550
#if defined(MODULE_SSSP_STARTUP_1_3_GPIOEVENT_HOOK)
......
559 569
  }
560 570
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
561 571
  if (shutdown == AOS_SHUTDOWN_NONE) {
562
    aosSsspProceed(NULL, 0, 0, NULL);
572
    aosSsspProceed(NULL, 0, NULL);
563 573
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_2_2);
564 574
  }
565 575
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
566 576

  
567 577
  // proceed to startup stage 3 (MSI is enabled), or to operation phase (no MSI)
568
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
578
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(&_eventListenerGPIO, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS)) {
569 579
    /*
570 580
     * This code is executed if the received event was not about a deactivation of the snychronization signal.
571 581
     * The received event could be caused by any listener.
......
574 584
    if (eventmask & _eventListenerGPIO.events) {
575 585
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
576 586
      // PD event
577
      if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
587
      if (eventflags & moduleSsspEventflagPD()) {
578 588
        shutdown = AOS_SHUTDOWN_PASSIVE;
579 589
      } else {
580 590
#if defined(MODULE_SSSP_STARTUP_2_2_GPIOEVENT_HOOK)
......
596 606
  }
597 607
  if (shutdown == AOS_SHUTDOWN_NONE) {
598 608
#if (AMIROOS_CFG_SSSP_MSI == true)
599
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_1);
609
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3);
600 610
#else /* (AMIROOS_CFG_SSSP_MSI == true) */
601 611
    aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_OPERATION);
602 612
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
......
607 617
   */
608 618

  
609 619
#if (AMIROOS_CFG_SSSP_MSI == true)
610

  
611
  //TODO: MSI
620
  {
621
    // initialize temporary MSI data
622
    aos_ssspmsidata_t msidata;
623
    aosSsspMsiInit(&msidata, EVENTMASK_SSSPDELAY, EVENTMASK_SSSPTIMEOUT, &_eventListenerGPIO);
624

  
625
    // execute module stack initialization (MSI) but react to unrelated events as well
626
    while ((shutdown == AOS_SHUTDOWN_NONE) && (aos.sssp.stage != AOS_SSSP_STAGE_OPERATION)) {
627
      // execute MSI routine
628
      aosSsspMsi(&msidata, &eventmask);
629
      // handly event (if any)
630
      if (eventmask) {
631
        // GPIO event
632
        if (eventmask & _eventListenerGPIO.events) {
633
          eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
634
          // PD event
635
          if (eventflags & moduleSsspEventflagPD()) {
636
            shutdown = AOS_SHUTDOWN_PASSIVE;
637
          } else {
638
  #if defined(MODULE_SSSP_STARTUP_3_GPIOEVENT_HOOK)
639
            MODULE_SSSP_STARTUP_3_GPIOEVENT_HOOK(eventmask, eventflags);
640
  #else /* defined(MODULE_SSSP_STARTUP_3_GPIOEVENT_HOOK) */
641
            /* silently ignore any other GPIO events */
642
  #endif /* defined(MODULE_SSSP_STARTUP_3_GPIOEVENT_HOOK) */
643
          }
644
        }
645
        // OS event
646
        else if (eventmask & _eventListenerOS.events) {
647
          eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
648
          _unexpectedEventError(eventmask, eventflags);
649
        }
650
        // unknown event
651
        else {
652
          _unexpectedEventError(eventmask, 0);
653
        }
654
      }
655
    }
656
  }
612 657

  
613 658
#if (HAL_USE_RTC == TRUE)
614 659

  
......
640 685

  
641 686
#if (AMIROOS_CFG_SSSP_ENABLE == true)
642 687
  /* ignore all SSSP signal events, except for PD and configured events */
643
  eventflags = MODULE_SSSP_EVENTFLAG_S;
688
  eventflags = moduleSsspEventflagS();
644 689
#if (AMIROOS_CFG_SSSP_MSI == true)
645 690
#if (AMIROOS_CFG_SSSP_STACK_START != true)
646
  eventflags |= MODULE_SSSP_EVENTFLAG_DN;
691
  eventflags |= moduleSsspEventflagDN();
647 692
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
648 693
#if (AMIROOS_CFG_SSSP_STACK_END != true)
649
  eventflags |= MODULE_SSSP_EVENTFLAG_UP;
694
  eventflags |= moduleSsspEventflagUP();
650 695
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
651 696
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
652 697
  eventflags &= ~((eventflags_t)AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK);
......
677 722
        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
678 723
#if (AMIROOS_CFG_SSSP_ENABLE == true)
679 724
        // PD event
680
        if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
725
        if (eventflags & moduleSsspEventflagPD()) {
681 726
          aosSsspShutdownInit(false);
682 727
          shutdown = AOS_SHUTDOWN_PASSIVE;
683 728
        }
......
742 787
     * Note that events for the optional signals UP and DN are not enabled as they are not utilized during SSSP shutdown phase.
743 788
     */
744 789
    chSysLock();
745
    _eventListenerGPIO.wflags |= MODULE_SSSP_EVENTFLAG_S;
790
    _eventListenerGPIO.wflags |= moduleSsspEventflagS();
746 791
    chSysUnlock();
747 792

  
748 793
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
......
816 861
#if (AMIROOS_CFG_SSSP_ENABLE == true)
817 862

  
818 863
  // proceed to SSSP shutdown stage 1.3
819
  aosSsspProceed(NULL, 0, 0, NULL);
864
  aosSsspProceed(NULL, 0, NULL);
820 865
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_1_3);
821 866

  
822 867
#if (AMIROOS_CFG_SSSP_SHUTDOWN == true)
......
828 873
   */
829 874

  
830 875
  // proceed to SSSP shutdown stage 2.1
831
  while (aosSsspProceed(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS) {
876
  while (aosSsspProceed(&_eventListenerGPIO, EVENTMASK_GPIO, &eventmask) != AOS_SUCCESS) {
832 877
    /*
833 878
     * This code is executed if the received event was not about a deactivation of the synchronization signal.
834 879
     * The received event could be caused by any listener.
......
855 900
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_1);
856 901

  
857 902
  // proceed to SSSP shutdown stage 2.2
858
  aosSsspProceed(NULL, 0, 0, &eventmask);
903
  aosSsspProceed(NULL, 0, &eventmask);
859 904
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_2);
860 905
  if (shutdown == AOS_SHUTDOWN_PASSIVE) {
861 906
    aosDbgPrintf("%s request received\n", eventmask ? "shutdown" : "restart");
......
875 920
    unsigned int identifier = 0;
876 921

  
877 922
    // receive the identifier, which specifies the type of shutdown/restart
878
    while ((eventmask = aosSsspShutdownWaitForIdentifierPulse(&_eventListenerGPIO, MODULE_SSSP_EVENTFLAG_S, EVENTMASK_SSSPTIMER, &identifier)) != EVENTMASK_SSSPTIMER) {
923
    while ((eventmask = aosSsspShutdownWaitForIdentifierPulse(&_eventListenerGPIO, moduleSsspEventflagS(), EVENTMASK_SSSPDELAY, &identifier)) != EVENTMASK_SSSPDELAY) {
879 924
      // GPIO event
880 925
      if (eventmask & _eventListenerGPIO.events) {
881 926
        eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
......
901 946
  }
902 947

  
903 948
  // proceed to SSSP shutdown stage 2.3
904
  aosSsspProceed(NULL, 0, 0, NULL);
949
  aosSsspProceed(NULL, 0, NULL);
905 950
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_SHUTDOWN_2_3);
906 951

  
907 952
  /*
core/src/aos_sssp.c
83 83

  
84 84
/**
85 85
 * @brief   A timer event based delays.
86
 * @details This timer must not be an AMiRo-OS timer, since delays occurr before system is initialized.
86 87
 */
87 88
static virtual_timer_t _delayTimer;
88 89

  
89 90
/**
90 91
 * @brief   Event source for the delay timer.
91 92
 */
92
static event_source_t _eventSourceDelay;
93
static event_source_t _delayEventSource;
93 94

  
94 95
/**
95 96
 * @brief   Event listener for the delay event.
96 97
 */
97
static event_listener_t _eventListenerDelay;
98
static event_listener_t _delayEventListener;
98 99

  
99 100
/******************************************************************************/
100 101
/* LOCAL FUNCTIONS                                                            */
......
103 104
#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__)
104 105

  
105 106
/**
106
 * @brief   Callback function for the Sync signal interrupt.
107
 * @brief   Callback function for the S signal interrupt.
107 108
 *
108 109
 * @param[in] args   Pointer to the GPIO line identifier.
109 110
 */
......
119 120
  // if the system is in operation phase
120 121
  if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) {
121 122
    // read signal S
122
    apalControlGpioGet(&moduleSsspGpioS, &s);
123
    apalControlGpioGet(moduleSsspSignalS(), &s);
123 124
    // if S was toggled from on to off
124 125
    if (s == APAL_GPIO_OFF) {
125 126
      // get current uptime
......
154 155

  
155 156
/**
156 157
 * @brief   Periodic system synchronization callback function.
157
 * @details Toggles the SYS_SYNC signal and reconfigures the system synchronization timer.
158
 * @details Toggles the S signal and reconfigures the system synchronization timer.
158 159
 *
159 160
 * @param[in] par   Unused parameters.
160 161
 */
......
162 163
{
163 164
  (void)par;
164 165

  
166
  // local variables
165 167
  apalControlGpioState_t state;
166 168
  aos_timestamp_t uptime;
167 169

  
168 170
  chSysLockFromISR();
169 171
  // toggle and read signal S
170
  apalGpioToggle(moduleSsspGpioS.gpio);
171
  apalControlGpioGet(&moduleSsspGpioS, &state);
172
  apalGpioToggle(moduleSsspSignalS()->gpio);
173
  apalControlGpioGet(moduleSsspSignalS(), &state);
172 174
  // if S was toggled from off to on
173 175
  if (state == APAL_GPIO_ON) {
174 176
    // reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time
175 177
    _synctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
176 178
    aosSysGetUptimeX(&uptime);
177
    chVTSetI(&_synctimer, chTimeUS2I(_synctime - uptime), _syncTimerCallback, NULL);
179
    chVTSetI(&_synctimer, chTimeUS2I((time_usecs_t)(_synctime - uptime)), _syncTimerCallback, NULL);
178 180
  }
179 181
  // if S was toggled from on to off
180 182
  else /* if (state == APAL_GPIO_OFF) */ {
......
199 201
  aos_timestamp_t t;
200 202
  aosSysGetUptimeX(&t);
201 203
  t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (t % AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
202
  chVTSetI(&_synctimer, chTimeUS2I((t > (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) ? (t - (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) : (t + (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2))), _syncTimerCallback, NULL);
204
  chVTSetI(&_synctimer, chTimeUS2I((time_usecs_t)((t > (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) ? (t - (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) : (t + (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)))), _syncTimerCallback, NULL);
203 205

  
204 206
  return;
205 207
}
......
226 228
 * @brief   Waits for the S signal to switch to the desired state.
227 229
 *
228 230
 * @param[in]   listener      Pointer to the GPIO event listener to be used.
229
 * @param[in]   flags         Event flags to listen to by the event listener (indicating a S signal event).
230 231
 * @param[in]   signalstate   Desired state of the S signal ti be waited for.
231 232
 * @param[out]  received      Output variable to store the received event mask to.
232 233
 *
233 234
 * @return  Status, indicating whether the expected event was received.
234 235
 */
235
static inline aos_status_t _waitForS(event_listener_t* listener, eventflags_t flags, apalControlGpioState_t signalstate, eventmask_t* received)
236
static inline aos_status_t _waitForS(event_listener_t* listener, apalControlGpioState_t signalstate, eventmask_t* received)
236 237
{
237 238
  aosDbgCheck(listener != NULL);
238
  aosDbgCheck(flags != 0);
239 239
  aosDbgCheck(received != NULL);
240 240

  
241
  // local variables
242
  aos_status_t status = AOS_FAILURE;
243

  
241 244
  // wait for the next event (do not apply any filters in order not to miss any events)
242 245
  *received = chEvtWaitOne(ALL_EVENTS);
243 246
  // if the correct event was triggered
244
  if (*received == listener->events) {
247
  if (*received & listener->events) {
245 248
    apalControlGpioState_t s;
246
    apalControlGpioGet(&moduleSsspGpioS, &s);
249
    apalControlGpioGet(moduleSsspSignalS(), &s);
250
    chSysLock();
247 251
    // only check for the expected event
248
    if (flags & listener->flags && s == signalstate) {
252
    if ((listener->flags & moduleSsspEventflagS()) && (s == signalstate)) {
249 253
      // unset the expected flags but keep any other ones
250
      listener->flags &= ~flags;
251
      return AOS_SUCCESS;
254
      listener->flags &= ~moduleSsspEventflagS();
255
      status = AOS_SUCCESS;
252 256
    }
257
    // if no further flags are set
258
    if (listener->flags == 0) {
259
      // clear event
260
      *received &= ~(listener->events);
261
    }
262
    chSysUnlock();
253 263
  }
254 264

  
255
  return AOS_FAILURE;
265
  return status;
256 266
}
257 267

  
258 268
/**
......
260 270
 *
261 271
 * @param[in]   dt          Delay time in microseconds to be set to the timer.
262 272
 * @param[in]   mask        Event mask to be used for the delay timer.
263
 * @param[in]   arm_timer   Flag to indicate whether the timer has to be armed yet (i.e. on first call of this function).
264 273
 * @param[out]  received    Output variable to store the received event mask to.
265 274
 *
266 275
 * @return  Status, indicating whether the expected event (delay timer) was received.
267 276
 */
268
static inline aos_status_t _delay(uint32_t dt, eventmask_t mask, bool arm_timer, eventmask_t* received)
277
static inline aos_status_t _delay(uint32_t dt, eventmask_t mask, eventmask_t* received)
269 278
{
270 279
  aosDbgCheck(dt != TIME_IMMEDIATE);
271 280
  aosDbgCheck(mask != 0);
272 281
  aosDbgCheck(received != NULL);
273 282

  
274 283
  // arm the delay timer once
275
  if (arm_timer) {
276
    chEvtRegisterMask(&_eventSourceDelay, &_eventListenerDelay, mask);
277
    chVTSet(&_delayTimer, chTimeUS2I(dt), _timerCallback, &_eventSourceDelay);
284
  if (!chVTIsArmed(&_delayTimer)) {
285
    chEvtRegisterMask(&_delayEventSource, &_delayEventListener, mask);
286
    chVTSet(&_delayTimer, chTimeUS2I(dt), _timerCallback, &_delayEventSource);
278 287
  }
279 288

  
280 289
  // wait for any event to occur (do not apply any filters in order not to miss any events)
281 290
  *received = chEvtWaitOne(ALL_EVENTS);
282 291

  
283 292
  // if the timer event was received, cleanup
284
  if (*received & _eventListenerDelay.events) {
285
    chEvtUnregister(&_eventSourceDelay, &_eventListenerDelay);
293
  if (*received & _delayEventListener.events) {
294
    chEvtUnregister(&_delayEventSource, &_delayEventListener);
295
    *received &= ~(_delayEventListener.events);
286 296
    return AOS_SUCCESS;
287 297
  }
288 298

  
289 299
  return AOS_FAILURE;
290 300
}
291 301

  
302
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
303

  
304
/**
305
 * @brief   Serialize a BCB message.
306
 * @details The individual primitives are serialized in big-endian fashion.
307
 *
308
 * @param[out]  buffer    Buffer to write the serialized message to.
309
 * @param[in]   message   The message to be serialized.
310
 */
311
aos_status_t _serializeBcbMessage(uint8_t* buffer, aos_ssspbcbmessage_t message)
312
{
313
  aosDbgCheck(buffer != NULL);
314

  
315
  // encode the message depending on its type
316
  switch (message.type) {
317
    case AOS_SSSP_BCBMESSAGE_MSIINIT:
318
    case AOS_SSSP_BCBMESSAGE_MSIABORT:
319
    {
320
      buffer[0] = message.type;
321
      return AOS_SUCCESS;
322
    }
323
    case AOS_SSSP_BCBMESSAGE_MSIID:
324
    {
325
      buffer[0] = message.type;
326
      for (size_t byte = 0; byte < sizeof(aos_ssspmoduleid_t); ++byte) {
327
        buffer[byte+1] = (message.payload.id >> (8 * (sizeof(aos_ssspmoduleid_t) - (byte+1)))) & 0xFF;
328
      }
329
      return AOS_SUCCESS;
330
    }
331
    default:
332
    {
333
      return AOS_FAILURE;
334
    }
335
  }
336
}
337

  
338
/**
339
 * @brief   Deserialize a BCB message.
340
 * @details The individual primitives must be serialized in big-endian fashion.
341
 *
342
 * @param[out]  message   Message object to be filled.
343
 * @param[in]   buffer    Buffer holding the serialized message.
344
 */
345
aos_status_t _deserializeBcbMessage(aos_ssspbcbmessage_t* message, uint8_t* buffer)
346
{
347
  aosDbgCheck(message != NULL);
348
  aosDbgCheck(buffer != NULL);
349

  
350
  // only decode the first byte, which contains the message type
351
  message->type = buffer[0];
352

  
353
  // decode the message depedning on its type
354
  switch (message->type) {
355
    case AOS_SSSP_BCBMESSAGE_MSIINIT:
356
    case AOS_SSSP_BCBMESSAGE_MSIABORT:
357
    {
358
      return AOS_SUCCESS;
359
    }
360
    case AOS_SSSP_BCBMESSAGE_MSIID:
361
    {
362
      message->payload.id = 0;
363
      for (size_t byte = 0; byte < sizeof(aos_ssspmoduleid_t); ++byte) {
364
        message->payload.id |= (aos_ssspmoduleid_t)(buffer[byte+1] << (8 * (sizeof(aos_ssspmoduleid_t) - (byte+1))));
365
      }
366
      return AOS_SUCCESS;
367
    }
368
    default:
369
    {
370
      message->type = AOS_SSSP_BCBMESSAGE_INVALID;
371
      return AOS_FAILURE;
372
    }
373
  }
374
}
375

  
376
/**
377
 * @brief   Common outro of the module stack initialization (MSI).
378
 * @details This function must be called on failure, success and if MSI is skipped.
379
 *
380
 * @param[in] msidata   Pointer to the temporary data structure used during MSI.
381
 */
382
void _msiOutro(aos_ssspmsidata_t* msidata)
383
{
384
  aosDbgCheck(msidata != NULL);
385

  
386
  // local variables
387
  eventmask_t mask = 0;
388

  
389
  // start the internal uptime aggregation
390
  chSysLock();
391
  aosSysStartUptimeS();
392
#if (AMIROOS_CFG_SSSP_MASTER == true)
393
  // start toggling S for system synchronization
394
  _syncTimerStartS();
395
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
396
  chSysUnlock();
397

  
398
  // reset delay timer
399
  chVTIsArmed(&_delayTimer);
400
  // unregister delay events
401
  mask |= _delayEventListener.events;
402
  chEvtUnregister(&_delayEventSource, &_delayEventListener);
403

  
404
#if (AMIROOS_CFG_SSSP_STACK_END != true)
405
  // deactivate UP signal
406
  apalControlGpioSet(moduleSsspSignalUP(), APAL_GPIO_OFF);
407
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
408

  
409
  // reset timeout timer
410
  chVTReset(&msidata->timeout.timer);
411
  // unregister timeout events
412
  mask |= msidata->timeout.eventlistener.events;
413
  chEvtUnregister(&msidata->timeout.eventsource, &msidata->timeout.eventlistener);
414

  
415
  // discard any pending timing events
416
  chEvtWaitAnyTimeout(mask, TIME_IMMEDIATE);
417

  
418
  // proceed to operation phase
419
  aos.sssp.stage = AOS_SSSP_STAGE_OPERATION;
420

  
421
  return;
422
}
423

  
424
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
425

  
292 426
/******************************************************************************/
293 427
/* EXPORTED FUNCTIONS                                                         */
294 428
/******************************************************************************/
......
300 434
{
301 435
  aosDbgCheck(system_uptime != NULL);
302 436

  
303
  // local variables
304
  apalControlGpioState_t state;
305

  
306 437
#if (AMIROOS_CFG_SSSP_STARTUP == true)
307 438
  // AMiRo-OS has to perform the basic initialization
308 439
  aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_1_1;
......
311 442
  aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_2_1;
312 443
#endif /* (AMIROOS_CFG_SSSP_STARTUP == true) */
313 444

  
445
  // module ID is initialized as 'invalid'
446
  aos.sssp.moduleId = AOS_SSSP_MODULEID_INVALID;
447

  
448
#if (AMIROOS_CFG_DBG == true)
314 449
  // check all SSSP signals for correct state
315
  apalControlGpioGet(&moduleSsspGpioS, &state);
316
  aosDbgAssert(state == APAL_GPIO_ON);
317
  apalControlGpioGet(&moduleSsspGpioPD, &state);
318
  aosDbgAssert(state == APAL_GPIO_OFF);
450
  {
451
    apalControlGpioState_t state;
452
    apalControlGpioGet(moduleSsspSignalS(), &state);
453
    aosDbgAssert(state == APAL_GPIO_ON);
454
    apalControlGpioGet(moduleSsspSignalPD(), &state);
455
    aosDbgAssert(state == APAL_GPIO_OFF);
319 456
#if (AMIROOS_CFG_SSSP_MSI == true)
320
#if (AMIROOS_CFG_SSSP_STACK_END != true)
321
  apalControlGpioGet(&moduleSsspGpioUP, &state);
322
  aosDbgAssert(state == APAL_GPIO_OFF);
323
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
324 457
#if (AMIROOS_CFG_SSSP_STACK_START != true)
325
  apalControlGpioGet(&moduleSsspGpioDN, &state);
326
  aosDbgAssert(state == APAL_GPIO_OFF);
458
    apalControlGpioGet(moduleSsspSignalDN(), &state);
459
    aosDbgAssert(state == APAL_GPIO_OFF);
327 460
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
461
#if (AMIROOS_CFG_SSSP_STACK_END != true)
462
    apalControlGpioGet(moduleSsspSignalUP(), &state);
463
    aosDbgAssert(state == APAL_GPIO_OFF);
464
#endif /* (AMIROOS_CFG_SSSP_END_START != true) */
328 465
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
329

  
330
#if (AMIROOS_CFG_SSSP_MSI == true)
331
  // module ID is initialized as 'invalid'
332
  aos.sssp.moduleId = AOS_SSSP_MODULEID_INVALID;
333
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
466
  }
467
#endif /* (AMIROOS_CFG_DBG == true) */
334 468

  
335 469
  // initialize static variables
336 470
  _uptime = system_uptime;
......
342 476
  _syncskew = 0.0f;
343 477
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
344 478
  chVTObjectInit(&_delayTimer);
345
  chEvtObjectInit(&_eventSourceDelay);
479
  chEvtObjectInit(&_delayEventSource);
346 480

  
347 481
  // signal interrupt setup
348
  palSetLineCallback(moduleSsspGpioPD.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioPD.gpio->line);
349
  palEnableLineEvent(moduleSsspGpioPD.gpio->line, APAL2CH_EDGE(moduleSsspGpioPD.meta.edge));
482
  palSetLineCallback(moduleSsspSignalPD()->gpio->line, aosSysGetStdGpioCallback(), &moduleSsspSignalPD()->gpio->line);
483
  palEnableLineEvent(moduleSsspSignalPD()->gpio->line, APAL2CH_EDGE(moduleSsspSignalPD()->meta.edge));
350 484
#if (AMIROOS_CFG_SSSP_MASTER == true)
351
  palSetLineCallback(moduleSsspGpioS.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioS.gpio->line);
485
  palSetLineCallback(moduleSsspSignalS()->gpio->line, aosSysGetStdGpioCallback(), &moduleSsspSignalS()->gpio->line);
352 486
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
353
  palSetLineCallback(moduleSsspGpioS.gpio->line, _gpioCallbackSSignal, &moduleSsspGpioS.gpio->line);
487
  palSetLineCallback(moduleSsspSignalS()->gpio->line, _gpioCallbackSSignal, &moduleSsspSignalS()->gpio->line);
354 488
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
355
  palEnableLineEvent(moduleSsspGpioS.gpio->line, APAL2CH_EDGE(moduleSsspGpioS.meta.edge));
489
  palEnableLineEvent(moduleSsspSignalS()->gpio->line, APAL2CH_EDGE(moduleSsspSignalS()->meta.edge));
356 490
#if (AMIROOS_CFG_SSSP_MSI == true)
357 491
#if (AMIROOS_CFG_SSSP_STACK_START != true)
358
  palSetLineCallback(moduleSsspGpioDN.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioDN.gpio->line);
359
  palEnableLineEvent(moduleSsspGpioDN.gpio->line, APAL2CH_EDGE(moduleSsspGpioDN.meta.edge));
492
  palSetLineCallback(moduleSsspSignalDN()->gpio->line, aosSysGetStdGpioCallback(), &moduleSsspSignalDN()->gpio->line);
493
  palEnableLineEvent(moduleSsspSignalDN()->gpio->line, APAL2CH_EDGE(moduleSsspSignalDN()->meta.edge));
360 494
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
361 495
#if (AMIROOS_CFG_SSSP_STACK_END != true)
362
  palSetLineCallback(moduleSsspGpioUP.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioUP.gpio->line);
363
  palEnableLineEvent(moduleSsspGpioUP.gpio->line, APAL2CH_EDGE(moduleSsspGpioUP.meta.edge));
496
  palSetLineCallback(moduleSsspSignalUP()->gpio->line, aosSysGetStdGpioCallback(), &moduleSsspSignalUP()->gpio->line);
497
  palEnableLineEvent(moduleSsspSignalUP()->gpio->line, APAL2CH_EDGE(moduleSsspSignalUP()->meta.edge));
364 498
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
365 499
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
366 500

  
......
373 507
 *          The function aosSsspShutdownInit() must be used instead.
374 508
 *
375 509
 * @param[in]   listener  An optional listener, in case the system has to wait for a specific event.
376
 * @param[in]   flags     The relevant flags to wait for (mandatory if a listener is given).
377 510
 * @param[in]   mask      If the stage transition involves a timer event (handled internally by this function),
378 511
 *                        the given input value of this parameter defines the mask to be used for that event.
379 512
 *                        In case a listener was specified, the according mask is retrieved from the listener but this parameter is still used as input for sanity checks.
......
381 514
 *
382 515
 * @return  Status, indicating whether proceeding in the protocol was successful.
383 516
 */
384
aos_status_t aosSsspProceed(event_listener_t* listener, eventflags_t flags, eventmask_t mask, eventmask_t* received)
517
aos_status_t aosSsspProceed(event_listener_t* listener, eventmask_t mask, eventmask_t* received)
385 518
{
386 519
  // local variables
387 520
#pragma GCC diagnostic push
......
402 535
    {
403 536
#if (AMIROOS_CFG_SSSP_MASTER == true)
404 537
      aosDbgCheck(listener == NULL);
405
      aosDbgCheck(flags == 0);
406 538
      aosDbgCheck(mask != 0);
407 539
      aosDbgCheck(received != NULL);
408 540

  
409 541
      // delay execution and deactivate the S signal on success
410
      if (_delay(AOS_SSSP_DELAY, mask, (laststage != AOS_SSSP_STAGE_STARTUP_1_1), received) == AOS_SUCCESS) {
411
        apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
542
      if (_delay(AOS_SSSP_DELAY, mask, received) == AOS_SUCCESS) {
543
        apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
412 544
        nextstage = AOS_SSSP_STAGE_STARTUP_1_2;
413 545
      }
414 546
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
415 547
      aosDbgCheck(listener == NULL);
416
      aosDbgCheck(flags == 0);
417 548
      aosDbgCheck(mask == 0);
418 549
      aosDbgCheck(received == NULL);
419 550

  
420 551
      // deactivate S signal and proceed
421
      apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
552
      apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
422 553
      nextstage = AOS_SSSP_STAGE_STARTUP_1_2;
423 554
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
424 555
      break;
......
430 561
    case AOS_SSSP_STAGE_STARTUP_1_2:
431 562
    {
432 563
      aosDbgCheck(listener != NULL);
433
      aosDbgCheck(flags != 0);
434 564
      aosDbgCheck(mask == listener->events);
435 565
      aosDbgCheck(received != NULL);
436 566

  
437 567
      // wait for the S signal to become inactive and proceed on success
438
      if (_waitForS(listener, flags, APAL_GPIO_OFF, received) == AOS_SUCCESS) {
568
      if (_waitForS(listener, APAL_GPIO_OFF, received) == AOS_SUCCESS) {
439 569
        nextstage = AOS_SSSP_STAGE_STARTUP_1_3;
440 570
      }
441 571
      break;
......
449 579
    {
450 580
#if (AMIROOS_CFG_SSSP_MASTER == true)
451 581
      aosDbgCheck(listener == NULL);
452
      aosDbgCheck(flags == 0);
453 582
      aosDbgCheck(mask != 0);
454 583
      aosDbgCheck(received != NULL);
455 584

  
456 585
      // delay execution and deactivate the S signal on success
457
      if (_delay(AOS_SSSP_DELAY, mask, (laststage != AOS_SSSP_STAGE_STARTUP_1_3), received) == AOS_SUCCESS) {
458
        apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
586
      if (_delay(AOS_SSSP_DELAY, mask, received) == AOS_SUCCESS) {
587
        apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_ON);
459 588
        nextstage = AOS_SSSP_STAGE_STARTUP_2_1;
460 589
      }
461 590
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
462 591
      aosDbgCheck(listener != NULL);
463
      aosDbgCheck(flags != 0);
464 592
      aosDbgCheck(mask == listener->events);
465 593
      aosDbgCheck(received != NULL);
466 594

  
467 595
      // wait for the S signal to become active and activate it as well and proceed on success
468
      if (_waitForS(listener, flags, APAL_GPIO_ON, received) == AOS_SUCCESS) {
469
        apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
596
      if (_waitForS(listener, APAL_GPIO_ON, received) == AOS_SUCCESS) {
597
        apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_ON);
470 598
        nextstage = AOS_SSSP_STAGE_STARTUP_2_1;
471 599
      }
472 600
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
......
483 611
    {
484 612
#if (AMIROOS_CFG_SSSP_MASTER == true)
485 613
      aosDbgCheck(listener == NULL);
486
      aosDbgCheck(flags == 0);
487 614
      aosDbgCheck(mask != 0);
488 615
      aosDbgCheck(received != NULL);
489 616

  
490 617
      // delay execution and deactivate the S signal on success
491
      if (_delay(AOS_SSSP_DELAY, mask, (laststage != AOS_SSSP_STAGE_STARTUP_2_1), received) == AOS_SUCCESS) {
492
        apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
618
      if (_delay(AOS_SSSP_DELAY, mask, received) == AOS_SUCCESS) {
619
        apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
493 620
        nextstage = AOS_SSSP_STAGE_STARTUP_2_2;
621
      } else {
622
        aosprintf(".");
494 623
      }
495 624
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
496 625
      aosDbgCheck(listener == NULL);
497
      aosDbgCheck(flags == 0);
498 626
      aosDbgCheck(mask == 0);
499 627
      aosDbgCheck(received == NULL);
500 628

  
501 629
      // deactivate S signal and proceed
502
      apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
630
      apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
503 631
      nextstage = AOS_SSSP_STAGE_STARTUP_2_2;
504 632
      mask = 0;
505 633
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
......
513 641
    case AOS_SSSP_STAGE_STARTUP_2_2:
514 642
    {
515 643
      aosDbgCheck(listener != NULL);
516
      aosDbgCheck(flags != 0);
517 644
      aosDbgCheck(mask == listener->events);
518 645
      aosDbgCheck(received != NULL);
519 646

  
520 647
      // wait for the S signal to become inactive and proceed on success
521
      if (_waitForS(listener, flags, APAL_GPIO_OFF, received) == AOS_SUCCESS) {
648
      if (_waitForS(listener, APAL_GPIO_OFF, received) == AOS_SUCCESS) {
522 649
#if (AMIROOS_CFG_SSSP_MSI == true)
523 650
        nextstage = AOS_SSSP_STAGE_STARTUP_3;
524 651
#else /* (AMIROOS_CFG_SSSP_MSI == true) */
525
        chSysLock();
526 652
        // start the internal uptime aggregation
653
        chSysLock();
527 654
        aosSysStartUptimeS();
528 655
#if (AMIROOS_CFG_SSSP_MASTER == true)
529 656
        // start toggling S for system synchronization
......
536 663
      break;
537 664
    }
538 665

  
539
#if (AMIROOS_CFG_SSSP_MSI == true)
540

  
541
      //TODO
542

  
543
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
666
    /*
667
     * PLEASE NOTE:
668
     * Stage transitions during MSI are not hanlded by thins function but are executed in aosSsspMsi().
669
     */
544 670

  
545 671
    /*
546 672
     * Invalid operation.
......
560 686
    case AOS_SSSP_STAGE_SHUTDOWN_1_2:
561 687
    {
562 688
      aosDbgCheck(listener == NULL);
563
      aosDbgCheck(flags == 0);
564 689
      aosDbgCheck(mask == 0);
565 690
      aosDbgCheck(received == NULL);
566 691

  
567 692
      // delay execution
568 693
      aosThdUSleep(AOS_SSSP_DELAY);
569 694
      // deactivate S signal
570
      apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
695
      apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
571 696
      nextstage = AOS_SSSP_STAGE_SHUTDOWN_1_3;
572 697
      break;
573 698
    }
......
580 705
    case AOS_SSSP_STAGE_SHUTDOWN_1_3:
581 706
    {
582 707
      aosDbgCheck(listener != NULL);
583
      aosDbgCheck(flags != 0);
584 708
      aosDbgCheck(mask == listener->events);
585 709
      aosDbgCheck(received != NULL);
586 710

  
587 711
      // wait for the S signal to become inactive and proceed on success
588
      if (_waitForS(listener, flags, APAL_GPIO_OFF, received) == AOS_SUCCESS) {
712
      if (_waitForS(listener, APAL_GPIO_OFF, received) == AOS_SUCCESS) {
589 713
        nextstage = AOS_SSSP_STAGE_SHUTDOWN_2_1;
590 714
      }
591 715
      break;
......
598 722
    case AOS_SSSP_STAGE_SHUTDOWN_2_1:
599 723
    {
600 724
      aosDbgCheck(listener == NULL);
601
      aosDbgCheck(flags == 0);
602 725
      aosDbgCheck(mask == 0);
603 726
      aosDbgCheck(received != NULL);
604 727

  
605 728
      // evaluate PD signal
606 729
      apalControlGpioState_t pd;
607
      apalControlGpioGet(&moduleSsspGpioPD, &pd);
730
      apalControlGpioGet(moduleSsspSignalPD(), &pd);
608 731
      *received = (pd == APAL_GPIO_ON) ? (eventmask_t)~0 : 0;
609 732
      nextstage = AOS_SSSP_STAGE_SHUTDOWN_2_2;
610 733
      break;
......
616 739
    case AOS_SSSP_STAGE_SHUTDOWN_2_2:
617 740
    {
618 741
      aosDbgCheck(listener == NULL);
619
      aosDbgCheck(flags == 0);
620 742
      aosDbgCheck(mask == 0);
621 743
      aosDbgCheck(received == NULL);
622 744

  
......
642 764
  return status;
643 765
}
644 766

  
767
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
768

  
769
/**
770
 * @brief   Initialize MSI data structure.
771
 *
772
 * @param[out]  msidata       Pointer to the MSI data structure to be initialized.
773
 * @param[in]   delayMask     Event maks used for delay events.
774
 * @param[in]   timeoutMask   Event mask used for timeout events.
775
 * @param[in]   gpioListener  Event listener for GPIO events.
776
 */
777
void aosSsspMsiInit(aos_ssspmsidata_t* msidata, eventmask_t delayMask, eventmask_t timeoutMask, event_listener_t* gpioListener)
778
{
779
  aosDbgCheck(msidata != NULL);
780
  aosDbgCheck(gpioListener != NULL);
781

  
782
  // register delay events
783
  chEvtRegisterMask(&_delayEventSource, &_delayEventListener, delayMask);
784

  
785
  // initialize timeout related data
786
  chVTObjectInit(&msidata->timeout.timer);
787
  chEvtObjectInit(&msidata->timeout.eventsource);
788
  chEvtRegisterMask(&msidata->timeout.eventsource, &msidata->timeout.eventlistener, timeoutMask);
789

  
790
  // set GPIO event information
791
  msidata->signals.eventlistener = gpioListener;
792

  
793
  // initialize BCB related data
794
  msidata->bcb.lastid = AOS_SSSP_MODULEID_INVALID;
795

  
796
  return;
797
}
798

  
799
/**
800
 * @brief   Execute module stack initialization (MSI).
801
 *
802
 * @param[in]   msidata   Data required for MSI.
803
 * @param[out]  received  Output variable to store the received event mask to.
804
 */
805
void aosSsspMsi(aos_ssspmsidata_t* msidata, eventmask_t* received)
806
{
807
  aosDbgCheck(msidata != NULL);
808
  aosDbgCheck(received != NULL);
809

  
810
  /*
811
   * execute anything that does not depend on BCB messages or events
812
   */
813
  switch (aos.sssp.stage) {
814
    case AOS_SSSP_STAGE_STARTUP_3:
815
    case AOS_SSSP_STAGE_STARTUP_3_1:
816
    {
817
      aosDbgPrintf(">>> MSI init\n");
818
      // setup timeout timer
819
      chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
820
      // proceed
821
#if (AMIROOS_CFG_SSSP_MASTER == true)
822
      aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_1_BROADCASTINIT;
823
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
824
      aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_1_WAITFORINIT;
825
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
826
      break;
827
    }
828

  
829
#if (AMIROOS_CFG_SSSP_MASTER == true)
830
    case AOS_SSSP_STAGE_STARTUP_3_1_BROADCASTINIT:
831
    {
832
      aosDbgPrintf("%u\tsend INIT\t", chVTGetSystemTime());
833
      // send init command
834
      msidata->bcb.message.type = AOS_SSSP_BCBMESSAGE_MSIINIT;
835
      _serializeBcbMessage(msidata->bcb.buffer, msidata->bcb.message);
836
      if (moduleSsspBcbTransmit(msidata->bcb.buffer, sizeof(aos_ssspbcbmessage_t)) == AOS_SSSP_BCB_SUCCESS) {
837
        aosDbgPrintf("ok\tS+\t");
838
        // activate S
839
        apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_ON);
840
        // restart timeout timer
841
        chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
842
        // proceed
843
#if (AMIROOS_CFG_SSSP_STACK_START == true)
844
        aosDbgPrintf("->start\n");
845
        aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_2;
846
#else /* (AMIROOS_CFG_SSSP_STACK_START == true) */
847
        aosDbgPrintf("->count\n");
848
        aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT;
849
#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
850
      } else {
851
        aosDbgPrintf("fail\t->retry\n");
852
        // retry in next iteration
853
      }
854
      break;
855
    }
856
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
857

  
858
#if (AMIROOS_CFG_SSSP_STACK_START == true)
859
    case AOS_SSSP_STAGE_STARTUP_3_2:
860
    {
861
      aosDbgPrintf("%u\tstart\t", chVTGetSystemTime());
862
      // set the own module ID
863
      aos.sssp.moduleId = 1;
864
      // broadcast the new ID
865
      msidata->bcb.message.type = AOS_SSSP_BCBMESSAGE_MSIID;
866
      msidata->bcb.message.payload.id = aos.sssp.moduleId;
867
      aosDbgPrintf("bc ID (%u)\t", msidata->bcb.message.payload.id);
868
      _serializeBcbMessage(msidata->bcb.buffer, msidata->bcb.message);
869
      if (moduleSsspBcbTransmit(msidata->bcb.buffer, sizeof(aos_ssspbcbmessage_t)) == AOS_SSSP_BCB_SUCCESS) {
870
        aosDbgPrintf("ok\t->count\n");
871
        // restart timeout timer
872
        chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
873
        // set delay timer so UP will be activated and S deactivated later
874
        chVTSet(&_delayTimer, chTimeUS2I(AOS_SSSP_DELAY), _timerCallback, &_delayEventSource);
875
        // store the transmitted ID
876
        msidata->bcb.lastid = msidata->bcb.message.payload.id;
877
        // proceed
878
        aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT;
879
      } else {
880
        aosDbgPrintf("fail\t->retry\n");
881
        // retry next iteration
882
      }
883
      break;
884
    }
885
#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
886

  
887
    case AOS_SSSP_STAGE_STARTUP_3_3_BROADCASTID:
888
    {
889
      // broadcast ID
890
      msidata->bcb.message.type = AOS_SSSP_BCBMESSAGE_MSIID;
891
      msidata->bcb.message.payload.id = aos.sssp.moduleId;
892
      aosDbgPrintf("%u\tbc ID (%u)\t", chVTGetSystemTime(), msidata->bcb.message.payload.id);
893
      _serializeBcbMessage(msidata->bcb.buffer, msidata->bcb.message);
894
      if (moduleSsspBcbTransmit(msidata->bcb.buffer, sizeof(aos_ssspbcbmessage_t)) == AOS_SSSP_BCB_SUCCESS) {
895
        aosDbgPrintf("ok->count\n");
896
        // restart timeout timer
897
        chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
898
        // set delay timer so UP will be activated and S deactivated later
899
        chVTSet(&_delayTimer, chTimeUS2I(AOS_SSSP_DELAY), _timerCallback, &_delayEventSource);
900
        // store the transmitted ID
901
        msidata->bcb.lastid = msidata->bcb.message.payload.id;
902
        // return to receiving
903
        aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT;
904
      } else {
905
        aosDbgPrintf("fail\t->retry\n");
906
        // retry next iteration
907
      }
908
      break;
909
    }
910

  
911
    case AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT:
912
    {
913
      aosDbgPrintf("%u\tabort\t", chVTGetSystemTime());
914
      // reset timeout timer
915
      chVTReset(&msidata->timeout.timer);
916
      // transmit abort message
917
      msidata->bcb.message.type = AOS_SSSP_BCBMESSAGE_MSIABORT;
918
      _serializeBcbMessage(msidata->bcb.buffer, msidata->bcb.message);
919
      if (moduleSsspBcbTransmit(msidata->bcb.buffer, sizeof(aos_ssspbcbmessage_t)) == AOS_SSSP_BCB_SUCCESS) {
920
        aosDbgPrintf("ok\tS-\t->sync\n");
921
        // deactivate S
922
        apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
923
        // proceed
924
        aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_SYNC;
925
      } else {
926
        aosDbgPrintf("fail\t->retry\n");
927
        // retry next iteration
928
      }
929
      break;
930
    }
931

  
932
    default:
933
    {
934
      // all other stages depend on events or BCB messages and are thus handled below
935
      break;
936
    }
937
  }
938

  
939
  /*
940
   * handle BCB messages
941
   */
942
  msidata->bcb.status = moduleSsspBcbReceive(msidata->bcb.buffer, sizeof(aos_ssspbcbmessage_t));
943
  switch (msidata->bcb.status) {
944

  
945
    /* VALID BCB MESSAGE
946
     * A message was received via BCB that seems to be plausible.
947
     * The first BCB message initiates the sequence once.
948
     * During MSI an arbitrary number of IDs will be received.
949
     * Abort messages can be received at any time.
950
     */
951
    case AOS_SSSP_BCB_SUCCESS:
952
    {
953
      aosDbgPrintf("%u\tBCB\t", chVTGetSystemTime());
954
      // deserialize message and handle types differently
955
      _deserializeBcbMessage(&msidata->bcb.message, msidata->bcb.buffer);
956
      switch (msidata->bcb.message.type) {
957
        // initialization message
958
        case AOS_SSSP_BCBMESSAGE_MSIINIT:
959
        {
960
#if (AMIROOS_CFG_SSSP_MASTER == true)
961
          aosDbgPrintf("INIT\t->abort\n");
962
          // initiate abortion
963
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
964
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
965
          aosDbgPrintf("INIT\t");
966
          // check for correct SSSP stage
967
          if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_1_WAITFORINIT) {
968
            aosDbgPrintf("S+\t");
969
            // activate S
970
            apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_ON);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff