26 static bool _changeEmitHoldOff =
false;
27 static bool _stateChanged =
false;
29 #define SEQ_AUTO_DELAY 100
33 static int _seqTaskId;
54 #define SUBS(IDX, ID, NAME) #NAME,
62 "Undefined",
"Idle",
"StandBy",
"Ready",
"Paused",
"Running"
84 const char * errorMsg;
90 static ClbSubSys _subSystems[CLB_SUB_CNT];
94 assert(idx >= 0 && idx < CLB_SUB_CNT);
96 return _subSystems[idx].state;
101 assert(idx >= 0 && idx < CLB_SUB_CNT);
102 return _subSystems[idx].id;
108 assert(idx >= 0 && idx < CLB_SUB_CNT);
109 if (_subSystems[idx].errorCode ==
E_NONE)
return false;
111 *code = _subSystems[idx].errorCode;
112 *message = _subSystems[idx].errorMsg;
120 return _subSystems[idx].status;
126 static bool clbCheckGoto(
int idx,
ClbEvent event)
128 ClbState state = _subSystems[idx].state;
136 if (tansitionTable[event].source == state)
151 static bool clbEventInternal(
int idx,
ClbEvent event)
154 _changeEmitHoldOff =
true;
158 for (i = 0; i < CLB_SUB_CNT; ++i) clbEventInternal(i, event);
163 _subSystems[idx].errorCode =
E_NONE;
164 _subSystems[idx].errorMsg = NULL;
165 _subSystems[idx].status = 0;
168 assert(idx < CLB_SUB_CNT);
169 if (clbCheckGoto(idx, event))
172 _subSystems[idx].execEvent(event);
179 _subSystems[idx].status &= ~CLB_STATUS_PENDING;
186 _changeEmitHoldOff =
false;
189 if (_seqLen > 0)
return true;
194 _stateChanged =
false;
206 assert(idx >= 0 && idx < CLB_SUB_CNT);
207 ClbState state = tansitionTable[event].target;
210 assert (tansitionTable[event].source == _subSystems[idx].state);
212 _subSystems[idx].state = state;
213 _subSystems[idx].status = status;
216 if (_changeEmitHoldOff) _stateChanged =
true;
224 if((idx < 0 || idx >= CLB_SUB_CNT) && idx !=
CLB_SUB_ALL) {
231 if (_seqLen > 0)
return true;
232 if (lastEvent != event) {
237 return clbEventInternal(idx, event);
243 assert((idx >= 0 && idx < CLB_SUB_CNT));
252 _subSystems[idx].state &= ~CLB_STATUS_ERROR;
253 _subSystems[idx].errorCode = 0;
254 _subSystems[idx].errorMsg = NULL;
258 void _clbStateError(
int idx,
int errorCode,
const char * errorMsg,
const char * name)
261 if (_subSystems[idx].errorCode !=
E_NONE)
return;
264 if (errorCode ==
E_NONE)
return;
266 if (name == NULL) name =
"Unknown";
269 _subSystems[idx].status |= CLB_STATUS_ERROR;
272 _subSystems[idx].errorCode = errorCode;
273 _subSystems[idx].errorMsg = errorMsg;
287 uint32_t curTicks =
ticks();
288 for (i = CLB_SUB_CNT - 1; i >= 0; --i)
290 if (_subSystems[i].update) {
291 _subSystems[i].update(_subSystems[i].state, curTicks);
303 static void clbStateAuto()
319 if (_seq != NULL)
return;
330 for (i = 0; i < CLB_SUB_CNT; ++i)
335 for (i = 0; i < CLB_SUB_MAX; ++i) {
339 #define SUBS(IDX, ID, NAME) _subSystems[IDX].execEvent = (_subs ## NAME ## ExecEvent); \
340 _subSystems[IDX].update = (_subs ## NAME ## Update); \
341 _subSystems[IDX].id = ID; \
342 clbSys2Idx[ID] = IDX;
bool errHas()
Returns whether there is an error pending.
const char *const clbEventNames[9]
All state change event names.
ClbEvent
All state change events.
Application specific error codes.
White Rabbit simple timer 'Ticks' driver.
ClbState clbState(int idx)
Returns the current clbSubState for the specified subsystem.
bool schdRegister(SchdTaskF task, bool priority, int *taskId)
Register a task with the scheduler.
bool clbEvent(int idx, ClbEvent event)
Request a subsystem to go to a certain state.
const char * errGetDescr()
Returns the last error description, if any, else null.
Simple task scheduler for tasks.
void clbClearErrorState(int idx)
Clears the error state of the specific subsystem.
void clbAutoEventSeq(ClbEvent *events, int seqLen)
Executes an autonomous a sequence of events.
static uint32_t ticks()
Nr of ticks since device start up.
bool clbStateError(int idx, int *code, const char **message)
Retrieves the error of a subsystem (if any).
uint8_t clbSys2Idx[6]
Mapping from subsystem ID to index.
CLB Remote message processor.
void clbUpdateSubsys()
Invoked the update method on each subsystem.
#define logWarn(MSG,...)
Format a log message with warning level.
#define E_NONE
Zero is no error.
#define E_INVARGUMENT
Generic error: invalid argument.
const char *const clbSubsystemNames[5]
Contains a list of all the subsystems.
void schdRunDelay(int taskId, int interval)
Schedule a task to run after a delay.
int clbSubId(int idx)
Returns the subsystem ID code for the provided index.
Manages the global system error.
Undefined => Idle, for internal use only.
void errPrint(bool clear)
Prints the last error.
#define CLB_STATUS_PENDING
Indicates that the subsystem is in transit to a new state.
void clbStateInit()
Initializes the state machine.
const char *const clbStateNames[6]
Contains list of the state names.
void errClear()
Clears the current error.
#define CLB_SUB_ALL
Indicates all subsystems. Can be used in clbStateGoto.
uint32_t errGet()
Returns the last error code, or null.
#define logError(MSG,...)
Format a log message with fatal level.
#define LOG_DEF(NAME,...)
Define a logger for a module.
The CLB stare module tracks is responsible for state management of the various sub-systems on the CLB...
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
bool evtClbEmitStateChange()
Indicates the CLB to emit a state change event to the slow control.
Implements a generic logger facility.
void _clbStateError(int idx, int error, const char *message, const char *name)
Invoked by subsystem to indicate an error happened.
#define logInfo(MSG,...)
Write a log message with formatting on info level.
void _clbStateUpdate(int idx, ClbEvent event, uint8_t status)
Invoked by the subsystem to indicate a state change has happened.
Undefined state (prior to module init, should never be seen on shore)
uint8_t clbStatus(int idx)
Returns the current subsystem status.