Revision c218345a

View differences:

core/inc/aos_sssp.h
101 101
  AOS_SSSP_STAGE_STARTUP_3_2  = 0x1320, /**< Identifier of SSSP startup phase stage 3-2.  */
102 102
  AOS_SSSP_STAGE_STARTUP_3_3  = 0x1330, /**< Identifier of SSSP startup phase stage 3-3.  */
103 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 pahse.          */
104
  AOS_SSSP_STAGE_OPERATION    = 0x2000, /**< Identifier of SSSP operation phase.          */
105 105
  AOS_SSSP_STAGE_SHUTDOWN     = 0x3000, /**< Identifier of SSSP shutdown phase.           */
106 106
  AOS_SSSP_STAGE_SHUTDOWN_1   = 0x3100, /**< Identifier of SSSP shutdown phase stage 1.   */
107 107
  AOS_SSSP_STAGE_SHUTDOWN_1_1 = 0x3110, /**< Identifier of SSSP shutdown phase stage 1-1. */
......
159 159
#if defined(__cplusplus)
160 160
extern "C" {
161 161
#endif /* defined(__cplusplus) */
162
  void aosSsspInit(void);
162
  void aosSsspInit(aos_timestamp_t* system_uptime);
163 163
  aos_status_t aosSsspProceed(event_listener_t* listener, eventflags_t flags, eventmask_t mask, eventmask_t* received);
164
  void aosSsspShutdownInit(void);
164
  void aosSsspShutdownInit(bool active);
165 165
#if (AMIROOS_CFG_SSSP_SHUTDOWN == true) || defined(__DOXYGEN__)
166 166
  void aosSsspShutdownBroadcastIdentifier(unsigned int identifier);
167 167
  eventmask_t aosSsspShutdownWaitForIdentifierPulse(event_listener_t* gpiolistener, eventflags_t sflags, eventmask_t timermask, unsigned int* identifier);
168 168
#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) */
169 172
#if defined(__cplusplus)
170 173
}
171 174
#endif /* defined(__cplusplus) */
core/inc/aos_system.h
171 171
#endif /* defined(__cplusplus) */
172 172
  void aosSysInit(const char* shellPrompt);
173 173
  void aosSysStart(void);
174
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined (__DOXYGEN__)
175
  void aosSysStartUptime(void);
176
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
174
  void aosSysStartUptimeS(void);
177 175
  void aosSysGetUptimeX(aos_timestamp_t* ut);
178 176
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
179 177
  void aosSysGetDateTime(struct tm* dt);
core/src/aos_main.cpp
274 274
#if (AMIROOS_CFG_SSSP_ENABLE == true)
275 275
  {
276 276
    eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | MODULE_SSSP_EVENTFLAG_PD | MODULE_SSSP_EVENTFLAG_S;
277
#if (AMIROOS_CFG_SSSP_MSI == true)
277 278
#if (AMIROOS_CFG_SSSP_STACK_START != true)
278 279
    flagsmask |= MODULE_SSSP_EVENTFLAG_DN;
279 280
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
280 281
#if (AMIROOS_CFG_SSSP_STACK_END != true)
281 282
    flagsmask |= MODULE_SSSP_EVENTFLAG_UP;
282 283
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
284
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
283 285
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, flagsmask);
284 286
  }
285 287
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
......
600 602
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
601 603
  }
602 604

  
603
  // start the internal system uptime counter
604
  aosSysStartUptime();
605

  
606 605
  /*
607
   * There must be no delays at this point, thus no hook allowed.
606
   * There must be no delay at this point, thus no hook allowed.
608 607
   */
609 608

  
610 609
#if (AMIROOS_CFG_SSSP_MSI == true)
611 610

  
612
  //TODO
611
  //TODO: MSI
613 612

  
613
#if (HAL_USE_RTC == TRUE)
614

  
615
  //TODO: Calendar synchronization
616

  
617
#endif /* (HAL_USE_RTC == TRUE) */
614 618
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
615 619

  
616 620
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
......
634 638
   * ##########################################################################
635 639
   */
636 640

  
641
#if (AMIROOS_CFG_SSSP_ENABLE == true)
642
  /* ignore all SSSP signal events, except for PD and configured events */
643
  eventflags = MODULE_SSSP_EVENTFLAG_S;
