Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_sssp.c @ 8ba3c06b

History | View | Annotate | Download (47.633 KB)

1 cda14729 Thomas Schöpping
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3 96621a83 Thomas Schöpping
Copyright (C) 2016..2020  Thomas Schöpping et al.
4 cda14729 Thomas Schöpping

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
/**
20
 * @file    aos_sssp.c
21
 * @brief   SSSP related code.
22
 *
23
 * @addtogroup aos_sssp
24
 * @{
25
 */
26
27
#include <amiroos.h>
28
29
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
30
31
/******************************************************************************/
32
/* LOCAL DEFINITIONS                                                          */
33
/******************************************************************************/
34
35 c218345a Thomas Schöpping
#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
44 cda14729 Thomas Schöpping
/******************************************************************************/
45
/* EXPORTED VARIABLES                                                         */
46
/******************************************************************************/
47
48
/******************************************************************************/
49
/* LOCAL TYPES                                                                */
50
/******************************************************************************/
51
52
/******************************************************************************/
53
/* LOCAL VARIABLES                                                            */
54
/******************************************************************************/
55
56
/**
57 c218345a Thomas Schöpping
 * @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
/**
85 cda14729 Thomas Schöpping
 * @brief   A timer event based delays.
86 c53ef0b1 Thomas Schöpping
 * @details This timer must not be an AMiRo-OS timer, since delays occurr before system is initialized.
87 cda14729 Thomas Schöpping
 */
88
static virtual_timer_t _delayTimer;
89
90
/**
91
 * @brief   Event source for the delay timer.
92
 */
93 c53ef0b1 Thomas Schöpping
static event_source_t _delayEventSource;
94 cda14729 Thomas Schöpping
95
/**
96
 * @brief   Event listener for the delay event.
97
 */
98 c53ef0b1 Thomas Schöpping
static event_listener_t _delayEventListener;
99 cda14729 Thomas Schöpping
100
/******************************************************************************/
101
/* LOCAL FUNCTIONS                                                            */
102
/******************************************************************************/
103
104 c218345a Thomas Schöpping
#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__)
105
106
/**
107 c53ef0b1 Thomas Schöpping
 * @brief   Callback function for the S signal interrupt.
108 c218345a Thomas Schöpping
 *
109
 * @param[in] args   Pointer to the GPIO line identifier.
110
 */
111
static void _gpioCallbackSSignal(void *args)
112
{
113
  aosDbgCheck((args != NULL) && (*((ioline_t*)args) != PAL_NOLINE) && (PAL_PAD(*((ioline_t*)args)) < sizeof(eventflags_t) * 8));
114
115
  apalControlGpioState_t s;
116
  aos_timestamp_t t;
117
118
  chSysLockFromISR();
119
120
  // if the system is in operation phase
121
  if (aos.sssp.stage == AOS_SSSP_STAGE_OPERATION) {
122
    // read signal S
123 c53ef0b1 Thomas Schöpping
    apalControlGpioGet(moduleSsspSignalS(), &s);
124 c218345a Thomas Schöpping
    // if S was toggled from on to off
125
    if (s == APAL_GPIO_OFF) {
126
      // get current uptime
127
      aosSysGetUptimeX(&t);
128
      // align the uptime with the synchronization period
129
      t %= AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
130
      if (t < AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2) {
131
        *_uptime -= t;
132
#if (AMIROOS_CFG_PROFILE == true)
133
        _syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) + (SYNCSKEW_SMOOTHFACTOR * t);
134
#endif /* (AMIROOS_CFG_PROFILE == true) */
135
      } else {
136
        t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - t;
137
        *_uptime += t;
138
#if (AMIROOS_CFG_PROFILE == true)
139
        _syncskew = ((1.0f - SYNCSKEW_SMOOTHFACTOR) * _syncskew) - (SYNCSKEW_SMOOTHFACTOR * t);
140
#endif /* (AMIROOS_CFG_PROFILE == true) */
141
      }
142
    }
143
  }
