- Added a new magnet driver for the SLS-VME setup using a

little program on an onboard computer
This commit is contained in:
koennecke
2008-05-08 09:33:07 +00:00
parent 5e96ae6939
commit f10767551e
2 changed files with 867 additions and 0 deletions

805
slsvme.c Normal file
View File

@ -0,0 +1,805 @@
/*--------------------------------------------------------------------------
S L S V M E
This file contains the driver for the PSI-DSP magnet controller as
aquired from SLS.
This version is for the new interface provided by the vmemaggi server
program running on embedded linux on a computer in the VME crate which
talks directly to the IP communication mudules on the VME bus.
Copyright: see file COPYRIGHT
Mark Koennecke, April 2008
----------------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fortify.h>
#include <conman.h>
#include <servlog.h>
#include <fortify.h>
#include <sics.h>
#include "evdriver.h"
#include <network.h>
#include <rs232controller.h>
#include "vmemaggi.h"
#include <stptok.h>
#define ABS(x) (x < 0 ? -(x) : (x))
extern char *trim(char *txt);
#define DEVERR -2001
#define BADHIGHLIM -2002
#define BADLOWLIM -2003
/*-----------------------------------------------------------------------*/
typedef struct {
prs232 controller;
int iNum;
int iError;
int iDevError;
char errorText[80];
} SLSDriv, *pSLSDriv;
/*-------------------------------------------------------------------------*/
static int communicateSLS(pSLSDriv self, char *command,
char *reply, int replyLen)
{
long lVal = 0;
int iRet, i, address, status;
char *pPtr;
char text[80];
if(!self->controller){
self->iError = NOTCONNECTED;
strcpy(self->errorText,"Not Connected");
return -1;
}
self->iDevError = 0;
memset(reply,0,replyLen);
iRet = transactRS232(self->controller, command, strlen(command),
reply, replyLen);
if(iRet < 0){
return iRet;
}
if(strstr(reply, "ERROR") != NULL){
pPtr = reply;
/* jump over error */
pPtr = stptok(pPtr,"text",80,":");
/* read error number */
pPtr = stptok(pPtr,"text",80,":");
self->iError = atoi(trim(text));
/* read error description */
pPtr = stptok(pPtr,"text",80,":");
strncpy(self->errorText, text, 80);
return DEVERR;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static void locateValue(char *rawReply, char *value, int valLen){
char *pPtr;
pPtr = rawReply;
pPtr = stptok(pPtr,value, valLen," ");
pPtr = stptok(pPtr,value, valLen," ");
stptok(pPtr,value, valLen," ");
}
/*---------------------------------------------------------------------*/
static void slsdspCodeToText(int code, char *text, int textlen){
switch(code){
case 0x0:
strncpy(text,"NO",textlen);
break;
case 0x1:
strncpy(text,"DEVICE_STATE_ERROR",textlen);
break;
case 0x2:
strncpy(text,"DEVICE_SUPERVISOR_DISABLED",textlen);
break;
case 0x3:
strncpy(text,"COMMAND_ABORT",textlen);
break;
case 0x4:
strncpy(text,"DATA_NOT_STORED",textlen);
break;
case 0x5:
strncpy(text,"ERROR_ERASING_FLASH",textlen);
break;
case 0x6:
strncpy(text,"COMMUNICATION_BREAK",textlen);
break;
case 0x7:
strncpy(text,"INTERNAL_COMMUNICATION_ERROR",textlen);
break;
case 0x8:
strncpy(text,"MASTER_CARD_ERROR",textlen);
break;
case 0x9:
strncpy(text,"INTERNAL_BUFFER_FULL",textlen);
break;
case 0xa:
strncpy(text,"WRONG_SECTOR",textlen);
break;
case 0xb:
strncpy(text,"DATA_NOT_COPIED",textlen);
break;
case 0xc:
strncpy(text,"WRONG_DOWNLOAD_PARAMETERS",textlen);
break;
case 0xd:
strncpy(text,"DEVICE_PARAMETRIZATION_ERROR",textlen);
break;
case 0x10:
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE",textlen);
break;
case 0x11:
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_ON",textlen);
break;
case 0x12:
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_OFF",textlen);
break;
case 0x13:
strncpy(text,"TIMEOUT_MAIN_RELAY_ON",textlen);
break;
case 0x14:
strncpy(text,"TIMEOUT_MAIN_RELAY_OFF",textlen);
break;
case 0x15:
strncpy(text,"TIMEOUT_DATA_DOWNLOAD",textlen);
break;
case 0x20:
strncpy(text,"INTERLOCK",textlen);
break;
case 0x21:
strncpy(text,"MASTER_SWITCH",textlen);
break;
case 0x22:
strncpy(text,"MAGNET_INTERLOCK",textlen);
break;
case 0x23:
strncpy(text,"TEMPERATURE_TRANSFORMER",textlen);
break;
case 0x24:
strncpy(text,"TEMPERATURE_RECTIFIER",textlen);
break;
case 0x25:
strncpy(text,"TEMPERATURE_CONVERTER",textlen);
break;
case 0x26:
strncpy(text,"CURRENT_TRANSDUCER",textlen);
break;
case 0x27:
strncpy(text,"TEMPERATURE_POLARITY_SWITCH",textlen);
break;
case 0x28:
strncpy(text,"POWER_SEMICONDUCTOR",textlen);
break;
case 0x29:
strncpy(text,"MAIN_RELAY",textlen);
break;
case 0x2a:
strncpy(text,"AD_CONVERTER_CARD",textlen);
break;
case 0x2b:
strncpy(text,"POLARITY_SWITCH",textlen);
break;
case 0x2c:
strncpy(text,"AUXILIARY_RELAY",textlen);
break;
case 0x2d:
strncpy(text,"MASTER_SWITCH_T1",textlen);
break;
case 0x2e:
strncpy(text,"MASTER_SWITCH_T2",textlen);
break;
case 0x2f:
strncpy(text,"TEMPERATURE_MAGNET",textlen);
break;
case 0x30:
strncpy(text,"WATER_MAGNET",textlen);
break;
case 0x31:
strncpy(text,"WATER_RACK",textlen);
break;
case 0x40:
strncpy(text,"LOAD_CURRENT_TOO_HIGH",textlen);
break;
case 0x41:
strncpy(text,"DC_LINK_VOLTAGE_TOO_LOW",textlen);
break;
case 0x42:
strncpy(text,"DC_LINK_VOLTAGE_TOO_HIGH",textlen);
break;
case 0x43:
strncpy(text,"LOAD_VOLTAGE_TOO_HIGH",textlen);
break;
case 0x44:
strncpy(text,"LOAD_CURRENT_RIPPLE_TOO_HIGH",textlen);
break;
case 0x45:
strncpy(text,"DC_LINK_ISOLATION_NOT_OK",textlen);
break;
case 0x46:
strncpy(text,"LOAD_ISOLATION_NOT_OK",textlen);
break;
case 0x47:
strncpy(text,"LOAD_IMPEDANCE_OUT_OF_RANGE",textlen);
break;
case 0x48:
strncpy(text,"SHUT_OFF_CURRENT_TOO_HIGH",textlen);
break;
case 0x49:
strncpy(text,"LOAD_DC_CURRENT_TOO_HIGH",textlen);
break;
case 0x4a:
strncpy(text,"CURRENT_I1A1_TOO_HIGH",textlen);
break;
case 0x4b:
strncpy(text,"CURRENT_I1B1_TOO_HIGH",textlen);
break;
case 0x4c:
strncpy(text,"CURRENT_I1A2_TOO_HIGH",textlen);
break;
case 0x4d:
strncpy(text,"CURRENT_I1B2_TOO_HIGH",textlen);
break;
case 0x4e:
strncpy(text,"CURRENT_I2A1_TOO_HIGH",textlen);
break;
case 0x4f:
strncpy(text,"CURRENT_I2B1_TOO_HIGH",textlen);
break;
case 0x50:
strncpy(text,"CURRENT_I2A2_TOO_HIGH",textlen);
break;
case 0x51:
strncpy(text,"CURRENT_I2B2_TOO_HIGH",textlen);
break;
case 0x52:
strncpy(text,"CURRENT_I3P_TOO_HIGH",textlen);
break;
case 0x53:
strncpy(text,"CURRENT_I3N_TOO_HIGH",textlen);
break;
case 0x54:
strncpy(text,"CURRENT_IE_TOO_HIGH",textlen);
break;
case 0x55:
strncpy(text,"VOLTAGE_U1A_TOO_LOW",textlen);
break;
case 0x56:
strncpy(text,"VOLTAGE_U1B_TOO_LOW",textlen);
break;
case 0x57:
strncpy(text,"DIFF_CURRENT_I1A1_I1A2_TOO_HIGH",textlen);
break;
case 0x58:
strncpy(text,"DIFF_CURRENT_I1B1_I1B2_TOO_HIGH",textlen);
break;
case 0x59:
strncpy(text,"DIFF_CURRENT_I2A1_I2A2_TOO_HIGH",textlen);
break;
case 0x5a:
strncpy(text,"DIFF_CURRENT_I2B1_I2B2_TOO_HIGH",textlen);
break;
case 0x5b:
strncpy(text,"DIFF_CURRENT_I3P_I3N_TOO_HIGH",textlen);
break;
case 0x5c:
strncpy(text,"CURRENT_I1A_TOO_HIGH",textlen);
break;
case 0x5d:
strncpy(text,"CURRENT_I1B_TOO_HIGH",textlen);
break;
case 0x5e:
strncpy(text,"CURRENT_I3A1_TOO_HIGH",textlen);
break;
case 0x5f:
strncpy(text,"CURRENT_I3B1_TOO_HIGH",textlen);
break;
case 0x60:
strncpy(text,"CURRENT_I3A2_TOO_HIGH",textlen);
break;
case 0x61:
strncpy(text,"CURRENT_I3B2_TOO_HIGH",textlen);
break;
case 0x62:
strncpy(text,"CURRENT_I4_TOO_HIGH",textlen);
break;
case 0x63:
strncpy(text,"CURRENT_I5_TOO_HIGH",textlen);
break;
case 0x64:
strncpy(text,"DIFF_CURRENT_I3A1_I3A2_TOO_HIGH",textlen);
break;
case 0x65:
strncpy(text,"DIFF_CURRENT_I3B1_I3B2_TOO_HIGH",textlen);
break;
case 0x66:
strncpy(text,"DIFF_CURRENT_I4_I5_TOO_HIGH",textlen);
break;
case 0x67:
strncpy(text,"VOLTAGE_U3A_TOO_LOW",textlen);
break;
case 0x68:
strncpy(text,"VOLTAGE_U3B_TOO_LOW",textlen);
break;
case 0x69:
strncpy(text,"VOLTAGE_U1_TOO_LOW",textlen);
break;
case 0x6a:
strncpy(text,"VOLTAGE_U3A_TOO_HIGH",textlen);
break;
case 0x6b:
strncpy(text,"VOLTAGE_U3B_TOO_HIGH",textlen);
break;
case 0x6c:
strncpy(text,"SPEED_ERROR_TOO_HIGH",textlen);
break;
case 0x70:
strncpy(text,"MAIN_RELAY_A",textlen);
break;
case 0x71:
strncpy(text,"MAIN_RELAY_B",textlen);
break;
case 0x72:
strncpy(text,"POWER_SWITCH_A",textlen);
break;
case 0x73:
strncpy(text,"POWER_SWITCH_B",textlen);
break;
case 0x74:
strncpy(text,"MONITOR_TRAFO_A",textlen);
break;
case 0x75:
strncpy(text,"MONITOR_TRAFO_B",textlen);
break;
case 0x76:
strncpy(text,"TEMPERATURE_RECTIFIER_A",textlen);
break;
case 0x77:
strncpy(text,"TEMPERATURE_RECTIFIER_B",textlen);
break;
case 0x78:
strncpy(text,"TEMPERATURE_CONVERTER_A",textlen);
break;
case 0x79:
strncpy(text,"TEMPERATURE_CONVERTER_B",textlen);
break;
case 0x7a:
strncpy(text,"TEMPERATURE_CONVERTER_A1",textlen);
break;
case 0x7b:
strncpy(text,"TEMPERATURE_CONVERTER_B1",textlen);
break;
case 0x7c:
strncpy(text,"TEMPERATURE_CONVERTER_A2",textlen);
break;
case 0x7d:
strncpy(text,"TEMPERATURE_CONVERTER_B2",textlen);
break;
case 0x7e:
strncpy(text,"TEMPERATURE_TRANSFORMER_A",textlen);
break;
case 0x7f:
strncpy(text,"TEMPERATURE_TRANSFORMER_B",textlen);
break;
case 0x80:
strncpy(text,"WATER_RECTIFIER_A",textlen);
break;
case 0x81:
strncpy(text,"WATER_RECTIFIER_B",textlen);
break;
case 0x82:
strncpy(text,"WATER_CONVERTER_A",textlen);
break;
case 0x83:
strncpy(text,"WATER_CONVERTER_B",textlen);
break;
case 0x84:
strncpy(text,"WATER_CONVERTER_A1",textlen);
break;
case 0x85:
strncpy(text,"WATER_CONVERTER_B1",textlen);
break;
case 0x86:
strncpy(text,"WATER_CONVERTER_A2",textlen);
break;
case 0x87:
strncpy(text,"WATER_CONVERTER_B2",textlen);
break;
case 0x88:
strncpy(text,"WATER_TRANSFORMER_A",textlen);
break;
case 0x89:
strncpy(text,"WATER_TRANSFORMER_B",textlen);
break;
case 0x8a:
strncpy(text,"DOOR_A",textlen);
break;
case 0x8b:
strncpy(text,"DOOR_B",textlen);
break;
case 0x8c:
strncpy(text,"DOOR_C",textlen);
break;
case 0x8d:
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A",textlen);
break;
case 0x8e:
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B",textlen);
break;
case 0x8f:
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A1",textlen);
break;
case 0x90:
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B1",textlen);
break;
case 0x91:
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A2",textlen);
break;
case 0x92:
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B2",textlen);
break;
case 0x93:
strncpy(text,"CURRENT_TRANSDUCER_I3P",textlen);
break;
case 0x94:
strncpy(text,"CURRENT_TRANSDUCER_I3N",textlen);
break;
case 0x95:
strncpy(text,"MAGNET_INTERLOCK_1",textlen);
break;
case 0x96:
strncpy(text,"MAGNET_INTERLOCK_2",textlen);
break;
case 0x97:
strncpy(text,"VENTILATOR",textlen);
break;
case 0x98:
strncpy(text,"EMERGENCY_SWITCH",textlen);
break;
case 0x99:
strncpy(text,"CAPACITOR_DISCHARGE_A_ON",textlen);
break;
case 0x9a:
strncpy(text,"CAPACITOR_DISCHARGE_B_ON",textlen);
break;
case 0x9b:
strncpy(text,"CURRENT_TRANSDUCER_I4",textlen);
break;
case 0x9c:
strncpy(text,"CURRENT_TRANSDUCER_I5",textlen);
break;
case 0xb0:
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE_PART_A",textlen);
break;
case 0xb1:
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE_PART_B",textlen);
break;
case 0xb2:
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_A_ON",textlen);
break;
case 0xb3:
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_B_ON",textlen);
break;
case 0xb4:
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_A_OFF",textlen);
break;
case 0xb5:
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_B_OFF",textlen);
break;
case 0xb6:
strncpy(text,"TIMEOUT_MAIN_RELAY_A_ON",textlen);
break;
case 0xb7:
strncpy(text,"TIMEOUT_MAIN_RELAY_B_ON",textlen);
break;
case 0xb8:
strncpy(text,"TIMEOUT_MAIN_RELAY_A_OFF",textlen);
break;
case 0xb9:
strncpy(text,"TIMEOUT_MAIN_RELAY_B_OFF",textlen);
break;
}
}
/*---------------------------------------------------------------------------*/
static int GetSLSPos(pEVDriver self, float *fPos)
{
pSLSDriv pMe = NULL;
char command[40], reply[132], value[40];
int iRet;
assert(self);
pMe = (pSLSDriv)self->pPrivate;
assert(pMe);
/*
* first try to read the error code
*/
snprintf(command,40,"r %d err\n", pMe->iNum);
iRet = communicateSLS(pMe, command, reply, 132);
if(iRet < 0){
return 0;
}
locateValue(reply, value,40);
sscanf(value,"%x", &iRet);
if(iRet != 0){
slsdspCodeToText(iRet, pMe->errorText, 80);
pMe->iError = DEVERROR;
pMe->iDevError = iRet;
return 0;
}
/*
* really read the current
*/
snprintf(command,40,"r %d cur\n", pMe->iNum);
iRet = communicateSLS(pMe, command, reply, 132);
if(iRet < 0){
return 0;
}
locateValue(reply, value,40);
sscanf(value,"%f", fPos);
return 1;
}
/*----------------------------------------------------------------------------*/
static int SLSRun(pEVDriver self, float fVal)
{
pSLSDriv pMe = NULL;
int iRet;
char command[40], reply[132], value[40];
assert(self);
pMe = (pSLSDriv )self->pPrivate;
assert(pMe);
/*
* first check if this on
*/
snprintf(command,40,"r %d onoff\n", pMe->iNum);
iRet = communicateSLS(pMe, command, reply, 132);
if(iRet < 0){
return 0;
}
locateValue(reply,value,40);
if(strstr(value,"1") == NULL){
/*
* switch on
*/
snprintf(command,40,"w %d on\n", pMe->iNum);
iRet = communicateSLS(pMe, command, reply, 132);
if(iRet < 0){
return 0;
}
}
/*
* set a new value
*/
snprintf(command,40,"w %d cur %f\n", pMe->iNum, fVal);
iRet = communicateSLS(pMe, command, reply, 132);
if(iRet < 0){
return 0;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int SLSError(pEVDriver self, int *iCode, char *error, int iErrLen)
{
pSLSDriv pMe = NULL;
char *pPtr = NULL;
int i1, i2;
char pBueffel[132];
assert(self);
pMe = (pSLSDriv)self->pPrivate;
assert(pMe);
*iCode = pMe->iError;
if(pMe->iError == DEVERROR){
strncpy(error,pMe->errorText, iErrLen);
return 1;
}
if(pMe->iError < -2000 || (pMe->iError >= 70 && pMe->iError < 83)){
strncpy(error,pMe->errorText, iErrLen);
return 1;
}
getRS232Error(*iCode,error,iErrLen);
return 1;
}
/*-------------------------------------------------------------------------*/
static int SLSSend(pEVDriver self, char *pCommand, char *pReply, int iLen)
{
pSLSDriv pMe = NULL;
int iRet, ival;
char command[40];
assert(self);
pMe = (pSLSDriv )self->pPrivate;
assert(pMe);
if(strcmp(pCommand,"off") == 0){
snprintf(command,40,"w %d off\n", pMe->iNum);
} else if(strcmp(pCommand,"on") == 0){
snprintf(command,40,"w %d on\n", pMe->iNum);
} else {
strncpy(command,pCommand,40);
}
iRet = communicateSLS(pMe, command, pReply, iLen);
if(iRet < 0){
return 0;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int SLSInit(pEVDriver self)
{
pSLSDriv pMe = NULL;
int iRet, ival, i;
char msg[40], reply[40];
assert(self);
pMe = (pSLSDriv )self->pPrivate;
assert(pMe);
iRet = initRS232(pMe->controller);
if(iRet < 0)
{
return 0;
}
setRS232SendTerminator(pMe->controller, "\n");
setRS232ReplyTerminator(pMe->controller, "\n");
setRS232Timeout(pMe->controller, 1000);
snprintf(msg,40,"w %d on\n", pMe->iNum);
iRet = communicateSLS(pMe, msg, reply, 40);
if(iRet < 0){
return 0;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int SLSClose(pEVDriver self)
{
pSLSDriv pMe = NULL;
int iRet, ival;
char msg[6], reply[6];
assert(self);
pMe = (pSLSDriv )self->pPrivate;
assert(pMe);
closeRS232(pMe->controller);
return 1;
}
/*---------------------------------------------------------------------------*/
static int SLSFix(pEVDriver self, int iError)
{
pSLSDriv pMe = NULL;
int iRet, i, dataLen;
char buffer[80];
char msg[6], reply[6];
float fVal = .0;
assert(self);
pMe = (pSLSDriv )self->pPrivate;
assert(pMe);
switch(iError)
{
case BADHIGHLIM:
case BADLOWLIM:
case BADSLOT:
case BADMAP:
case DSPSTOP:
case LINKDWN:
case MISPS:
case PSRNG:
case NOPAR:
case NOVAL:
case BADPAR:
case SETRNG:
case DEVERROR:
return DEVFAULT;
break;
case SOFTTIM:
case FPGATIM:
case ADDRMIS:
return DEVREDO;
break;
case TIMEOUT:
for(i = 0; i < 10; i++){
iRet = availableRS232(pMe->controller);
dataLen = 70;
if(iRet == 1){
readRS232(pMe->controller, buffer,&dataLen);
}
}
return DEVREDO;
break;
default:
SLSClose(self);
iRet = SLSInit(self);
if(iRet)
{
return DEVREDO;
}
else
{
return DEVFAULT;
}
break;
}
}
/*--------------------------------------------------------------------------*/
static int SLSHalt(pEVDriver *self)
{
assert(self);
return 1;
}
/*------------------------------------------------------------------------*/
static void KillSLS(void *pData)
{
pSLSDriv pMe = NULL;
pMe = (pSLSDriv)pData;
assert(pMe);
free(pMe);
}
/*------------------------------------------------------------------------*/
pEVDriver CreateSLSVMEDriv(int argc, char *argv[])
{
pEVDriver pNew = NULL;
pSLSDriv pSim = NULL;
/* check for arguments */
if(argc < 2)
{
return NULL;
}
pNew = CreateEVDriver(argc,argv);
pSim = (pSLSDriv)malloc(sizeof(SLSDriv));
memset(pSim,0,sizeof(SLSDriv));
if(!pNew || !pSim)
{
return NULL;
}
pNew->pPrivate = pSim;
pNew->KillPrivate = KillSLS;
pSim->controller = FindCommandData(pServ->pSics, argv[0],"RS232 Controller");
if(pSim->controller == NULL){
return NULL;
}
pSim->iNum = atoi(argv[1]);
/* initialise function pointers */
pNew->SetValue = SLSRun;
pNew->GetValue = GetSLSPos;
pNew->Send = SLSSend;
pNew->GetError = SLSError;
pNew->TryFixIt = SLSFix;
pNew->Init = SLSInit;
pNew->Close = SLSClose;
return pNew;
}

62
vmemaggi.h Normal file
View File

@ -0,0 +1,62 @@
/**
* This file contaisn some data structure definitions and constants
* for the VME-MAGII program. For more information see vmemaggi.c
*
* copyright: GPL
*
* Mark Koennecke, March 2008
*/
#ifndef VMEMAGGI
#define VMEMAGGI
#define SLOTBASE 0x1000 /* change when Hitec in different VME slot */
#define MAPREG 0x424
/**
* VME has several completely different address ranges:
* one 16 bit wide accessed through device node vme4l_a16d16
* one 24 bit wide accessed through device node vme4l_a24d16
* The sharc lives in the address range of the 24 bit bus.
*/
#define VMEDEV "/dev/vme4l_a16d16"
#define MODSIZE 0x100
typedef volatile unsigned char REG8BIT;
typedef volatile unsigned short REG16BIT;
struct PSCreg {
REG16BIT stat_and_addr;
REG16BIT data_hi;
REG16BIT data_lo;
REG16BIT not_used;
} ;
/* Bits of return status of the stat_and_addr word */
#define PSC_REPLY_ERROR 0x20000
#define PSC_STATUS_REPLY_READFLAG 0x8000
#define PSC_STATUS_REPLY_FLAG_MISMATCH 0x4000
#define PSC_STATUS_REPLY_BUFFERFULL 0x2000
#define PSC_STATUS_REPLY_DSP_STOPPED 0x1000 /* disabled */
#define PSC_STATUS_REPLY_PS_LOCAL 0x0800
#define PSC_STATUS_REPLY_LINK_DOWN 0x0400
#define PSC_STATUS_REPLY_ADDR_MISMATCH 0x0080
#define PSC_STATUS_REPLY_DATA_MISMATCH 0x0040
#define PSC_STATUS_REPLY_SOFTTIMEOUT 0x0020
#define PSC_STATUS_REPLY_FPGATIMEOUT 0x0010
#define PSC_STATUS_REPLY_STRLEN 256
/* error codes */
#define BADSLOT 70
#define BADMAP 71
#define DSPSTOP 72
#define LINKDWN 73
#define SOFTTIM 74
#define FPGATIM 75
#define ADDRMIS 76
#define MISPS 77
#define PSRNG 78
#define NOPAR 79
#define NOVAL 80
#define BADPAR 81
#define SETRNG 82
#endif