644
#if (AMIROOS_CFG_SSSP_MSI == true)
645
#if (AMIROOS_CFG_SSSP_STACK_START != true)
646
  eventflags |= MODULE_SSSP_EVENTFLAG_DN;
647
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
648
#if (AMIROOS_CFG_SSSP_STACK_END != true)
649
  eventflags |= MODULE_SSSP_EVENTFLAG_UP;
650
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
651
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
652
  eventflags &= ~((eventflags_t)AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK);
653
  _eventListenerGPIO.wflags &= ~eventflags;
654
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
655

  
637 656
  // sleep until a shutdown event is received
638 657
  while (shutdown == AOS_SHUTDOWN_NONE) {
639 658
    // wait for an event
......
659 678
#if (AMIROOS_CFG_SSSP_ENABLE == true)
660 679
        // PD event
661 680
        if (eventflags & MODULE_SSSP_EVENTFLAG_PD) {
662
          aosSsspShutdownInit();
681
          aosSsspShutdownInit(false);
663 682
          shutdown = AOS_SHUTDOWN_PASSIVE;
664 683
        }
665 684
        // all other events
......
716 735
        break;
717 736
    }
718 737

  
738
#if (AMIROOS_CFG_SSSP_ENABLE == true)
739

  
740
    /*
741
     * Re-anable the S signal GPIO event.
742
     * Note that events for the optional signals UP and DN are not enabled as they are not utilized during SSSP shutdown phase.
743
     */
744
    chSysLock();
745
    _eventListenerGPIO.wflags |= MODULE_SSSP_EVENTFLAG_S;
746
    chSysUnlock();
747

  
748
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
749

  
719 750
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2)
720 751
#if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS)
721 752
    AMIROOS_CFG_MAIN_LOOP_HOOK_2(AMIROOS_CFG_MAIN_LOOP_HOOK_2_ARGS);
core/src/aos_sssp.c
32 32
/* LOCAL DEFINITIONS                                                          */
33 33
/******************************************************************************/
34 34

  
35
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
36

  
37
/**
38
 * @brief   Weighting factor for smoothing the @p _syncskew value.
39
 */
40
#define SYNCSKEW_SMOOTHFACTOR                   (0.1f / AOS_SYSTEM_TIME_RESOLUTION)
41

  
42
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
43

  
35 44
/******************************************************************************/
36 45
/* EXPORTED VARIABLES                                                         */
37 46
/******************************************************************************/
......
45 54
/******************************************************************************/
46 55

  
47 56
/**
57
 * @brief   Pointer to the system uptime.
58
 */
59
static aos_timestamp_t* _uptime;
60

  
61
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__)
62

  
63
/**
64
 * @brief   Timer to drive the S signal for system wide time synchronization during operation phase.
65
 */
66
static virtual_timer_t _synctimer;
67

  
68
/**
69
 * @brief   Last uptime of system wide time synchronization.
70
 */
71
static aos_timestamp_t _synctime;
72

  
73
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
74

  
75
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
76

  
77
/**
78
 * @brief   Offset between local clock and system wide synchronization signal.
79
 */
80
static float _syncskew;
81

  
82
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
83

  
84
/**
48 85
 * @brief   A timer event based delays.
49 86
 */
50 87
static virtual_timer_t _delayTimer;
......
63 100
/* LOCAL FUNCTIONS                                                            */
64 101
/******************************************************************************/
65 102

  
103
#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__)
104

  
105
/**
106
 * @brief   Callback function for the Sync signal interrupt.
107
 *
108
 * @param[in] args   Pointer to the GPIO line identifier.
109
 */
