Revision c53ef0b1 core/src/aos_sssp.c

View differences:

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);
971
            // restart timeout timer
972
            chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
973
            // proceed
974
#if (AMIROOS_CFG_SSSP_STACK_START == true)
975
            aosDbgPrintf("->start\n");
976
            aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_2;
977
#else /* (AMIROOS_CFG_SSSP_STACK_START == true) */
978
            aosDbgPrintf("->count\n");
979
            aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT;
980
#endif /* (AMIROOS_CFG_SSSP_STACK_START == true) */
981
          } else {
982
            aosDbgPrintf("->abort\n");
983
            // initiate abortion
984
            aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
985
          }
986
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
987
          break;
988
        }
989
        // ID message
990
        case AOS_SSSP_BCBMESSAGE_MSIID:
991
        {
992
          aosDbgPrintf("ID (%u)\t", msidata->bcb.message.payload.id);
993
          // check for correct stage and whether ID was increased
994
          if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT &&
995
              msidata->bcb.message.payload.id > msidata->bcb.lastid) {
996
            aosDbgPrintf("ok\n");
997
            // restart timeout timer
998
            chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
999
            // store ID
1000
            msidata->bcb.lastid = msidata->bcb.message.payload.id;
1001
          } else {
1002
            aosDbgPrintf("fail\t->abort\n");
1003
            // initiate abortion
1004
            aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1005
          }
1006
          break;
1007
        }
1008
        // abort message
1009
        case AOS_SSSP_BCBMESSAGE_MSIABORT:
1010
        {
1011
          aosDbgPrintf("ABORT\tS-\t->sync\n");
1012
          // reset timeout timer
1013
          chVTReset(&msidata->timeout.timer);
1014
          // deactivate S
1015
          apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
1016
          // proceed to abort synchronization
1017
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_SYNC;
1018
          break;
1019
        }
1020
        // invalid message
1021
        default:
1022
        {
1023
          aosDbgPrintf("invalid\t->abort\n");
1024
          // initiate abortion
1025
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1026
          break;
1027
        }
1028
      }
1029
      return;
1030
    }
1031

  
1032
    /* INVALID BCB MESSAGE
1033
     * An obviously invalid message was received via BCB.
1034
     */
1035
    case AOS_SSSP_BCB_INVALIDMSG:
1036
    {
1037
      // error but ignore
1038
      aosDbgPrintf("WARNING: unknown message received via BCB\n");
1039
      break;
1040
    }
1041

  
1042
    /* NO BCB MESSAGE
1043
     * No message was received via BCB at all.
1044
     */
1045
    case AOS_SSSP_BCB_ERROR:
1046
    {
1047
      // do nothing and proceed
1048
      break;
1049
    }
1050
  }
1051

  
1052
  /*
1053
   * handle events
1054
   */
1055
  *received = chEvtWaitOneTimeout(ALL_EVENTS, TIME_IMMEDIATE);
1056
  /* TIMEOUT EVENT
1057
   * Timeouts can occur at any time during MSI after they have been initialized.
1058
   * As soon as the module has made it to the 3.4 completion stage, there will be no more timeouts, though.
1059
   */
1060
  if (*received & msidata->timeout.eventlistener.events) {
1061
    aosDbgPrintf("%u\ttimeout\t", chVTGetSystemTime());
1062
    // special cases
1063
    if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_1_WAITFORINIT ||
1064
        aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION) {
1065
      // master did not initiate the sequence
1066
      if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_1_WAITFORINIT) {
1067
        aosDbgPrintf("no init\t->operation\n");
1068
        // invalidate module ID
1069
        aos.sssp.moduleId = AOS_SSSP_MODULEID_INVALID;
1070
        aosDbgPrintf("<<< MSI skipped\n");
1071
      }
1072
      // no abort messages received after completion
1073
      else /* if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION) */ {
1074
        aosDbgPrintf("success\t->operation\n");
1075
        aosDbgPrintf("<<< MSI completed\n");
1076
      }
1077
      // cleanup and proceed to operation phase
1078
      _msiOutro(msidata);
1079
    }
