/*------------------------------------------------------------------------- A motor driver for EL734 DC motors as used at SinQ Mark Koennecke, November 1996 Original code foe EL734 stepper, modified for DC motors, the 11-June-1997 Mark Koennecke Copyright: Labor fuer Neutronenstreuung Paul Scherrer Institut CH-5423 Villigen-PSI The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ------------------------------------------------------------------------------*/ #include #include #include #include #include #include "modriv.h" #include "hardsup/sinq_prototypes.h" #include "hardsup/rs232c_def.h" #include "hardsup/el734_def.h" #include "hardsup/el734fix.h" #include #include #include static int EL734EncodeMSR(char *text, int iLen, int iMSR, int iOMSR, int iFP, int iFR); static int EL734AnalyzeMSR(int iMSR, int iOMSR); /* addional error codes for Status-things */ #define MSRBUSY -40 #define MSRONLIMIT -41 #define MSRRUNFAULT -42 #define MSRPOSFAULT -43 #define MSRDEADCUSHION -44 #define MSRHALT -45 #define MSRSTOP -46 #define MSROK -47 #define MSRREF -48 #define MSRFAULT -49 /*----------------------------------------------------------------------- The motor driver structure. Please note that the first set of fields has be identical with the fields of AbstractModriv in ../modriv.h ------------------------------------------------------------------------*/ typedef struct __MoDriv { /* general motor driver interface fields. REQUIRED! */ float fUpper; /* upper limit */ float fLower; /* lower limit */ char *name; int (*GetPosition)(void *self,float *fPos); int (*RunTo)(void *self, float fNewVal); int (*GetStatus)(void *self); void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen); int (*TryAndFixIt)(void *self,int iError, float fNew); int (*Halt)(void *self); int (*GetDriverPar)(void *self, char *name, float *value); int (*SetDriverPar)(void *self,SConnection *pCon, char *name, float newValue); void (*ListDriverPar)(void *self, char *motorName, SConnection *pCon); void (*KillPrivate)(void *self); /* EL-734 specific fields */ int iPort; char *hostname; int iChannel; int iMotor; void *EL734struct; int iMSR; } EL734Driv; /* --------------------------------------------------------------------------*/ static int GetPos(void *self, float *fData) { EL734Driv *pDriv; float fPos; int iRet, iMSR, iOMSR, iFRC,iFPC, iSS; assert(self); pDriv = (EL734Driv *)self; iRet = EL734_GetStatus(&(pDriv->EL734struct), &iMSR, &iOMSR, &iFPC, &iFRC, &iSS, &fPos); if(iMSR != 0) { pDriv->iMSR = iMSR; } *fData = fPos; if(iRet != 1) { return HWFault; } else return OKOK; } /*--------------------------------------------------------------------------*/ static int Run(void *self, float fNew) { EL734Driv *pDriv; int iRet; assert(self); pDriv = (EL734Driv *)self; iRet = EL734_MoveNoWait (&(pDriv->EL734struct), fNew); if(iRet == 1) { return OKOK; } else { return HWFault; } } /*--------------------------------------------------------------------------- EL734Error2Text converts between an EL734 error code to text -----------------------------------------------------------------------------*/ static void EL734Error2Text(char *pBuffer, int iErr) { strcpy(pBuffer,"ERROR: HW:"); switch(iErr) { case EL734__BAD_ADR: strcat(pBuffer,"EL734__BAD_ADR"); break; case EL734__BAD_BIND: strcat(pBuffer,"EL734__BAD_BIND"); break; case EL734__BAD_CMD: strcat(pBuffer,"EL734__BAD_CMD"); break; case EL734__BAD_CONNECT: strcat(pBuffer,"EL734__BAD_CONNECT"); break; case EL734__BAD_FLUSH: strcat(pBuffer,"EL734__BAD_FLUSH"); break; case EL734__BAD_HOST: strcat(pBuffer,"EL734__BAD_HOST"); break; case EL734__BAD_ID: strcat(pBuffer,"EL734__BAD_ID"); break; case EL734__BAD_ILLG: strcat(pBuffer,"EL734__BAD_ILLG"); break; case EL734__BAD_LOC: strcat(pBuffer,"EL734__BAD_LOC"); break; case EL734__BAD_MALLOC: strcat(pBuffer,"EL734__BAD_MALLOC"); break; case EL734__BAD_NOT_BCD: strcat(pBuffer,"EL734__BAD_NOT_BCD"); break; case EL734__BAD_OFL: strcat(pBuffer,"EL734__BAD_OFL"); break; case EL734__BAD_PAR: strcat(pBuffer,"EL734__BAD_PAR"); break; case EL734__BAD_RECV: strcat(pBuffer,"EL734__BAD_RECV"); break; case EL734__BAD_RECV_NET: strcat(pBuffer,"EL734__BAD_RECV_NET"); break; case EL734__BAD_RECV_PIPE: strcat(pBuffer,"EL734__BAD_RECV_PIPE"); break; case EL734__BAD_RECV_UNKN: strcat(pBuffer,"EL734__BAD_RECV_UNKN"); break; case EL734__BAD_RECVLEN: strcat(pBuffer,"EL734__BAD_RECVLEN"); break; case EL734__BAD_RECV1: strcat(pBuffer,"EL734__BAD_RECV1"); break; case EL734__BAD_RECV1_NET: strcat(pBuffer,"EL734__BAD_RECV1_NET"); break; case EL734__BAD_RECV1_PIPE: strcat(pBuffer,"EL734__BAD_RECV1_PIPE"); break; case EL734__BAD_RNG: strcat(pBuffer,"EL734__BAD_RNG"); break; case EL734__BAD_SEND: strcat(pBuffer,"EL734__BAD_SEND"); break; case EL734__BAD_SEND_PIPE: strcat(pBuffer,"EL734__BAD_SEND_PIPE"); break; case EL734__BAD_SEND_NET: strcat(pBuffer,"EL734__BAD_SEND_NET"); break; case EL734__BAD_SEND_UNKN: strcat(pBuffer,"EL734__BAD_SEND_UNKN"); break; case EL734__BAD_SENDLEN: strcat(pBuffer,"EL734__BAD_SENDLEN"); break; case EL734__BAD_SOCKET: strcat(pBuffer,"EL734__BAD_SOCKET"); break; case EL734__BAD_TMO: strcat(pBuffer,"EL734__BAD_TMO"); break; case EL734__FORCED_CLOSED: strcat(pBuffer,"EL734__FORCED_CLOSED"); break; case EL734__BAD_STP: strcat(pBuffer,"EL734__BAD_STP"); break; case EL734__EMERG_STOP: strcat(pBuffer,"EL734__EMERG_STOP"); break; case EL734__NOT_OPEN: strcat(pBuffer,"EL734__NOT_OPEN"); break; case EL734__BAD_ASYNSRV: strcat(pBuffer,"EL734__BAD_ASYNSRV"); break; default: sprintf(pBuffer,"Unknown EL734 error %d", iErr); break; } } /*-------------------------------------------------------------------------*/ static void GetErr(void *self, int *iCode, char *buffer, int iBufLen) { EL734Driv *pDriv; char pBueffel[512]; int iMSR, iOMSR, iSS; int iRet, iFPC, iFRC; int iErr; float fPos; char *pErr; assert(self); /* get EL734 error codes */ pDriv = (EL734Driv *)self; EL734_ErrInfo(&pErr,&iMSR,&iOMSR, &iSS); if(iMSR != 0) { EL734Error2Text(pBueffel,iMSR); strncpy(buffer,pBueffel,(iBufLen-1)); *iCode = iMSR; return; } else { /* check status flag for addional errors */ iRet = EL734_GetStatus(&(pDriv->EL734struct), &iMSR, &iOMSR, &iFPC, &iFRC, &iSS, &fPos); if(iRet != 1) { /* failure on this one, this has to be handled */ EL734_ErrInfo(&pErr,&iMSR,&iOMSR, &iSS); EL734Error2Text(pBueffel,iMSR); strncpy(buffer,pBueffel,(iBufLen-1)); *iCode = iMSR; return; } else { /* we really come down to looking at status flags */ *iCode = EL734EncodeMSR(buffer,iBufLen,iMSR, iOMSR,iFPC,iFRC); } } } /* ------------------------------------------------------------------------ Types of errors possible on EL734: Network error: Try reopening connection and redo command. Than there are problems which might have to do with a dodgy RS232, resend command may help Some things cannot be fixed. */ static int FixError(void *self, int iError, float fNew) { EL734Driv *pDriv; int iRet; char pBueffel[512]; int iMSR, iOMSR, iSS; float fPos; assert(self); pDriv = (EL734Driv *)self; sprintf(pBueffel,"EL734 : %s %d %d %d Problem:",pDriv->hostname, pDriv->iPort, pDriv->iChannel, pDriv->iMotor); /* get & check MSR flags */ /* check for codes */ switch(iError) { case 0: /* no error at all */ return MOTOK; case EL734__BAD_ID: /* ID */ case EL734__BAD_ADR: /* ADR */ case EL734__BAD_CMD: /* CMD */ case EL734__BAD_ILLG: /* ILLG */ case EL734__BAD_PAR: /* PAR */ case EL734__BAD_TMO: SICSLogWrite(pBueffel,eHWError); SICSLogWrite("BAD Command or dodgy RS-232",eHWError); return MOTREDO; case EL734__EMERG_STOP: return MOTFAIL; case EL734__BAD_RNG: /* RNG */ case MSRONLIMIT: SICSLogWrite(pBueffel,eHWError); SICSLogWrite("Out of Range",eHWError); return MOTFAIL; case EL734__BAD_STP: return MOTFAIL; break; case MSRBUSY: return MOTREDO; case MSRRUNFAULT: SICSLogWrite(pBueffel,eHWError); SICSLogWrite("------ RUN Fault in Controller ---- ",eHWError); return MOTFAIL; case MSRPOSFAULT: SICSLogWrite(pBueffel,eHWError); SICSLogWrite("------ POS Fault in Controller ---- ",eHWError); return MOTFAIL; case MSRDEADCUSHION: SICSLogWrite(pBueffel,eHWError); SICSLogWrite("------ Air cushion Fault in Controller ---- ",eHWError); return MOTFAIL; case MSRFAULT: return MOTFAIL; case MSRHALT: case MSRSTOP: return MOTFAIL; case EL734__FORCED_CLOSED: case EL734__NOT_OPEN: iRet = EL734_Open(&(pDriv->EL734struct),pDriv->hostname, pDriv->iPort,pDriv->iChannel, pDriv->iMotor,"DCMC EL734"); if(iRet != 1) { return MOTFAIL; } else { return MOTREDO; } break; case EL734__BAD_LOC: /* LO2 */ case EL734__BAD_OFL: EL734_Close(&(pDriv->EL734struct),0); iRet = EL734_Open(&(pDriv->EL734struct),pDriv->hostname, pDriv->iPort,pDriv->iChannel, pDriv->iMotor,"DCMC EL734"); if(iRet != 1) { return MOTFAIL; } else { return MOTREDO; } break; /* case EL734__BAD_ASYNSRV: EL734_Close(&(pDriv->EL734struct),1); return MOTREDO; break; */ default: SICSLogWrite(pBueffel,eHWError); SICSLogWrite("Network problem, trying to reopen",eHWError); EL734_Close(&(pDriv->EL734struct),1); iRet = EL734_Open(&(pDriv->EL734struct),pDriv->hostname, pDriv->iPort,pDriv->iChannel, pDriv->iMotor,"DCMC EL734"); if(iRet != 1) { return MOTFAIL; } else { return MOTREDO; } } } /*--------------------------------------------------------------------------*/ static int Halt(void *self) { EL734Driv *pDriv; int iRet; char pBueffel[80]; assert(self); pDriv = (EL734Driv *)self; iRet = EL734_Stop(&(pDriv->EL734struct)); if(iRet != 1) { return OKOK; } return HWFault; } /*--------------------------------------------------------------------------*/ static int GetStat(void *self) { EL734Driv *pDriv; float fPos; int iRet, iMSR, iOMSR, iFRC,iFPC, iSS; int eRet; int iTest; char pBueffel[80]; assert(self); pDriv = (EL734Driv *)self; iRet = EL734_GetStatus(&(pDriv->EL734struct), &iMSR, &iOMSR, &iFPC, &iFRC, &iSS, &fPos); if(iRet != 1) { return HWFault; } if(iMSR != 0) { pDriv->iMSR = iMSR; } iTest = EL734AnalyzeMSR(iMSR,iOMSR); switch(iTest) { case MSRDEADCUSHION: case MSRONLIMIT: case MSRREF: case MSRHALT: case MSRSTOP: return HWFault; break; case MSRRUNFAULT: case MSRPOSFAULT: return HWPosFault; break; case MSRBUSY: return HWBusy; break; case MSRFAULT: return HWWarn; break; default: return HWIdle; break; } } /*--------------------------------------------------------------------------*/ extern void KillEL734(void *pdata); /* from el734driv.c */ /*---------------------------------------------------------------------------*/ static EL734Driv *MakeEL734DC(char *hostname, int iPort, int iChannel, int iMotor) { EL734Driv *pDriv = NULL; int iError; char pBueffel[80]; char *pErr; int iRet; int iDummy; /* create a new struct */ pDriv = (EL734Driv *)malloc(sizeof(EL734Driv)); if(!pDriv) { return NULL; } memset(pDriv,0,sizeof(EL734Driv)); /* fill in some of the data entered */ pDriv->hostname = strdup(hostname); pDriv->iPort = iPort; pDriv->iChannel = iChannel; pDriv->iMotor = iMotor; pDriv->name = strdup("EL734"); /* try opening the motor */ iRet = EL734_Open(&(pDriv->EL734struct), hostname,iPort, iChannel,iMotor,"DCMC EL734"); if(iRet != 1) { EL734_ErrInfo(&pErr,&iError,&iRet, &iDummy); KillEL734((void *)pDriv); return NULL; } /* now get the limits */ EL734_GetLimits(&(pDriv->EL734struct),&(pDriv->fLower), &(pDriv->fUpper)); /* initialise the function pointers */ pDriv->GetPosition = GetPos; pDriv->RunTo = Run; pDriv->GetError = GetErr; pDriv->GetStatus = GetStat; pDriv->Halt = Halt; pDriv->TryAndFixIt = FixError; pDriv->KillPrivate = KillEL734; return pDriv; } /*-------------------------------------------------------------------------- interpreting the driver parameters is up to the driver, this below inplements just this */ MotorDriver *CreateEL734DC(SConnection *pCon, int argc, char *argv[]) { EL734Driv *pDriv = NULL; TokenList *pList = NULL; TokenList *pCurrent; char *hostname; int iPort, iChannel, iMotor; char pBueffel[512]; assert(pCon); /* split arguments */ pList = SplitArguments(argc,argv); if(!pList) { SCWrite(pCon,"Error parsing arguments",eError); return NULL; } /* first must be hostname */ pCurrent = pList; if(pCurrent->Type != eText) { sprintf(pBueffel,"EL734DC: Expected hostname but got --> %s <--", pCurrent->text); SCWrite(pCon,pBueffel,eError); DeleteTokenList(pList); return NULL; } hostname = pCurrent->text; /* next should be port */ pCurrent = pCurrent->pNext; if(!pCurrent) { SCWrite(pCon,"EL734DC: Insufficient number of arguments",eError); DeleteTokenList(pList); return NULL; } if(pCurrent->Type != eInt) { sprintf(pBueffel,"EL734DC: Expected Integer as Port number, got --> %s <--", pCurrent->text); SCWrite(pCon,pBueffel,eError); DeleteTokenList(pList); return NULL; } iPort = pCurrent->iVal; /* next should be Channel number */ pCurrent = pCurrent->pNext; if(!pCurrent) { SCWrite(pCon,"EL734DC: Insufficient number of arguments",eError); DeleteTokenList(pList); return NULL; } if(pCurrent->Type != eInt) { sprintf(pBueffel,"EL734DC: Expected Integer as channel number, got --> %s <--", pCurrent->text); SCWrite(pCon,pBueffel,eError); DeleteTokenList(pList); return NULL; } iChannel = pCurrent->iVal; /* finally motor number */ pCurrent = pCurrent->pNext; if(!pCurrent) { SCWrite(pCon,"EL734DC: Insufficient number of arguments",eError); DeleteTokenList(pList); return NULL; } if(pCurrent->Type != eInt) { sprintf(pBueffel,"EL734DC: Expected Integer as motor number, got --> %s <--", pCurrent->text); SCWrite(pCon,pBueffel,eError); DeleteTokenList(pList); return NULL; } iMotor = pCurrent->iVal; /* finally initialize driver */ pDriv = MakeEL734DC(hostname,iPort,iChannel,iMotor); if(!pDriv) { SCWrite(pCon,"EL734DC: error opening motor, check adress",eError); pDriv = NULL; } /* clean up */ DeleteTokenList(pList); return (MotorDriver *)pDriv; } /*------------------------------------------------------------------------- Stolen from David and modified to return an integer error code as well */ static int EL734EncodeMSR (char *text, int text_len, int msr, int ored_msr, int fp_cntr, int fr_cntr) { int len; char my_text[132]; char my_text_0[32]; int iRet = 0; if (msr == 0) { ored_msr = ored_msr & ~(MSR__BUSY); /* Zero "Busy" bit */ if (ored_msr == MSR__OK) { StrJoin (text, text_len, "Status, MSR = Idle. Positioned OK.", ""); }else { if ((ored_msr & MSR__OK) != 0) { StrJoin (text, text_len, "Status, MSR = Idle. Positioned OK. ", ""); }else { StrJoin (text, text_len, "Status, MSR = Idle. ", ""); } if ((ored_msr & MSR__REF_OK) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n OK. "); } if ((ored_msr & MSR__LIM_ERR) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Limit Switch Problem. "); iRet = MSRONLIMIT; } if ((ored_msr & MSR__AC_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Air-Cushion Error. "); iRet = MSRDEADCUSHION; } if ((ored_msr & MSR__REF_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n Fail. "); } if ((ored_msr & MSR__POS_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Pos'n Fail. "); iRet = MSRPOSFAULT; } if ((ored_msr & MSR__POS_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); if (fp_cntr == 1) { StrJoin (text, text_len, my_text, "1 Pos'n Fault. "); }else { sprintf (my_text_0, "%d Pos'n Faults. ", fp_cntr); StrJoin (text, text_len, my_text, my_text_0); } } if ((ored_msr & MSR__RUN_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Run Fail. "); iRet = MSRRUNFAULT; } if ((ored_msr & MSR__RUN_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); if (fr_cntr == 1) { StrJoin (text, text_len, my_text, "1 Run Fault. "); }else { sprintf (my_text_0, "%d Run Faults. ", fr_cntr); StrJoin (text, text_len, my_text, my_text_0); } } if ((ored_msr & MSR__HALT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Halt. "); iRet = MSRHALT; } if ((ored_msr & MSR__HI_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit HiLim. "); iRet = MSRONLIMIT; } if ((ored_msr & MSR__LO_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit LoLim. "); iRet = MSRONLIMIT; } if ((ored_msr & MSR__STOPPED) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Stopped. "); iRet = MSRSTOP; } } }else if ((msr & ~(0x2fff)) != 0) { StrJoin (text, text_len, "Status, MSR = ??", ""); }else { sprintf (my_text, "%#x ", msr); StrJoin (text, text_len, "Status, MSR = ", my_text); if ((msr & MSR__LIM_ERR) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Limit Switch Problem/"); iRet = MSRONLIMIT; } if ((msr & MSR__AC_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Air-Cushion Error/"); iRet = MSRDEADCUSHION; } if ((msr & MSR__REF_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n Fail/"); } if ((msr & MSR__POS_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Pos'n Fail/"); iRet = MSRPOSFAULT; } if ((msr & MSR__POS_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Pos'n Fault/"); } if ((msr & MSR__RUN_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Run Fail/"); iRet = MSRRUNFAULT; } if ((msr & MSR__RUN_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Run Fault/"); } if ((msr & MSR__HALT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Halt/"); iRet = MSRHALT; } if ((msr & MSR__HI_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit HiLim/"); iRet = MSRONLIMIT; } if ((msr & MSR__LO_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit LoLim/"); iRet = MSRONLIMIT; } if ((msr & MSR__STOPPED) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Stopped/"); iRet = MSRSTOP; } if ((msr & MSR__REF_OK) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n OK/"); } if ((msr & MSR__OK) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "OK/"); } if ((msr & MSR__BUSY) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Busy/"); } len = strlen (text); text[len-1] = '\0'; } return iRet; } /*-------------------------------------------------------------------------*/ static int EL734AnalyzeMSR(int msr,int ored_msr) { int iRet = 0; /* this means the motor is done */ if (msr == 0) { ored_msr = ored_msr & ~(MSR__BUSY); /* Zero "Busy" bit */ if (ored_msr == MSR__OK) { iRet = MSROK; }else { if ((ored_msr & MSR__OK) != 0) { iRet = MSROK; }else { iRet = MSROK; } if ((ored_msr & MSR__REF_OK) != 0) { iRet = MSROK; } if ((ored_msr & MSR__LIM_ERR) != 0) { return MSRONLIMIT; } if ((ored_msr & MSR__AC_FAIL) != 0) { return MSRDEADCUSHION; } if ((ored_msr & MSR__REF_FAIL) != 0) { iRet = MSRREF; } if ((ored_msr & MSR__POS_FAIL) != 0) { return MSRPOSFAULT; } if ((ored_msr & MSR__POS_FAULT) != 0) { iRet = MSRFAULT; } if ((ored_msr & MSR__RUN_FAIL) != 0) { return MSRRUNFAULT; } if ((ored_msr & MSR__RUN_FAULT) != 0) { iRet = MSRFAULT; } if ((ored_msr & MSR__HALT) != 0) { return MSRHALT; } if ((ored_msr & MSR__HI_LIM) != 0) { return MSRONLIMIT; } if ((ored_msr & MSR__LO_LIM) != 0) { return MSRONLIMIT; } if ((ored_msr & MSR__STOPPED) != 0) { return MSRSTOP; } } /* the motor is still fighting along */ }else if ((msr & ~(0x2fff)) != 0) { iRet = MSROK; }else { if ((msr & MSR__LIM_ERR) != 0) { return MSRONLIMIT; } if ((msr & MSR__AC_FAIL) != 0) { return MSRDEADCUSHION; } if ((msr & MSR__REF_FAIL) != 0) { iRet = MSRREF; } if ((msr & MSR__POS_FAIL) != 0) { return MSRPOSFAULT; } if ((msr & MSR__POS_FAULT) != 0) { iRet = MSRFAULT; } if ((msr & MSR__RUN_FAIL) != 0) { return MSRRUNFAULT; } if ((msr & MSR__RUN_FAULT) != 0) { iRet = MSRFAULT; } if ((msr & MSR__HALT) != 0) { return MSRHALT; } if ((msr & MSR__HI_LIM) != 0) { return MSRONLIMIT; } if ((msr & MSR__LO_LIM) != 0) { return MSRONLIMIT; } if ((msr & MSR__STOPPED) != 0) { return MSRSTOP; } if ((msr & MSR__REF_OK) != 0) { iRet = MSROK; } if ((msr & MSR__OK) != 0) { iRet = MSROK; } if ((msr & MSR__BUSY) != 0) { iRet = MSRBUSY; } } return iRet; }