110
static void _gpioCallbackSSignal(void *args)
111
{
112
  aosDbgCheck((args != NULL) && (*((ioline_t*)args) != PAL_NOLINE) && (PAL_PAD(*((ioline_t*)args)) < sizeof(eventflags_t) * 8));
113

  
114
  apalControlGpioState_t s;
115
  aos_timestamp_t t;
116

  
117
  chSysLockFromISR();
118

  
119
  // if the system is in operation phase
120
  if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) {
121
    // read signal S
122
    apalControlGpioGet(&moduleSsspGpioS, &s);
123
    // if S was toggled from on to off
124
    if (s == APAL_GPIO_OFF) {
125
      // get current uptime
126
      aosSysGetUptimeX(&t);
127
      // align the uptime with the synchronization period
128
      t %= AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
129
      if (t < AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2) {
130
        *_uptime -= t;
131
#if (AMIROOS_CFG_PROFILE == true)
132
        _syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) + (SYNCSKEW_SMOOTHFACTOR * t);
133
#endif /* (AMIROOS_CFG_PROFILE == true) */
134
      } else {
135
        t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - t;
136
        *_uptime += t;
137
#if (AMIROOS_CFG_PROFILE == true)
138
        _syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) - (SYNCSKEW_SMOOTHFACTOR * t);
139
#endif /* (AMIROOS_CFG_PROFILE == true) */
140
      }
141
    }
142
  }
143

  
144
  // broadcast event
145
  chEvtBroadcastFlagsI(&aos.events.gpio, AOS_GPIOEVENT_FLAG(PAL_PAD(*((ioline_t*)args))));
146
  chSysUnlockFromISR();
147

  
148
  return;
149
}
150

  
151
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */
152

  
153
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined (__DOXYGEN__)
154

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

  
165
  apalControlGpioState_t state;
166
  aos_timestamp_t uptime;
167

  
168
  chSysLockFromISR();
169
  // toggle and read signal S
170
  apalGpioToggle(moduleSsspGpioS.gpio);
171
  apalControlGpioGet(&moduleSsspGpioS, &state);
172
  // if S was toggled from off to on
173
  if (state == APAL_GPIO_ON) {
174
    // reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time
175
    _synctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
176
    aosSysGetUptimeX(&uptime);
177
    chVTSetI(&_synctimer, chTimeUS2I(_synctime - uptime), _syncTimerCallback, NULL);
178
  }
179
  // if S was toggled from on to off
180
  else /* if (state == APAL_GPIO_OFF) */ {
181
    // reconfigure the timer (lazy)
182
    chVTSetI(&_synctimer, chTimeUS2I(AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2), _syncTimerCallback, NULL);
183
  }
184
  chSysUnlockFromISR();
185

  
186
  return;
187
}
188

  
189
/**
190
 * @brief   Start the timer that toggles S for synchronization of the system.
191
 * @note    Must be called from a locked context.
192
 */
193
static inline void _syncTimerStartS(void)
194
{
195
  chDbgCheckClassS();
196

  
197
  // start synchronization timer
198
  // The first iteration of the timer is set to the next 'center' of a 'slice'.
199
  aos_timestamp_t t;
200
  aosSysGetUptimeX(&t);
201
  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);
203

  
204
  return;
205
}
206

  
207
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
208

  
66 209
/**
67 210
 * @brief   General callback function to be used for any local timers.
68 211
 *
......
153 296
/**
154 297
 * @brief   Initialize all SSSP related data.
155 298
 */
