Revision c53ef0b1
| 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); |
|
Also available in: Unified diff