1080
    // general timeout
1081
    else {
1082
      aosDbgPrintf("->abort\n");
1083
      // initiate active abort
1084
      aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1085
    }
1086
    // clear event
1087
    chEvtGetAndClearFlags(&msidata->timeout.eventlistener);
1088
    *received &= ~(msidata->timeout.eventlistener.events);
1089
  }
1090
  /* DELAY EVENT
1091
   * Delays are only used to toggle the UP signal.
1092
   */
1093
  else if (*received & _delayEventListener.events) {
1094
    aosDbgPrintf("%u\tdelay\t", chVTGetSystemTime());
1095
#if (AMIROOS_CFG_SSSP_STACK_END == true)
1096
    apalControlGpioState_t s;
1097
    aosDbgPrintf("S-\t");
1098
    // deactivate S
1099
    apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
1100
    // verify deactivation
1101
    apalControlGpioGet(moduleSsspSignalS(), &s);
1102
    if (s == APAL_GPIO_OFF) {
1103
      aosDbgPrintf("ok\t->done\n");
1104
      // set the timeout timer so no abort messages are missed
1105
      chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
1106
      // proceed to the completion stage
1107
      aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION;
1108
    } else {
1109
      aosDbgPrintf("fail\t->abort\n");
1110
      // initiate active abort
1111
      aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1112
    }
1113
#else /* (AMIROOS_CFG_SSSP_STACK_END == true) */
1114
    apalControlGpioState_t s;
1115
    // read the current state of the UP signal
1116
    apalControlGpioGet(moduleSsspSignalUP(), &s);
1117
    if (s == APAL_GPIO_OFF) {
1118
      aosDbgPrintf("UP+ & S-\n");
1119
      // activate UP in order to trigger the next module
1120
      apalControlGpioSet(moduleSsspSignalUP(), APAL_GPIO_ON);
1121
      // deactivate S
1122
      apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
1123
      // set the delay timer so the UP signal will get deactivated again later
1124
      chVTSet(&_delayTimer, chTimeUS2I(AOS_SSSP_DELAY), _timerCallback, &_delayEventSource);
1125
    } else {
1126
      aosDbgPrintf("UP-\n");
1127
      // deactvate UP
1128
      apalControlGpioSet(moduleSsspSignalUP(), APAL_GPIO_OFF);
1129
    }
1130
#endif /* (AMIROOS_CFG_SSSP_STACK_END == true) */
1131
    // clear event
1132
    chEvtGetAndClearFlags(&_delayEventListener);
1133
    *received &= ~(_delayEventListener.events);
1134
  }
1135
  /* GPIO EVENT
1136
   * GPIO events can occurr at any time, but only DN and S events are expected.
1137
   * DN may be activated only once per module to trigger the counting process and is deactivated briefly after activation.
1138
   * S must only deactivate when MSI is comleted by the last module in the stack.
1139
   */
1140
  else if (*received & msidata->signals.eventlistener->events) {
1141
    aosDbgPrintf("%u\tGPIO\t", chVTGetSystemTime());
1142
    apalControlGpioState_t s;
1143
    // fetch event flags
1144
    eventflags_t flags = chEvtGetAndClearFlags(msidata->signals.eventlistener);
1145
#if (AMIROOS_CFG_SSSP_STACK_START != true)
1146
    // if the DN signal was triggered
1147
    if (flags & moduleSsspEventflagDN()) {
1148
      // read the signal state
1149
      apalControlGpioGet(moduleSsspSignalDN(), &s);
1150
      // rising edge
1151
      if (s == APAL_GPIO_ON) {
1152
        aosDbgPrintf("+DN\t");
1153
        // Correct SSSP stage and no ID assigned yet?
1154
        if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT &&
1155
            aos.sssp.moduleId == AOS_SSSP_MODULEID_INVALID) {
1156
          // set the own module ID
1157
          aos.sssp.moduleId = msidata->bcb.lastid + 1;
1158
          aosDbgPrintf("set ID (%u)\t->bc ID\n", aos.sssp.moduleId);
1159
          // proceed to broadcasting
1160
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_3_BROADCASTID;
1161
        }
1162
        // incorrect SSSP stage or ID already assigned (triggered for a second time)
1163
        else {
1164
          aosDbgPrintf("->abort\n");
1165
          // initiate active abort
1166
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1167
        }
1168
      }
1169
      // falling egde
1170
      else {
1171
        aosDbgPrintf("-DN\n");
1172
        // ignored
1173
      }
1174
      // clear DN flags
1175
      flags &= ~moduleSsspEventflagDN();
1176
    }