156
void aosSsspInit(void)
299
void aosSsspInit(aos_timestamp_t* system_uptime)
157 300
{
301
  aosDbgCheck(system_uptime != NULL);
302

  
158 303
  // local variables
159 304
  apalControlGpioState_t state;
160 305

  
......
171 316
  aosDbgAssert(state == APAL_GPIO_ON);
172 317
  apalControlGpioGet(&moduleSsspGpioPD, &state);
173 318
  aosDbgAssert(state == APAL_GPIO_OFF);
319
#if (AMIROOS_CFG_SSSP_MSI == true)
174 320
#if (AMIROOS_CFG_SSSP_STACK_END != true)
175 321
  apalControlGpioGet(&moduleSsspGpioUP, &state);
176 322
  aosDbgAssert(state == APAL_GPIO_OFF);
......
179 325
  apalControlGpioGet(&moduleSsspGpioDN, &state);
180 326
  aosDbgAssert(state == APAL_GPIO_OFF);
181 327
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
328
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
182 329

  
183 330
#if (AMIROOS_CFG_SSSP_MSI == true)
184 331
  // module ID is initialized as 'invalid'
......
186 333
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
187 334

  
188 335
  // initialize static variables
336
  _uptime = system_uptime;
337
#if (AMIROOS_CFG_SSSP_MASTER == true)
338
  chVTObjectInit(&_synctimer);
339
  _synctime = 0;
340
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
341
#if (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
342
  _syncskew = 0.0f;
343
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
189 344
  chVTObjectInit(&_delayTimer);
190 345
  chEvtObjectInit(&_eventSourceDelay);
191 346

  
347
  // signal interrupt setup
348
  palSetLineCallback(moduleSsspGpioPD.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioPD.gpio->line);
349
  palEnableLineEvent(moduleSsspGpioPD.gpio->line, APAL2CH_EDGE(moduleSsspGpioPD.meta.edge));
350
#if (AMIROOS_CFG_SSSP_MASTER == true)
351
  palSetLineCallback(moduleSsspGpioS.gpio->line, aosSysGetStdGpioCallback(), &moduleSsspGpioS.gpio->line);
352
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
353
  palSetLineCallback(moduleSsspGpioS.gpio->line, _gpioCallbackSSignal, &moduleSsspGpioS.gpio->line);
354
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
355
  palEnableLineEvent(moduleSsspGpioS.gpio->line, APAL2CH_EDGE(moduleSsspGpioS.meta.edge));
356
#if (AMIROOS_CFG_SSSP_MSI == true)
357
#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));
360
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
361
#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));
364
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
365
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
366

  
192 367
  return;
193 368
}
194 369

  
195 370
/**
196 371
 * @brief   Proceed to the next SSSP stage.
372
 * @note    Calling this function when in operation phase is invalid.
373
 *          The function aosSsspShutdownInit() must be used instead.
197 374
 *
198 375
 * @param[in]   listener  An optional listener, in case the system has to wait for a specific event.
199 376
 * @param[in]   flags     The relevant flags to wait for (mandatory if a listener is given).
......
331 508

  
332 509
    /*
333 510
     * Wait for the S signal to become inactive.
511
     * When proceeding to operation phase, the master starts toggling S for synchronization
334 512
     */
335 513
    case AOS_SSSP_STAGE_STARTUP_2_2:
336 514
    {
......
344 522
#if (AMIROOS_CFG_SSSP_MSI == true)
345 523
        nextstage = AOS_SSSP_STAGE_STARTUP_3;
346 524
#else /* (AMIROOS_CFG_SSSP_MSI == true) */
525
        chSysLock();
526
        // start the internal uptime aggregation
527
        aosSysStartUptimeS();
528
#if (AMIROOS_CFG_SSSP_MASTER == true)
529
        // start toggling S for system synchronization
530
        _syncTimerStartS();
531
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
532
        chSysUnlock();
347 533
        nextstage = AOS_SSSP_STAGE_OPERATION;
348 534
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
349 535
      }
......
357 543
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
358 544

  
359 545
    /*
546
     * Invalid operation.
547
     * Shutdon must be initiatid via the aosSsspShutdownInit() function.
548
     */
549
    case AOS_SSSP_STAGE_OPERATION:
550
    {
551
      aosDbgAssertMsg(false, "in order to exit operation phase, aosSsspShutdownInit() function must be used");
552
      break;
553
    }
554

  
555
    /*
360 556
     * Delay execution by one perion AOS_SSSP_DELAY, deactivate the SYNC signal and proceed.
361 557
     * NOTE: Actually only the module that initiated the shutdown has to delay execution here.
362 558
     *       For the sake of simlicity though, each module delays execution.
......
446 642
  return status;
447 643
}
448 644

  
449
void aosSsspShutdownInit(void)
645
/**
646
 * @brief   Leave the operation pahse and initiate or acknowledge shutdown.
647
 *
648
 * @param[in] active  Flag, indicating whether the shutdon shall be activeliy initiated (true) or a passive request was received (false).
649
 */
