226 lines
5.7 KiB
C
226 lines
5.7 KiB
C
/*------------------------------------------------------------------------
|
|
C h o p p e r C o n t r o l l e r
|
|
|
|
Implementation file for the SICS chopper controller and general controller
|
|
device. For details about this object and its relation with the SICS system
|
|
see choco.w or choco.tex.
|
|
|
|
Mark Koennecke, January 1998
|
|
-------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <tcl.h>
|
|
#include <assert.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "site.h"
|
|
#define CHOCOINTERNAL
|
|
#include "choco.h"
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
int CHGetParameter(pChoco self, char *parname, char *pParValue,
|
|
int iBuflen)
|
|
{
|
|
int iRet, iCode;
|
|
|
|
assert(self);
|
|
|
|
iRet = self->pDriv->GetPar(self->pDriv, parname, pParValue, iBuflen);
|
|
if (!iRet) {
|
|
iRet = 0;
|
|
self->pDriv->GetError(self->pDriv, &iCode, pParValue, iBuflen);
|
|
}
|
|
return iRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
pCodri CHGetDriver(pChoco self)
|
|
{
|
|
assert(self);
|
|
|
|
return self->pDriv;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
int CHList(pChoco self, SConnection * pCon, char *name)
|
|
{
|
|
char *pPar, *pCopy = NULL;
|
|
char pValue[80];
|
|
char pMessage[256];
|
|
int iRet, iLen;
|
|
Tcl_DString tlist;
|
|
|
|
assert(self);
|
|
|
|
/* copy pParList as it will be destroyed by strtok */
|
|
iLen = strlen(self->pDriv->pParList);
|
|
pCopy = (char *) malloc((iLen + 10) * sizeof(char));
|
|
if (!pCopy) {
|
|
SCWrite(pCon, "ERROR: out of memory in CHList", eError);
|
|
return 0;
|
|
}
|
|
memset(pCopy, 0, iLen + 10);
|
|
strcpy(pCopy, self->pDriv->pParList);
|
|
Tcl_DStringInit(&tlist);
|
|
|
|
pPar = strtok(pCopy, ",");
|
|
while (pPar != NULL) {
|
|
iRet = CHGetParameter(self, pPar, pValue, 79);
|
|
if (iRet) {
|
|
sprintf(pMessage, "%s.%s = %s \n", name, pPar, pValue);
|
|
} else {
|
|
sprintf(pMessage, "ERROR: %s : while reading parameter %s \n",
|
|
pValue, pPar);
|
|
}
|
|
Tcl_DStringAppend(&tlist, pMessage, -1);
|
|
pPar = strtok(NULL, ",");
|
|
}
|
|
SCWrite(pCon, Tcl_DStringValue(&tlist), eValue);
|
|
Tcl_DStringFree(&tlist);
|
|
free(pCopy);
|
|
return 1;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------*/
|
|
int ChocoAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pChoco self = NULL;
|
|
char pValue[80], pMessage[256];
|
|
int iRet;
|
|
|
|
self = (pChoco) pData;
|
|
assert(self);
|
|
|
|
if (argc < 2) {
|
|
snprintf(pMessage,255, "ERROR: argument required for %s", argv[0]);
|
|
SCWrite(pCon, pMessage, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* argument can either be list or parameter name */
|
|
strtolower(argv[1]);
|
|
if (strcmp(argv[1], "list") == 0) {
|
|
return CHList(self, pCon, argv[0]);
|
|
} else {
|
|
if (argc > 2) {
|
|
/* set case */
|
|
iRet = self->pDriv->SetPar2(self->pDriv, argv[1], argv[2]);
|
|
if (!iRet) {
|
|
self->pDriv->GetError(self->pDriv, &iRet, pValue, 79);
|
|
sprintf(pMessage, "ERROR: %s", pValue);
|
|
SCWrite(pCon, pMessage, eError);
|
|
return 0;
|
|
} else {
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
} else {
|
|
/* get case */
|
|
iRet = CHGetParameter(self, argv[1], pValue, 79);
|
|
if (iRet) {
|
|
sprintf(pMessage, "%s.%s = %s", argv[0], argv[1], pValue);
|
|
} else {
|
|
sprintf(pMessage, "ERROR: %s : while reading parameter %s",
|
|
pValue, argv[1]);
|
|
}
|
|
SCWrite(pCon, pMessage, eValue);
|
|
return iRet;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
void KillChoco(void *pData)
|
|
{
|
|
pChoco self = NULL;
|
|
|
|
self = (pChoco) pData;
|
|
if (!self)
|
|
return;
|
|
|
|
if (self->pDriv) {
|
|
self->pDriv->Close(self->pDriv);
|
|
self->pDriv->Delete(self->pDriv);
|
|
free(self->pDriv);
|
|
}
|
|
if (self->pDes)
|
|
DeleteDescriptor(self->pDes);
|
|
|
|
free(self);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
DRIVERS
|
|
*/
|
|
|
|
extern pCodri MakeSimChopper(void);
|
|
/*-----------------------------------------------------------------------*/
|
|
int ChocoFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pChoco pNew = NULL;
|
|
pCodri pDriv = NULL;
|
|
pObjectDescriptor pDes = NULL;
|
|
char pBueffel[132];
|
|
int iRet, iPort, iChannel;
|
|
int iSingle = 0;
|
|
pSite site = NULL;
|
|
|
|
if (argc < 3) {
|
|
SCWrite(pCon,
|
|
"ERROR: Insufficient number of arguments to MakeController",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* first try to get everything done */
|
|
pNew = (pChoco) malloc(sizeof(Choco));
|
|
pDes = CreateDescriptor("Chopper");
|
|
/* do driver */
|
|
strtolower(argv[2]);
|
|
if (strcmp(argv[2], "sim") == 0) {
|
|
pDriv = MakeSimChopper();
|
|
} else {
|
|
site = getSite();
|
|
if (site != NULL) {
|
|
pDriv = site->CreateControllerDriver(pCon, argc - 2, &argv[2]);
|
|
} else {
|
|
pDriv = NULL;
|
|
}
|
|
if (pDriv == NULL) {
|
|
snprintf(pBueffel,131,
|
|
"ERROR: Driver %s NOT supported for MakeController",
|
|
argv[2]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
}
|
|
if ((pNew == NULL) || (pDes == NULL) || (pDriv == NULL)) {
|
|
SCWrite(pCon, "ERROR: No memory left to create controller", eError);
|
|
return 0;
|
|
}
|
|
pNew->pDes = pDes;
|
|
pNew->pDriv = pDriv;
|
|
|
|
/* initialize driver */
|
|
iRet = pDriv->Init(pDriv);
|
|
if (!iRet) {
|
|
SCWrite(pCon, "ERROR: Failed to initialize driver", eError);
|
|
KillChoco(pNew);
|
|
return 0;
|
|
}
|
|
|
|
/* install as command */
|
|
iRet = AddCommand(pSics, argv[1], ChocoAction, KillChoco, pNew);
|
|
if (!iRet) {
|
|
snprintf(pBueffel, 131, "ERROR: duplicate command %s NOT created", argv[1]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|