Align nhq200.c and orhvps.c to be more alike (and more diffable)

r2629 | dcl | 2008-06-12 17:23:40 +1000 (Thu, 12 Jun 2008) | 2 lines
This commit is contained in:
Douglas Clowes
2008-06-12 17:23:40 +10:00
parent 1795e07504
commit e59b073066
2 changed files with 394 additions and 201 deletions

View File

@@ -8,7 +8,7 @@
Douglas Clowes, May 2008
copyright: site_ansto/doc/Copyright.txt
Copyright: site_ansto/doc/Copyright.txt
----------------------------------------------------------------------------
*/
@@ -28,30 +28,36 @@
#include <netinet/tcp.h>
#define CMDLEN 132
#define MY_ABSOLUTE_MAXIMUM (6000.0)
#define MY_MINIMUM_RATE (1.0)
#define MY_MAXIMUM_RATE (255.0)
#define NHQ_FAST_POLL (500.0)
#define NHQ_SLOW_POLL (2000.0)
#define NHQ_FAST_POLL (500)
#define NHQ_SLOW_POLL (2000)
/* ERROR CODES */
#define NHQ200_ERR_NONE (0)
#define NHQ200_ERR_LOCKED (-1)
#define NHQ200_ERR_RANGE (-2)
typedef struct nhq200_s {
/* Device Driver Control Structure */
struct nhq200_s {
pEVControl controller;
int iControl; /* integer controller (1..2) */
int iErrorCode; /* error code */
int iErrorCount; /* error count */
float fTarget; /* target voltage in volts */
int iErrorCode; /* error code */
float fTarget; /* requested target voltage in volts */
float fValue; /* current voltage in volts */
float fMax; /* maximum voltage in volts */
float fRate; /* voltage slew rate in volts per second */
float fUpper; /* Normal Operating Voltage */
float fLower; /* Normal Moving Voltage */
bool isLocked; /* changes no longer permitted */
bool isLocked; /* changes no longer permitted */
bool bRunFlag; /* set by the run command */
bool bInternal; /* Flags an internal run request */
char* name;
pAsyncUnit asyncUnit;
StateMachine fsm;
pNWTimer state_timer; /**< state timer */
int iControl; /* integer controller (1..2) */
int iErrorCount; /* error count */
char serial_number[20];
char software_version[20];
char voltage_max[20];
@@ -62,9 +68,11 @@ typedef struct nhq200_s {
int vmax_percent;
int imax_percent;
int ramp_input;
bool run_flag;
} NHQ200Driv, *pNHQ200Driv;
};
typedef struct nhq200_s NHQ200Driv, *pNHQ200Driv;
/* Functions */
static int NHQ200GetValue( pEVDriver self, float* fPos);
static int NHQ200SetValue( pEVDriver self, float fPos);
static int NHQ200Send(pEVDriver self, char *pCommand, char *pReply, int iLen);
@@ -75,6 +83,18 @@ static int NHQ200Close(pEVDriver self);
static void NHQ200KillPrivate(void *pData);
static void NHQ200Notify(void* context, int event);
static void NHQ_SetTimer(pNHQ200Driv priv, int msecs) {
NetWatchRegisterTimer(&priv->state_timer, msecs, fsm_tmr_callback, &priv->fsm);
}
/**
* \brief Sends a command and set up for a response event
*
* \param self motor data
* \param cmd command to send
* \param reply space to return response
* \return
*/
static int NHQ_SendCmd(pNHQ200Driv priv,
char* command,
int cmd_len,
@@ -110,10 +130,7 @@ static int NHQ_SendReceive(pNHQ200Driv priv,
return OKOK;
}
static void NHQ_SetTimer(pNHQ200Driv priv, int msecs) {
NetWatchRegisterTimer(&priv->state_timer, msecs, fsm_tmr_callback, &priv->fsm);
}
/* State Functions */
static void NHQState_Unknown(pStateMachine sm, pEvtEvent event);
static void NHQState_Idle(pStateMachine sm, pEvtEvent event);
static void NHQState_Raising(pStateMachine sm, pEvtEvent event);
@@ -353,6 +370,13 @@ static void parse_Gx(pNHQ200Driv priv, const char* resp, int resp_len)
#define STATE_VX 6
#define STATE_END 9
/* State Functions */
/*
* Unknown State
*
* Handle initialisation and reset operations
*/
static void NHQState_Unknown(pStateMachine sm, pEvtEvent event) {
pEVDriver driv = (pEVDriver) sm->context;
pNHQ200Driv priv = (pNHQ200Driv) driv->pPrivate;
@@ -473,6 +497,12 @@ static void NHQState_Unknown(pStateMachine sm, pEvtEvent event) {
return;
}
/*
* Idle State
*
* Just monitoring what's going on
* and waiting to be told to run somewhere
*/
static void NHQState_Idle(pStateMachine sm, pEvtEvent event){
pEVDriver driv = (pEVDriver) sm->context;
pNHQ200Driv priv = (pNHQ200Driv) driv->pPrivate;
@@ -492,12 +522,12 @@ static void NHQState_Idle(pStateMachine sm, pEvtEvent event){
return;
case eTimerEvent:
priv->state_timer = NULL;
if (priv->run_flag) {
if (priv->bRunFlag) {
if (priv->fTarget > priv->fValue)
fsm_change_state(sm, NHQState_Raising);
else
fsm_change_state(sm, NHQState_Lowering);
priv->run_flag = false;
priv->bRunFlag = false;
return;
}
cmd_len = snprintf(cmd, sizeof(cmd), "U%d", priv->iControl);
@@ -545,6 +575,11 @@ static void NHQState_Idle(pStateMachine sm, pEvtEvent event){
}
return;
}
/* Raising State
*
* Increasing controlled value
*/
static void NHQState_Raising(pStateMachine sm, pEvtEvent event) {
pEVDriver driv = (pEVDriver) sm->context;
pNHQ200Driv priv = (pNHQ200Driv) driv->pPrivate;
@@ -626,6 +661,10 @@ static void NHQState_Raising(pStateMachine sm, pEvtEvent event) {
return;
}
/* Lowering State
*
* Decreasing controlled value
*/
static void NHQState_Lowering(pStateMachine sm, pEvtEvent event) {
pEVDriver driv = (pEVDriver) sm->context;
pNHQ200Driv priv = (pNHQ200Driv) driv->pPrivate;
@@ -707,10 +746,17 @@ static void NHQState_Lowering(pStateMachine sm, pEvtEvent event) {
return;
}
/* Error State
*
* Something bad has happened, we need a reset
*/
static void NHQState_Error(pStateMachine sm, pEvtEvent event) {
/* TODO */
}
/*
* Return the current value to SICS
*/
static int NHQ200GetValue( pEVDriver self, float* fPos) {
pNHQ200Driv priv = NULL;
assert(self);
@@ -719,12 +765,16 @@ static int NHQ200GetValue( pEVDriver self, float* fPos) {
*fPos = priv->fValue;
return 1;
}
/*
* Set the current value from SICS
*/
static int NHQ200SetValue( pEVDriver self, float fPos) {
pNHQ200Driv priv = NULL;
assert(self);
assert(self->pPrivate);
priv = (pNHQ200Driv) self->pPrivate;
if (priv->isLocked) {
if (priv->isLocked && !priv->bInternal) {
priv->iErrorCode = NHQ200_ERR_LOCKED;
return 0;
}
@@ -733,9 +783,13 @@ static int NHQ200SetValue( pEVDriver self, float fPos) {
return 0;
}
priv->fTarget = fPos;
priv->run_flag = true;
priv->bRunFlag = true;
return 1;
}
/*
* Send a command from SICS
*/
static int NHQ200Send(pEVDriver self, char *pCommand, char *pReply, int iLen) {
char cmd[CMDLEN];
int cmd_len;
@@ -770,6 +824,10 @@ static int NHQ200Send(pEVDriver self, char *pCommand, char *pReply, int iLen) {
}
return -1;
}
/*
* SICS error handler
*/
static int NHQ200Error(pEVDriver self, int *iCode, char *error, int iErrLen) {
pNHQ200Driv priv = (pNHQ200Driv) self->pPrivate;
*iCode = priv->iErrorCode;
@@ -787,6 +845,9 @@ static int NHQ200Error(pEVDriver self, int *iCode, char *error, int iErrLen) {
return 1;
}
/*
* SICS fix handler
*/
static int NHQ200Fix(pEVDriver self, int iError) {
/* TODO */
return DEVFAULT;
@@ -817,28 +878,42 @@ static void NHQ200KillPrivate(void *pData) {
}
}
static int NHQ200_Tx1(pAsyncProtocol p, void* ctx)
{
/*
* Auxilliary transmit function
* Called internaly to transmit a character
*/
static int NHQ200_Tx1(pAsyncProtocol p, pAsyncTxn myCmd) {
int iRet = 1;
pAsyncTxn myCmd = (pAsyncTxn) ctx;
assert(myCmd);
iRet = AsyncUnitWrite(myCmd->unit, &myCmd->out_buf[myCmd->out_idx], 1);
return iRet;
}
static int NHQ200_Tx(pAsyncProtocol p, pAsyncTxn myCmd)
{
/*
* Set/reset command states for send/resend of command
*/
myCmd->txn_state = 0;
myCmd->out_idx = 0;
myCmd->inp_idx = 0;
myCmd->txn_status = ATX_ACTIVE;
return NHQ200_Tx1(p, myCmd);
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
*/
static int NHQ200_Tx(pAsyncProtocol p, pAsyncTxn myCmd) {
int iRet = 1;
if (myCmd) {
myCmd->txn_status = ATX_ACTIVE;
/*
* Set/reset command states for send/resend of command
*/
myCmd->txn_state = 0;
myCmd->out_idx = 0;
myCmd->inp_idx = 0;
iRet = NHQ200_Tx1(p, myCmd);
return iRet;
}
return 1;
}
/*
* Protocol receive character - characater by character
*/
static int NHQ200_Rx(pAsyncProtocol p, pAsyncTxn myCmd, int rxchar)
{
int iRet = 1;
@@ -890,6 +965,9 @@ static int NHQ200_Rx(pAsyncProtocol p, pAsyncTxn myCmd, int rxchar)
return iRet;
}
/*
* AsyncUnit Notify Callback
*/
static void NHQ200Notify(void* context, int event)
{
pNHQ200Driv priv = (pNHQ200Driv) context;
@@ -912,6 +990,9 @@ static void NHQ200Notify(void* context, int event)
return;
}
/*
* AsyncProtocol Event callback
*/
static int NHQ200_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
if (event == AQU_TIMEOUT) {
/* handle command timeout */
@@ -921,30 +1002,26 @@ static int NHQ200_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
return AQU_POP_CMD;
}
static int NHQ200_PrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int cmd_len, int rsp_len) {
txn->out_buf = (char*) malloc(cmd_len);
if (txn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in NHQ200_PrepareTxn", eError);
return 0;
}
memcpy(txn->out_buf, cmd, cmd_len);
txn->out_len = cmd_len;
return 1;
}
static pAsyncProtocol NHQ200_Protocol = NULL;
/*
* Protocol Initialisation
*/
void NHQ200InitProtocol(SicsInterp *pSics) {
if (NHQ200_Protocol == NULL) {
NHQ200_Protocol = AsyncProtocolCreate(pSics, "NHQ200", NULL, NULL);
NHQ200_Protocol->sendCommand = NHQ200_Tx;
NHQ200_Protocol->handleInput = NHQ200_Rx;
NHQ200_Protocol->handleEvent = NHQ200_Ev;
NHQ200_Protocol->prepareTxn = NULL; /* NHQ200_PrepareTxn; */
NHQ200_Protocol->killPrivate = NULL;
// NHQ200_Protocol->prepareTxn = NULL;
// NHQ200_Protocol->killPrivate = NULL;
}
}
/*
* Device Factory
*/
pEVDriver CreateNHQ200Driver(int argc, char *argv[])
{
pEVDriver self = NULL;
@@ -966,7 +1043,7 @@ pEVDriver CreateNHQ200Driver(int argc, char *argv[])
if (!AsyncUnitCreate(argv[0], &priv->asyncUnit)) {
char line[132];
snprintf(line, 132, "Error: did not find AsyncQueue %s for Device", argv[0]);
snprintf(line, 132, "Error: did not find AsyncQueue %s for Device %s", argv[1], argv[0]);
SICSLogWrite(line, eError);
DeleteEVDriver(self);
free(priv);
@@ -994,7 +1071,7 @@ pEVDriver CreateNHQ200Driver(int argc, char *argv[])
priv->fRate = 10.0;
priv->fLower = 0.0;
priv->fUpper = 0.0;
priv->iControl = 1;
priv->bRunFlag = false;
priv->iControl = 1;
if (argc > 1)
priv->iControl = strtol(argv[1], NULL, 10);
@@ -1004,6 +1081,9 @@ pEVDriver CreateNHQ200Driver(int argc, char *argv[])
return self;
}
/*
* Register the controller with the driver
*/
void NHQ200Register(pEVControl self, pEVDriver driv)
{
pNHQ200Driv priv = (pNHQ200Driv) driv->pPrivate;
@@ -1025,6 +1105,9 @@ void NHQ200Register(pEVControl self, pEVDriver driv)
}
/*
* Action Wrapper routine
*/
int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
@@ -1090,7 +1173,9 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
priv->fTarget = priv->fMax;
if (priv->fTarget < 0)
priv->fTarget = 0.0;
priv->bInternal = true;
iRet = EVCDrive(priv->controller, pCon, priv->fTarget);
priv->bInternal = false;
if(iRet)
SCSendOK(pCon);
return iRet;
@@ -1100,7 +1185,9 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
if(!SCMatchRights(pCon,usUser))
return 0;
priv->fTarget = 0.0;
priv->bInternal = true;
iRet = EVCDrive(priv->controller, pCon, priv->fTarget);
priv->bInternal = false;
if(iRet)
SCSendOK(pCon);
return iRet;
@@ -1108,7 +1195,9 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
if (strcasecmp("upper", argv[1]) == 0) {
char rsp[CMDLEN];
if (argc > 2) {
if (priv->isLocked) {
if (!SCMatchRights(pCon, usUser))
return 0;
if (priv->isLocked && !SCMatchRights(pCon, usMugger)) {
SCWrite(pCon, "object is locked", eError);
return 0;
}
@@ -1130,7 +1219,9 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
if (strcasecmp("lower", argv[1]) == 0) {
char rsp[CMDLEN];
if (argc > 2) {
if (priv->isLocked) {
if (!SCMatchRights(pCon, usUser))
return 0;
if (priv->isLocked && !SCMatchRights(pCon, usMugger)) {
SCWrite(pCon, "object is locked", eError);
return 0;
}
@@ -1152,17 +1243,21 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
if (strcasecmp("max", argv[1]) == 0) {
char rsp[CMDLEN];
if (argc > 2) {
if (!SCMatchRights(pCon, usUser))
return 0;
if (priv->isLocked) {
SCWrite(pCon, "object is locked", eError);
return 0;
}
else {
float value = atof(argv[2]);
if (value >= 0.0 && value <= 6000.0) {
if (value >= 0.0 && value <= MY_ABSOLUTE_MAXIMUM) {
priv->fMax = value;
}
else {
SCWrite(pCon, "max must be between 0.0 and 6000.0", eError);
char line[CMDLEN];
snprintf(line, CMDLEN, "max must be between 0.0 and %.0f", MY_ABSOLUTE_MAXIMUM);
SCWrite(pCon, line, eError);
return 0;
}
}
@@ -1171,7 +1266,7 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon, rsp, eValue);
return 1;
}
if (strcasecmp("debug", argv[1]) == 0) {
if (strcasecmp("debug", argv[1]) == 0 && SCMatchRights(pCon, usMugger)) {
char rsp[CMDLEN];
if (argc > 2) {
int debug = atoi(argv[2]);
@@ -1187,13 +1282,15 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
if (strcasecmp("rate", argv[1]) == 0) {
char rsp[CMDLEN];
if (argc > 2) {
if (priv->isLocked) {
if (!SCMatchRights(pCon, usUser))
return 0;
if (priv->isLocked && !SCMatchRights(pCon, usMugger)) {
SCWrite(pCon, "object is locked", eError);
return 0;
}
else {
float value = atof(argv[2]);
if (value >= 2.0 && value <= 255.0) {
if (value >= MY_MINIMUM_RATE && value <= MY_MAXIMUM_RATE) {
priv->fRate = value;
char cmd[CMDLEN];
int cmd_len;
@@ -1204,7 +1301,9 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
NHQ_SendReceive(priv, cmd, cmd_len, rsp, &rsp_len);
}
else {
SCWrite(pCon, "rate must be between 2 and 255", eError);
char line[CMDLEN];
snprintf(line, CMDLEN, "rate must be between %.0f and %.0f", MY_MINIMUM_RATE, MY_MAXIMUM_RATE);
SCWrite(pCon, line, eError);
return 0;
}
}
@@ -1213,15 +1312,10 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon, rsp, eValue);
return 1;
}
if (strcasecmp("status", argv[1]) == 0) {
char line[CMDLEN];
read_status(priv, line, sizeof(line));
SCWrite(pCon, line, eValue);
return 1;
}
if (strcasecmp("reset", argv[1]) == 0) {
char line[CMDLEN];
if (!SCMatchRights(pCon, usUser))
return 0;
read_status(priv, line, sizeof(line));
SCWrite(pCon, line, eValue);
/* restart state machine */
@@ -1235,20 +1329,21 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon, line, eValue);
return 1;
}
if(strcasecmp("state", argv[1]) == 0) {
char line[132];
snprintf(line, 132, "%s.state = %s(%d) (timer=%s)",
priv->name,
state_name(priv->fsm.myState),
priv->fsm.mySubState,
priv->state_timer ? "active" : "inactive");
SCWrite(pCon, line, eValue);
return 1;
}
if (strcasecmp("lock", argv[1]) == 0) {
char rsp[CMDLEN];
if (!SCMatchRights(pCon, usUser))
return 0;
priv->isLocked = 1;
snprintf(rsp, CMDLEN, "%s.lock = 1", priv->name);
snprintf(rsp, CMDLEN, "%s.lock = %d", priv->name, priv->isLocked);
SCWrite(pCon, rsp, eValue);
return 1;
}
if (strcasecmp("unlock", argv[1]) == 0
&& SCMatchRights(pCon, usMugger)
&& priv->fsm.debug) {
char rsp[CMDLEN];
priv->isLocked = 0;
snprintf(rsp, CMDLEN, "%s.lock = %d", priv->name, priv->isLocked);
SCWrite(pCon, rsp, eValue);
return 1;
}
@@ -1266,8 +1361,25 @@ int NHQ200Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
snprintf(rsp, CMDLEN, "%s.rate = %8.2f", priv->name, priv->fRate);
SCWrite(pCon, rsp, eValue);
}
if(strcasecmp("state", argv[1]) == 0) {
char line[132];
snprintf(line, 132, "%s.state = %s(%d) (timer=%s)",
priv->name,
state_name(priv->fsm.myState),
priv->fsm.mySubState,
priv->state_timer ? "active" : "inactive");
SCWrite(pCon, line, eValue);
return 1;
}
return iRet;
}
if (strcasecmp("status", argv[1]) == 0) {
char line[CMDLEN];
read_status(priv, line, sizeof(line));
SCWrite(pCon, line, eValue);
return 1;
}
return EVControlWrapper(pCon,pSics,pData,argc,argv);
}