650
void aosSsspShutdownInit(bool active)
450 651
{
451
  // activate S signal
452
  apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
652
  aosDbgAssert(aos.sssp.stage == AOS_SSSP_STAGE_OPERATION);
653

  
453 654
  // proceed to shutdown phase
655
  aos.sssp.stage = AOS_SSSP_STAGE_SHUTDOWN_1_1;
656

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

  
662
#if (AMIROOS_CFG_SSSP_MASTER == true)
663
  // stop toggling S
664
  chVTReset(&_synctimer);
665
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
666

  
667
  // activate S
668
  apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
669

  
670
  // proceed in the shutdown phase
454 671
  aos.sssp.stage = AOS_SSSP_STAGE_SHUTDOWN_1_2;
455 672

  
456 673
  return;
......
547 764

  
548 765
#endif /* (AMIROOS_CFG_SSSP_SHUTDOWN == true) */
549 766

  
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

  
550 781
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
551 782

  
552 783
/** @} */
core/src/aos_system.c
55 55
 */
56 56
#define SYSTEM_INFO_NAMEWIDTH         14
57 57

  
58
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
59

  
60
/**
61
 * @brief   Weighting factor for the low-pass filter used for calculating the @p _syssyncskew value.
62
 */
63
#define SYSTEM_SYSSYNCSKEW_LPFACTOR   (0.1f / AOS_SYSTEM_TIME_RESOLUTION)
64

  
65
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
66

  
67 58
/******************************************************************************/
68 59
/* EXPORTED VARIABLES                                                         */
69 60
/******************************************************************************/
......
108 99
 */
109 100
static systime_t _synctime;
110 101

  
111
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
112
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__)
113

  
114
/**
115
 * @brief   Timer to drive the SYS_SYNC signal for system wide time synchronization according to SSSP.
116
 */
117
static virtual_timer_t _syssynctimer;
118

  
119
/**
120
 * @brief   Last uptime of system wide time synchronization.
121
 */
122
static aos_timestamp_t _syssynctime;
123

  
124
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
125

  
126
#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
127

  
128
/**
129
 * @brief   Offset between local clock and system wide synchronization signal.
130
 */
131
static float _syssyncskew;
132

  
133
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
134
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
135

  
136 102
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
137 103

  
138 104
/**
......
536 502
  chprintf(stream, "%10u milliseconds\n", (uint16_t)(uptime % MICROSECONDS_PER_SECOND / MICROSECONDS_PER_MILLISECOND));
537 503
  chprintf(stream, "%10u microseconds\n", (uint16_t)(uptime % MICROSECONDS_PER_MILLISECOND / MICROSECONDS_PER_MICROSECOND));
538 504
#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
539
  chprintf(stream, "SSSP synchronization offset: %.3fus per %uus\n", (double)_syssyncskew, AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
505
  chprintf(stream, "SSSP synchronization offset: %.3fus per %uus\n", (double)aosSsspGetSyncSkew(), AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
540 506
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
541 507
  _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
542 508

  
......
694 660
}
695 661
#pragma GCC diagnostic pop
696 662

  
697
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true)) || defined(__DOXYGEN__)
698

  
699
/**
700
 * @brief   Callback function for the Sync signal interrupt.
701
 *
702
 * @param[in] args   Pointer to the GPIO line identifier.
703
 */
704
static void _signalSyncCallback(void *args)
705
{
706
  aosDbgCheck((args != NULL) && (*((ioline_t*)args) != PAL_NOLINE) && (PAL_PAD(*((ioline_t*)args)) < sizeof(eventflags_t) * 8));
707

  
708
  apalControlGpioState_t state;
709
  aos_timestamp_t uptime;
710

  
711
  chSysLockFromISR();
712

  
713
  // if the system is in operation phase
714
  if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) {
715
    // read signal S
716
    apalControlGpioGet(&moduleSsspGpioS, &state);
717
    // if S was toggled from on to off
718
    if (state == APAL_GPIO_OFF) {
719
      // get current uptime
720
      aosSysGetUptimeX(&uptime);
721
      // align the uptime with the synchronization period
722
      if (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD < AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2) {
723
        _uptime -= uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
724
#if (AMIROOS_CFG_PROFILE == true)
725
        _syssyncskew = ((1.0f - SYSTEM_SYSSYNCSKEW_LPFACTOR) * _syssyncskew) + (SYSTEM_SYSSYNCSKEW_LPFACTOR * (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD));
726
#endif /* (AMIROOS_CFG_PROFILE == true) */
727
      } else {
728
        _uptime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
729
#if (AMIROOS_CFG_PROFILE == true)
730
        _syssyncskew = ((1.0f - SYSTEM_SYSSYNCSKEW_LPFACTOR) * _syssyncskew) - (SYSTEM_SYSSYNCSKEW_LPFACTOR * (AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (uptime % AMIROOS_CFG_SSSP_SYSSYNCPERIOD)));
731
#endif /* (AMIROOS_CFG_PROFILE == true) */
732
      }
733
    }
734
  }
