From eeac77f9cec2c8b4cb8bb4431065935e6e61db93 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 26 Jun 2012 14:36:32 +1000 Subject: [PATCH] Refactor the timer clearing; force timer clear on set; improve the tracing of timer operations. r3616 | dcl | 2012-06-26 14:36:32 +1000 (Tue, 26 Jun 2012) | 1 line --- site_ansto/motor_dmc2280.c | 96 +++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 28 deletions(-) diff --git a/site_ansto/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index 1cb96063..1e49396c 100644 --- a/site_ansto/motor_dmc2280.c +++ b/site_ansto/motor_dmc2280.c @@ -35,7 +35,7 @@ #define UNITSLEN 256 #define TEXTPARLEN 1024 #define CMDLEN 1024 -#define STATE_TRACE (100) +#define STATE_TRACE (200) /** \brief Used to ensure that the getDMCSetting function is called * with valid values. @@ -51,7 +51,9 @@ enum eventtype { eTimerEvent, eMessageEvent, eCommandEvent, - eTimeoutEvent + eTimeoutEvent, + eTimerSet, /* pseudo-event for state trace only */ + eTimerClear /* pseudo-event for state trace only */ }; typedef struct EvtEvent_s EvtEvent, *pEvtEvent; @@ -73,6 +75,14 @@ typedef struct EvtCommand_s { typedef struct EvtTimeout_s { } EvtTimeout; +typedef struct TimerClear_s { /* pseudo-event for state trace only */ + int timerValue; +} TimerClear; + +typedef struct TimerSet_s { /* pseudo-event for state trace only */ + int timerValue; +} TimerSet; + struct EvtEvent_s { enum eventtype event_type; union { @@ -81,6 +91,8 @@ struct EvtEvent_s { EvtMessage msg; EvtCommand cmd; EvtTimeout tmo; + TimerSet tms; + TimerClear tmc; } event; }; @@ -283,6 +295,9 @@ static int state_msg_callback(pAsyncTxn pCmd); static int state_tmr_callback(void* ctx, int mode); static int state_cmd_execute(pDMC2280Driv self, enum commandtype cmd); +static void report_event(pDMC2280Driv self, pEvtEvent event); +static void state_trace_prn(pDMC2280Driv self); +static char* state_name(StateFunc func); static int DMC2280Halt(void *pData); static int DMC2280SetPar(void *pData, SConnection *pCon, char *name, float newValue); @@ -845,7 +860,42 @@ static int DMC_SendReceive(pDMC2280Driv self, char *cmd, char* reply) { return OKOK; } +/* + * Clear the timer if it is set + */ +static void DMC_ClearTimer(pDMC2280Driv self) { + /* only if the timer is really set */ + if (self->state_timer) { + /* log this event in the trace buffer */ + EvtEvent event; + event.event_type = eTimerClear; + event.event.tmc.timerValue = self->timerValue; + report_event(self, &event); + NetWatchRemoveTimer(self->state_timer); + self->state_timer = 0; + } +} + static void DMC_SetTimer(pDMC2280Driv self, int msecs) { + EvtEvent event; + + /* if the timer is already set, log the logic error and clear it */ + if (self->state_timer != 0) { + char line[133]; + snprintf(line, 132, "Motor %s, state %s(%d): setting new timer (%d mSec) when old (%d mSec) active, clearing", + self->name, + state_name(self->myState), + self->subState, + msecs, + self->timerValue); + SICSLogWrite(line, eError); + DMC_ClearTimer(self); + state_trace_prn(self); + } + /* log this event in the trace buffer */ + event.event_type = eTimerSet; + event.event.tms.timerValue = msecs; + report_event(self, &event); self->timerValue = msecs; NetWatchRegisterTimer(&self->state_timer, msecs, state_tmr_callback, self); } @@ -1467,6 +1517,12 @@ static char* event_name(pEvtEvent event, char* text, int length) { case eTimerEvent: snprintf(text, length, "eTimerEvent (%d mSec)", event->event.tmr.timerValue); return text; + case eTimerSet: + snprintf(text, length, "eTimerSet (%d mSec)", event->event.tms.timerValue); + return text; + case eTimerClear: + snprintf(text, length, "eTimerClear (%d mSec)", event->event.tmc.timerValue); + return text; case eMessageEvent: snprintf(text, length, "eMessageEvent:"); str_n_cat(text, length, event->event.msg.cmd->out_buf); @@ -1741,9 +1797,7 @@ static void DMCState_Unknown(pDMC2280Driv self, pEvtEvent event) { static void DMCState_Idle(pDMC2280Driv self, pEvtEvent event) { switch (event->event_type) { case eStateEvent: - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); if (self->driver_status == HWBusy) self->driver_status = HWIdle; if (self->variables & VAR_RUN) { @@ -1828,10 +1882,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) { switch (event->event_type) { case eStateEvent: self->run_flag = 0; - if (self->state_timer) { - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; - } + DMC_ClearTimer(self); /* If Motion Control is off, report HWFault */ if (DMC2280MotionControl != 1) { state_cmd_execute(self, CMD_HALT); @@ -2433,9 +2484,7 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) { static void DMCState_MotorHalt(pDMC2280Driv self, pEvtEvent event) { switch (event->event_type) { case eStateEvent: - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); cmdHalt(self); /* Note fall through */ case eTimerEvent: @@ -2517,18 +2566,14 @@ static void DMCState_OffTimer(pDMC2280Driv self, pEvtEvent event) { switch (event->event.cmd.cmd_type) { case CMD_RUN: /* handle run command, convert to motor on timer expired */ - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); if (self->driver_status == HWIdle) self->driver_status = HWBusy; change_state(self, DMCState_MotorOn); return; case CMD_HALT: /* handle halt command, convert to motor off timer expired */ - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); change_state(self, DMCState_MotorStop); return; } @@ -2897,9 +2942,7 @@ static int DMC2280Fix(void *pData, int iCode,/*@unused@*/ float fValue){ return MOTREDO; case STATEERROR: /* recover state error */ - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); change_state(self, DMCState_Unknown); return MOTFAIL; default: @@ -2923,8 +2966,8 @@ static int DMC2280Halt(void *pData){ self = (pDMC2280Driv)pData; assert(self != NULL); - state_trace_prn(self); state_cmd_execute(self, CMD_HALT); + state_trace_prn(self); return 1; } @@ -3527,15 +3570,14 @@ static void DMC_Notify(void* context, int event) { snprintf(line, 132, "Disconnect on Motor '%s'", self->name); SICSLogWrite(line, eStatus); /* TODO: disconnect */ + change_state(self, DMCState_Error); break; case AQU_RECONNECT: snprintf(line, 132, "Reconnect on Motor '%s'", self->name); SICSLogWrite(line, eStatus); /* TODO: reconnect */ /* Reset the state machine */ - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); change_state(self, DMCState_Unknown); break; } @@ -4060,9 +4102,7 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData, } else if(strcasecmp("reset", argv[1]) == 0) { /* Reset the state machine */ - if (self->state_timer) - NetWatchRemoveTimer(self->state_timer); - self->state_timer = 0; + DMC_ClearTimer(self); self->driver_status = HWIdle; change_state(self, DMCState_Unknown); while (self->myState == DMCState_Unknown) {