1177
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
1178
#if (AMIROOS_CFG_SSSP_STACK_END != true)
1179
    // if the UP signal was triggered
1180
    if (flags & moduleSsspEventflagUP()) {
1181
      /*
1182
       * The UP signal is acting as output only.
1183
       * Any events resulting from toggling the signal are thus ignored.
1184
       */
1185
      aosDbgPrintf("?UP\n");
1186
      // clear UP flags
1187
      flags &= ~moduleSsspEventflagUP();
1188
    }
1189
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
1190
    // if the S signal was triggered
1191
    if (flags & moduleSsspEventflagS()) {
1192
      // read the signal state
1193
      apalControlGpioGet(moduleSsspSignalS(), &s);
1194
      // rising edge
1195
      if (s == APAL_GPIO_ON) {
1196
        aosDbgPrintf("+S\n");
1197
        // ignored
1198
      }
1199
      // falling edge
1200
      else {
1201
        aosDbgPrintf("-S\t");
1202
        // special case
1203
        if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_SYNC) {
1204
          aosDbgPrintf("->operation\n");
1205
          // invalidate module ID
1206
          aos.sssp.moduleId = AOS_SSSP_MODULEID_INVALID;
1207
          // proceed
1208
          aosDbgPrintf("<<< MSI aborted\n");
1209
          _msiOutro(msidata);
1210
        }
1211
#if (AMIROOS_CFG_SSSP_STACK_END == true)
1212
        // Correct SSSP stage?
1213
        else if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION) {
1214
          aosDbgPrintf("ok\n");
1215
          // ignored
1216
        } else {
1217
          aosDbgPrintf("->abort\n");
1218
          // initialize abortion
1219
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1220
        }
1221
#else /* (AMIROOS_CFG_SSSP_STACK_END == true) */
1222
        // Correct SSSP stage and ID assigned?
1223
        else if (aos.sssp.stage == AOS_SSSP_STAGE_STARTUP_3_3_WAIT4EVENT &&
1224
            aos.sssp.moduleId != AOS_SSSP_MODULEID_INVALID) {
1225
          aosDbgPrintf("->done\n");
1226
          // set the timeout timer so no abort messages are missed
1227
          chVTSet(&msidata->timeout.timer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &msidata->timeout.eventsource);
1228
          // proceed to the completion stage
1229
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_COMPLETION;
1230
        } else {
1231
          aosDbgPrintf("->abort\n");
1232
          // initiate abortion
1233
          aos.sssp.stage = AOS_SSSP_STAGE_STARTUP_3_4_ABORTION_INIT;
1234
        }
1235
#endif /* (AMIROOS_CFG_SSSP_STACK_END == true) */
1236
      }
1237
      // clear S flags
1238
      flags &= ~moduleSsspEventflagS();
1239
    }
1240
    // any further flags set?
1241
    if (flags) {
1242
      aosDbgPrintf("0x%08X\n", flags);
1243
      // reassign remaining flags and do not clear event mask
1244
      msidata->signals.eventlistener->flags |= flags;
1245
    } else {
1246
      // clear event
1247
      *received &= ~(msidata->signals.eventlistener->events);
1248
    }
1249
  }
1250
  /* OTHER EVENT
1251
   * Any other events may occur as well but are not handled by this function
1252
   */
1253
  else if (*received != 0){
1254
    aosDbgPrintf("%u\tOTHER\t0x%08X\n", chVTGetSystemTime(), *received);
1255
    // do not clear the event mask
1256
  }
1257

  
1258
  return;