735

  
736
  // broadcast event
737
  chEvtBroadcastFlagsI(&aos.events.gpio, AOS_GPIOEVENT_FLAG(PAL_PAD(*((ioline_t*)args))));
738
  chSysUnlockFromISR();
739

  
740
  return;
741
}
742

  
743
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) */
744

  
745 663
/**
746 664
 * @brief   Callback function for the uptime accumulation timer.
747 665
 *
......
764 682
  return;
765 683
}
766 684

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

  
769
/**
770
 * @brief   Periodic system synchronization callback function.
771
 * @details Toggles the SYS_SYNC signal and reconfigures the system synchronization timer.
772
 *
773
 * @param[in] par   Unused parameters.
774
 */
775
static void _sysSyncTimerCallback(void* par)
776
{
777
  (void)par;
778

  
779
  apalControlGpioState_t state;
780
  aos_timestamp_t uptime;
781

  
782
  chSysLockFromISR();
783
  // toggle and read signal S
784
  apalGpioToggle(moduleSsspGpioS.gpio);
785
  apalControlGpioGet(&moduleSsspGpioS, &state);
786
  // if S was toggled from off to on
787
  if (state == APAL_GPIO_ON) {
788
    // reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time
789
    _syssynctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
790
    aosSysGetUptimeX(&uptime);
791
    chVTSetI(&_syssynctimer, chTimeUS2I(_syssynctime - uptime), _sysSyncTimerCallback, NULL);
792
  }
793
  // if S was toggled from on to off
794
  else /* if (state == APAL_GPIO_OFF) */ {
795
    // reconfigure the timer (lazy)
796
    chVTSetI(&_syssynctimer, chTimeUS2I(AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2), _sysSyncTimerCallback, NULL);
797
  }
798
  chSysUnlockFromISR();
799

  
800
  return;
801
}
802

  
803
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true) */
804

  
805 685
/**
806 686
 * @brief   Retreive the number of active threads.
807 687
 *
......
835 715
  chThdSetPriority(AOS_THD_CTRLPRIO);
836 716

  
837 717
#if (AMIROOS_CFG_SSSP_ENABLE == true)
838
  aosSsspInit();
718
  aosSsspInit(&_uptime);
839 719
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
840 720

  
841 721
  /* set local variables */
842 722
  chVTObjectInit(&_systimer);
843 723
#if (AMIROOS_CFG_SSSP_ENABLE == true)
724
  // uptime counter is started when SSSP proceeds to operation phase
844 725
  _synctime = 0;
845 726
  _uptime = 0;
846
#if (AMIROOS_CFG_SSSP_MASTER == true)
847
  chVTObjectInit(&_syssynctimer);
848
  _syssynctime = 0;
849
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
850
#if (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
851
  _syssyncskew = 0.0f;
852
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
853 727
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
854 728
  // start the uptime counter
855 729
  chSysLock();
856
  _synctime = chVTGetSystemTimeX();
857
  _uptime = 0;
858
  chVTSetI(&_systimer, SYSTIMER_PERIOD, &_uptimeCallback, NULL);
730
  aosSysStartUptimeS();
859 731
  chSysUnlock();
860 732
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
861 733

  
......
864 736
  chEvtObjectInit(&aos.events.gpio);
865 737
  chEvtObjectInit(&aos.events.os);
866 738

  
867
#if (AMIROOS_CFG_SSSP_ENABLE == true)
868

  
869
  /* SSSP signal interrupt setup */
870
  // PD signal
871
  palSetLineCallback(moduleSsspGpioPD.gpio->line, _gpioCallback, &moduleSsspGpioPD.gpio->line);
872
  palEnableLineEvent(moduleSsspGpioPD.gpio->line, APAL2CH_EDGE(moduleSsspGpioPD.meta.edge));
873
  // S signal
874
#if (AMIROOS_CFG_SSSP_MASTER == true)
875
  palSetLineCallback(moduleSsspGpioS.gpio->line, _gpioCallback, &moduleSsspGpioS.gpio->line);
