- Rearranged directory structure for forking out ANSTO
- Refactored site specific stuff into a site module - PSI specific stuff is now in the PSI directory. - The old version has been tagged with pre-ansto
This commit is contained in:
210
velodorn.c
Normal file
210
velodorn.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
|
||||
V E L O D O R N
|
||||
|
||||
Utility functions for talking to a Dornier velocity selector in the
|
||||
SINQ setup.
|
||||
|
||||
Mark Koennecke, Juli 1997
|
||||
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <sics.h>
|
||||
#include <fortify.h>
|
||||
#include "hardsup/sinq_prototypes.h"
|
||||
#include "velodorn.h"
|
||||
#include "hardsup/serialsinq.h"
|
||||
#include <serialwait.h>
|
||||
|
||||
#define TOK_BUF_L 25
|
||||
/*--------------------------- analyse Dornier status string ----------------*/
|
||||
int AnalyseDornierStatus(char *pText, pDornierStatus pResult)
|
||||
{
|
||||
int cnt, key_id, sl, sts;
|
||||
long err;
|
||||
char ena_str[] = "ENABLED";
|
||||
char dis_str[] = "DISABLED";
|
||||
char keys[16][9] =
|
||||
{
|
||||
"Status:\0 ",
|
||||
"S_DREH:\0 ",
|
||||
"I_DREH:\0 ",
|
||||
"P_VERL:\0 ",
|
||||
"STROM:\0 ",
|
||||
"T_ROT:\0 ",
|
||||
"T_GEH:\0 ",
|
||||
"T_VOR:\0 ",
|
||||
"T_RUECK:\0",
|
||||
"DURCHFL:\0",
|
||||
"VAKUUM:\0 ",
|
||||
"BESCHL:\0 ",
|
||||
"KOM: \0 ",
|
||||
"DATE: \0 ",
|
||||
"TIME: \0 ",
|
||||
"Hz:\0 "};
|
||||
|
||||
char tok_buf[TOK_BUF_L], *ptr_token, *ptr_src, *ptr;
|
||||
const char tok_c[] = "/\\\0";
|
||||
char status[255];
|
||||
|
||||
ptr_src = pText;
|
||||
memset(pResult,0,sizeof(DornierStatus));
|
||||
|
||||
/* skip over first token, should be command echo */
|
||||
ptr_token = strtok(ptr_src, tok_c);
|
||||
if (ptr_token == NULL) return 0; /* error */
|
||||
strcpy(pResult->echo,(const char *)ptr_token);
|
||||
ptr_src += strlen(ptr_token);
|
||||
|
||||
ptr_src = NULL; /* necessary for further search with strtok */
|
||||
for (;;)
|
||||
{
|
||||
/* read text till next separator '/' */
|
||||
ptr_token = strtok(ptr_src, tok_c);
|
||||
if (ptr_token == NULL) break;
|
||||
strcpy(tok_buf,ptr_token);
|
||||
|
||||
for (key_id = 0; key_id<=15; key_id++)
|
||||
{
|
||||
/* search key ? */
|
||||
sl = strlen(keys[key_id]);
|
||||
if (strncmp(&keys[key_id][0], tok_buf, sl) == 0)
|
||||
{
|
||||
/* step over key */
|
||||
for (cnt=0;cnt+sl < TOK_BUF_L; cnt++)
|
||||
tok_buf[cnt] = tok_buf[cnt+sl];
|
||||
switch (key_id)
|
||||
{
|
||||
case 0: {strcpy(pResult->rm, tok_buf); break;}
|
||||
case 1: {sscanf(tok_buf,"%d",&pResult->nom_rpm); break;}
|
||||
case 2: {sscanf(tok_buf,"%d",&pResult->cur_rpm); break;}
|
||||
case 3: {sscanf(tok_buf,"%d",&pResult->pwr); break;}
|
||||
case 4: {sscanf(tok_buf,"%f",&pResult->curr); break;}
|
||||
case 5: {sscanf(tok_buf,"%d",&pResult->rot_temp); break;}
|
||||
case 6: {sscanf(tok_buf,"%d",&pResult->cont_temp); break;}
|
||||
case 7: {sscanf(tok_buf,"%d",&pResult->inl_temp); break;}
|
||||
case 8: {sscanf(tok_buf,"%d",&pResult->outl_temp); break;}
|
||||
case 9: {sscanf(tok_buf,"%f",&pResult->cool_wat); break;}
|
||||
case 10: {sscanf(tok_buf,"%f",&pResult->vacuum); break;}
|
||||
case 11: {sscanf(tok_buf,"%f",&pResult->accel); break;}
|
||||
case 12: {
|
||||
if (strcmp(tok_buf, ena_str) == 0)
|
||||
{pResult->komm = 1; break;}
|
||||
if (strcmp(tok_buf, dis_str) == 0)
|
||||
{pResult->komm = 0;break;}
|
||||
break;
|
||||
}
|
||||
case 13: break; /* date */
|
||||
case 14: break; /* time */
|
||||
case 15: {sscanf(tok_buf,"%d",&pResult->iHz); break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int DornierSend(void **pData, char *pCommand, char *pReply, int iRepLen)
|
||||
{
|
||||
char pOldCom[10];
|
||||
char *pPtr;
|
||||
int iRet;
|
||||
|
||||
/* first copy the command send out, in order to test for echo */
|
||||
pPtr = pCommand;
|
||||
memset(pOldCom,0,10);
|
||||
while( isspace(*pPtr) && (*pPtr != '\0') )
|
||||
{
|
||||
pPtr++;
|
||||
}
|
||||
if(*pPtr == '\0') /* no command */
|
||||
{
|
||||
return NOCOMMAND;
|
||||
}
|
||||
strncpy(pOldCom,pPtr,3);
|
||||
|
||||
iRet = SerialWriteRead(pData, pCommand, pReply, iRepLen);
|
||||
/*
|
||||
iRet = SerialSicsExecute(pData,pCommand,pReply,iRepLen);
|
||||
*/
|
||||
if(iRet != 1)
|
||||
{
|
||||
return iRet; /* an error ocurred */
|
||||
}
|
||||
|
||||
/* try to find command in the reply */
|
||||
pPtr = strstr(pReply,pOldCom);
|
||||
if(pPtr == NULL)
|
||||
{
|
||||
SICSLogWrite("Velocity Selector: Bad Reply:",eError);
|
||||
SICSLogWrite(pReply,eError);
|
||||
return ECHOMISSING;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int GetDornierStatus(void **pData, pDornierStatus pDornier)
|
||||
{
|
||||
char pCommand[10] = {"???"};
|
||||
char pReply[256];
|
||||
int iRet;
|
||||
|
||||
/* send command */
|
||||
iRet = DornierSend(pData,pCommand,pReply,255);
|
||||
if(iRet < 0 )
|
||||
{
|
||||
return iRet;
|
||||
}
|
||||
if(strlen(pReply) < 100)
|
||||
{
|
||||
SICSLogWrite("Velocity Selector: Bad Reply:",eError);
|
||||
SICSLogWrite(pReply,eError);
|
||||
return INVALIDSTATUS;
|
||||
}
|
||||
|
||||
|
||||
/* analyse reply */
|
||||
iRet = AnalyseDornierStatus(pReply,pDornier);
|
||||
if(!iRet)
|
||||
{
|
||||
return BADANALYSIS;
|
||||
}
|
||||
if(pDornier->cur_rpm > 70000)
|
||||
{
|
||||
printf("Shitty status reply: %s detected \n",pReply);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user