1259
}
1260

  
1261
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
1262

  
1263
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
1264

  
1265
/**
1266
 * @brief   Retreive the offset between local clock and system synchronization signal.
1267
 *
1268
 * @return
1269
 */
1270
inline float aosSsspGetSyncSkew(void)
1271
{
1272
  return _syncskew;
1273
}
1274

  
1275
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
1276

  
645 1277
/**
646 1278
 * @brief   Leave the operation pahse and initiate or acknowledge shutdown.
647 1279
 *
......
656 1288

  
657 1289
  // activate PD if this was an active shutdown initiation
658 1290
  if (active) {
659
    apalControlGpioSet(&moduleSsspGpioPD, APAL_GPIO_ON);
1291
    apalControlGpioSet(moduleSsspSignalPD(), APAL_GPIO_ON);
660 1292
  }
661 1293

  
662 1294
#if (AMIROOS_CFG_SSSP_MASTER == true)
......
665 1297
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
666 1298

  
667 1299
  // activate S
668
  apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
1300
  apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_ON);
669 1301

  
670 1302
  // proceed in the shutdown phase
671 1303
  aos.sssp.stage = AOS_SSSP_STAGE_SHUTDOWN_1_2;
......
690 1322
      aosThdUSleep(AOS_SSSP_DELAY);
691 1323

  
692 1324
      // activate S for one AOS_SSSP_DELAY.
693
      apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
1325
      apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_ON);
694 1326
      aosThdUSleep(AOS_SSSP_DELAY);
695
      apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_OFF);
1327
      apalControlGpioSet(moduleSsspSignalS(), APAL_GPIO_OFF);
696 1328
    }
697 1329
  }
698 1330

  
......
728 1360

  
729 1361
  // arm the timer once
730 1362
  if (!chVTIsArmed(&_delayTimer)) {
731
    chEvtRegisterMask(&_eventSourceDelay, &_eventListenerDelay, timermask);
732
    chVTSet(&_delayTimer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &_eventSourceDelay);
1363
    chEvtRegisterMask(&_delayEventSource, &_delayEventListener, timermask);
1364
    chVtSet(&_delayTimer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &_delayEventSource);
733 1365
  }
734 1366

  
735 1367
  // wait for any event to occur (do not apply any filters in order not to miss any events)
......
739 1371
  if (mask & gpiolistener->events) {
740 1372
    // retreive flags without clearing them
741 1373
    flags = gpiolistener->flags;
742
    apalControlGpioGet(&moduleSsspGpioS, &sstate);
1374
    apalControlGpioGet(moduleSsspSignalS(), &sstate);
743 1375
    if (flags == sflags) {
744
      apalControlGpioGet(&moduleSsspGpioS, &sstate);
1376
      apalControlGpioGet(moduleSsspSignalS(), &sstate);
745 1377
      // if this was the end of a pulse
746 1378
      if (sstate == APAL_GPIO_OFF) {
747 1379
        // restart the timer
748
        chVTReset(&_delayTimer);
749
        chVTSet(&_delayTimer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &_eventSourceDelay);
1380
        chVtSet(&_delayTimer, chTimeUS2I(AOS_SSSP_TIMEOUT), _timerCallback, &_delayEventSource);
750 1381
        // increment the identifier
751 1382
        ++(*identifier);
752 1383
      }
753 1384
    }
754 1385
  }
755 1386
  // timer event
756
  else if (mask & _eventListenerDelay.events) {
1387
  else if (mask & _delayEventListener.events) {
757 1388
    // unregister event
758
    chEvtUnregister(&_eventSourceDelay, &_eventListenerDelay);
1389
    chEvtUnregister(&_delayEventSource, &_delayEventListener);
759 1390
  }
760 1391
  // any further events must be handled externally
761 1392

  
......
764 1395

  
765 1396
#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
766 1397

  
767
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
768

  
769
/**
770
 * @brief   Retreive the offset between local clock and system synchronization signal.
771
 *
772
 * @return
773
 */
774
float aosSsspGetSyncSkew(void)
775
{
776
  return _syncskew;
777
}
778

  
779
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
780

  
781 1398
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
782 1399

  
783 1400
/** @} */

Also available in: Unified diff