876
#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
877
  palSetLineCallback(moduleSsspGpioS.gpio->line, _signalSyncCallback, &moduleSsspGpioS.gpio->line);
878
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
879
  palEnableLineEvent(moduleSsspGpioS.gpio->line, APAL2CH_EDGE(moduleSsspGpioS.meta.edge));
880
#if (AMIROOS_CFG_SSSP_STACK_START != true)
881
  // DN signal
882
  palSetLineCallback(moduleSsspGpioDN.gpio->line, _gpioCallback, &moduleSsspGpioDN.gpio->line);
883
  palEnableLineEvent(moduleSsspGpioDN.gpio->line, APAL2CH_EDGE(moduleSsspGpioDN.meta.edge));
884
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
885
#if (AMIROOS_CFG_SSSP_STACK_END != true)
886
  // UP signal
887
  palSetLineCallback(moduleSsspGpioUP.gpio->line, _gpioCallback, &moduleSsspGpioUP.gpio->line);
888
  palEnableLineEvent(moduleSsspGpioUP.gpio->line, APAL2CH_EDGE(moduleSsspGpioUP.meta.edge));
889
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
890

  
891
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
892

  
893 739
#if (AMIROOS_CFG_SHELL_ENABLE == true)
894 740

  
895 741
  /* init shell */
......
908 754
  aosShellAddCommand(&aos.shell, &_shellcmd_kerneltest);
909 755
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
910 756

  
757
#else /* (AMIROOS_CFG_SHELL_ENABLE == true) */
758

  
759
  // suppress unused variable warnings
760
  (void)shellPrompt;
761

  
911 762
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
912 763

  
913 764
  return;
......
918 769
 */
919 770
void aosSysStart(void)
920 771
{
921
#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true)
922
  {
923
    chSysLock();
924
    // start the system synchronization counter
925
    // The first iteration of the timer is set to the next 'center' of a 'slice'.
926
    aos_timestamp_t t;
927
    aosSysGetUptimeX(&t);
928
    t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (t % AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
929
    chVTSetI(&_syssynctimer, chTimeUS2I((t > (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) ? (t - (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2)) : (t + (AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2))), _sysSyncTimerCallback, NULL);
930
    chSysUnlock();
931
  }
932
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) && (AMIROOS_CFG_SSSP_ENABLE == true) */
933

  
934 772
  // print system information;
935 773
  _printSystemInfo((BaseSequentialStream*)&aos.iostream);
936 774
  aosprintf("\n");
......
947 785
  return;
948 786
}
949 787

  
950
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
951

  
952 788
/**
953 789
 * @brief   Start the system uptime measurement.
790
 * @note    Must be called from a locked context.
954 791
 */
955
void aosSysStartUptime(void)
792
void aosSysStartUptimeS(void)
956 793
{
957
  chSysLock();
794
  chDbgCheckClassS();
958 795

  
959
  // start the uptime counter
796
  // start the uptime aggregation counter
960 797
  _synctime = chVTGetSystemTimeX();
961 798
  _uptime = 0;
962 799
  chVTSetI(&_systimer, SYSTIMER_PERIOD, &_uptimeCallback, NULL);
963 800

  
964
  chSysUnlock();
965

  
966 801
  return;
967 802
}
968 803

  
969
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
970

  
971 804
/**
972 805
 * @brief   Retrieves the system uptime.
973 806
 *
......
1031 864

  
1032 865
#if (AMIROOS_CFG_SSSP_ENABLE == true)
1033 866

  
1034
#if (AMIROOS_CFG_SSSP_MASTER == true)
1035
  // deactivate the system synchronization timer
1036
  chVTReset(&_syssynctimer);
1037
  // activate SSSP S signal in case the synchronization timer had it deactivated.
1038
  apalControlGpioSet(&moduleSsspGpioS, APAL_GPIO_ON);
1039
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
1040

  
1041 867
  // activate the PD signal only if this module initiated the shutdown
1042 868
  if (shutdown != AOS_SHUTDOWN_PASSIVE) {
1043
    apalControlGpioSet(&moduleSsspGpioPD, APAL_GPIO_ON);
1044
    aosSsspShutdownInit();
869
    aosSsspShutdownInit(true);
1045 870
  }
1046 871

  
1047 872
  switch (shutdown) {

Also available in: Unified diff