144
145
  // broadcast event
146
  chEvtBroadcastFlagsI(&aos.events.gpio, AOS_GPIOEVENT_FLAG(PAL_PAD(*((ioline_t*)args))));
147
  chSysUnlockFromISR();
148
149
  return;
150
}
151
152
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */
153
154
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined (__DOXYGEN__)
155
156
/**
157
 * @brief   Periodic system synchronization callback function.
158 c53ef0b1 Thomas Schöpping
 * @details Toggles the S signal and reconfigures the system synchronization timer.
159 c218345a Thomas Schöpping
 *
160
 * @param[in] par   Unused parameters.
161
 */
162
static void _syncTimerCallback(void* par)
163
{
164
  (void)par;
165
166 c53ef0b1 Thomas Schöpping
  // local variables
167 c218345a Thomas Schöpping
  apalControlGpioState_t state;
168
  aos_timestamp_t uptime;
169
170
  chSysLockFromISR();
171
  // toggle and read signal S
172 c53ef0b1 Thomas Schöpping
  apalGpioToggle(moduleSsspSignalS()->gpio);
173
  apalControlGpioGet(moduleSsspSignalS(), &state);
174 c218345a Thomas Schöpping
  // if S was toggled from off to on
175
  if (state == APAL_GPIO_ON) {
176
    // reconfigure the timer precisely, because the logically falling edge (next interrupt) snychronizes the system time
177
    _synctime += AMIROOS_CFG_SSSP_SYSSYNCPERIOD;
178
    aosSysGetUptimeX(&uptime);
179 c53ef0b1 Thomas Schöpping
    chVTSetI(&_synctimer, chTimeUS2I((time_usecs_t)(_synctime - uptime)), _syncTimerCallback, NULL);
180 c218345a Thomas Schöpping
  }
181
  // if S was toggled from on to off
182
  else /* if (state == APAL_GPIO_OFF) */ {
183
    // reconfigure the timer (lazy)
184
    chVTSetI(&_synctimer, chTimeUS2I(AMIROOS_CFG_SSSP_SYSSYNCPERIOD / 2), _syncTimerCallback, NULL);
185
  }
186
  chSysUnlockFromISR();
187
188
  return;
189
}
190
191
/**
192
 * @brief   Start the timer that toggles S for synchronization of the system.
193
 * @note    Must be called from a locked context.
194
 */
195
static inline void _syncTimerStartS(void)
196
{
197
  chDbgCheckClassS();
198
199
  // start synchronization timer
200
  // The first iteration of the timer is set to the next 'center' of a 'slice'.
201
  aos_timestamp_t t;
202
  aosSysGetUptimeX(&t);
203
  t = AMIROOS_CFG_SSSP_SYSSYNCPERIOD - (t % AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
204 c53ef0b1 Thomas Schöpping
  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);
205 c218345a Thomas Schöpping
206
  return;
207
}
208
209
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
210
211 cda14729 Thomas Schöpping
/**
212
 * @brief   General callback function to be used for any local timers.
213
 *
214
 * @param[in] par   A pointer to an @p event_source_t to be fired.
215
 */
216
static void _timerCallback(void* par)
217
{
218
  aosDbgCheck(par != NULL);
219
220
  chSysLockFromISR();
221
  chEvtBroadcastI((event_source_t*)par);
222
  chSysUnlockFromISR();
223
224
  return;
225
}
226
227
/**
228
 * @brief   Waits for the S signal to switch to the desired state.
229
 *
230
 * @param[in]   listener      Pointer to the GPIO event listener to be used.
231
 * @param[in]   signalstate   Desired state of the S signal ti be waited for.
232
 * @param[out]  received      Output variable to store the received event mask to.
233
 *
234
 * @return  Status, indicating whether the expected event was received.
235
 */
236 c5