From bb37ab49f8bb66d4f71ea3e6f1f832d5d6cf890b Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 2 Feb 2000 19:43:38 +0000 Subject: [PATCH] osiClock;osiwatchdog => callbackRequestDelayed --- src/rec/Makefile | 6 - src/rec/boRecord.c | 52 +- src/rec/calcoutRecord.c | 33 +- src/rec/histogramRecord.c | 52 +- src/rec/palRecord.c | 228 -------- src/rec/palRecord.dbd | 323 ----------- src/rec/seqRecord.c | 93 ++-- src/rec/steppermotorRecord.c | 955 --------------------------------- src/rec/steppermotorRecord.dbd | 307 ----------- 9 files changed, 87 insertions(+), 1962 deletions(-) delete mode 100644 src/rec/palRecord.c delete mode 100644 src/rec/palRecord.dbd delete mode 100644 src/rec/steppermotorRecord.c delete mode 100644 src/rec/steppermotorRecord.dbd diff --git a/src/rec/Makefile b/src/rec/Makefile index 179bfe11f..326c7f077 100644 --- a/src/rec/Makefile +++ b/src/rec/Makefile @@ -31,16 +31,13 @@ RECTYPES += mbbiRecord.h RECTYPES += mbbiDirectRecord.h RECTYPES += mbboRecord.h RECTYPES += mbboDirectRecord.h -RECTYPES += palRecord.h RECTYPES += permissiveRecord.h -RECTYPES += pidRecord.h RECTYPES += pulseCounterRecord.h RECTYPES += pulseDelayRecord.h RECTYPES += pulseTrainRecord.h RECTYPES += selRecord.h RECTYPES += seqRecord.h RECTYPES += stateRecord.h -RECTYPES += steppermotorRecord.h RECTYPES += stringinRecord.h RECTYPES += stringoutRecord.h RECTYPES += subRecord.h @@ -72,16 +69,13 @@ OBJS_IOC += mbbiRecord.o OBJS_IOC += mbbiDirectRecord.o OBJS_IOC += mbboRecord.o OBJS_IOC += mbboDirectRecord.o -OBJS_IOC += palRecord.o OBJS_IOC += permissiveRecord.o -OBJS_IOC += pidRecord.o OBJS_IOC += pulseCounterRecord.o OBJS_IOC += pulseDelayRecord.o OBJS_IOC += pulseTrainRecord.o OBJS_IOC += selRecord.o OBJS_IOC += seqRecord.o OBJS_IOC += stateRecord.o -#OBJS_IOC += steppermotorRecord.o OBJS_IOC += stringinRecord.o OBJS_IOC += stringoutRecord.o OBJS_IOC += subRecord.o diff --git a/src/rec/boRecord.c b/src/rec/boRecord.c index 7c2a36368..358fa3cfd 100644 --- a/src/rec/boRecord.c +++ b/src/rec/boRecord.c @@ -74,8 +74,6 @@ #include #include "dbDefs.h" -#include "osiWatchdog.h" -#include "osiClock.h" #include "epicsPrint.h" #include "alarm.h" #include "callback.h" @@ -141,35 +139,29 @@ struct bodset { /* binary output dset */ /* control block for callback*/ -struct callback { +typedef struct myCallback { CALLBACK callback; struct dbCommon *precord; - watchdogId wd_id; -}; +}myCallback; static void alarm(); static void monitor(); static long writeValue(); -void callbackRequest(); - -static void myCallback(pcallback) - struct callback *pcallback; +static void myCallbackFunc(CALLBACK *arg) { + myCallback *pcallback; + struct boRecord *pbo; - struct boRecord *pbo=(struct boRecord *)pcallback->precord; - int wait_time; - + callbackGetUser(pcallback,arg); + pbo=(struct boRecord *)pcallback->precord; dbScanLock((struct dbCommon *)pbo); if(pbo->pact) { - wait_time = (int)(pbo->high * clockGetRate()); - if (pbo->val==1 && wait_time>0) { - struct callback *pcallback; - pcallback = (struct callback *)(pbo->rpvt); - if(pcallback->wd_id==NULL) pcallback->wd_id = watchdogCreate(); - callbackSetPriority(pbo->prio, &pcallback->callback); - watchdogStart(pcallback->wd_id, wait_time, - (WATCHDOGFUNC)callbackRequest, (void *)pcallback); + if((pbo->val==1) && (pbo->high>0)){ + myCallback *pcallback; + pcallback = (myCallback *)(pbo->rpvt); + callbackSetPriority(pbo->prio, &pcallback->callback); + callbackRequestDelayed(&pcallback->callback,(double)pbo->high); } } else { pbo->val = 0; @@ -184,7 +176,7 @@ static long init_record(pbo,pass) { struct bodset *pdset; long status=0; - struct callback *pcallback; + myCallback *pcallback; if (pass==0) return(0); @@ -213,9 +205,10 @@ static long init_record(pbo,pass) } } - pcallback = (struct callback *)(calloc(1,sizeof(struct callback))); + pcallback = (myCallback *)(calloc(1,sizeof(myCallback))); pbo->rpvt = (void *)pcallback; - callbackSetCallback(myCallback,&pcallback->callback); + callbackSetCallback(myCallbackFunc,&pcallback->callback); + callbackSetUser(pcallback,&pcallback->callback); pcallback->precord = (struct dbCommon *)pbo; if( pdset->init_record ) { @@ -304,14 +297,11 @@ static long process(pbo) pbo->pact = TRUE; recGblGetTimeStamp(pbo); - wait_time = (int)(pbo->high * clockGetRate()); - if (pbo->val==1 && wait_time>0) { - struct callback *pcallback; - pcallback = (struct callback *)(pbo->rpvt); - if(pcallback->wd_id==0) pcallback->wd_id = watchdogCreate(); - callbackSetPriority(pbo->prio, &pcallback->callback); - watchdogStart(pcallback->wd_id, wait_time, - (WATCHDOGFUNC)callbackRequest, (void *)pcallback); + if((pbo->val==1) && (pbo->high>0)){ + myCallback *pcallback; + pcallback = (myCallback *)(pbo->rpvt); + callbackSetPriority(pbo->prio, &pcallback->callback); + callbackRequestDelayed(&pcallback->callback,(double)pbo->high); } /* check event list */ monitor(pbo); diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c index 8d00193e3..d56c1ad13 100644 --- a/src/rec/calcoutRecord.c +++ b/src/rec/calcoutRecord.c @@ -49,8 +49,6 @@ #include #include "alarm.h" -#include "osiWatchdog.h" -#include "osiClock.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbEvent.h" @@ -126,9 +124,7 @@ struct rset calcoutRSET={ struct rpvtStruct { CALLBACK doOutCb; - watchdogId wd_id_0; CALLBACK checkLinkCb; - watchdogId wd_id_1; short wd_id_1_LOCK; short caLinkStat; /* NO_CA_LINKS,CA_LINKS_ALL_OK,CA_LINKS_NOT_OK */ }; @@ -208,16 +204,13 @@ static long init_record(pcalc,pass) callbackSetCallback(checkLinksCallback, &prpvt->checkLinkCb); callbackSetPriority(0, &prpvt->checkLinkCb); callbackSetUser(pcalc, &prpvt->checkLinkCb); - prpvt->wd_id_0 = watchdogCreate(); - prpvt->wd_id_1 = watchdogCreate(); prpvt->wd_id_1_LOCK = 0; /* Can't do this. Sometimes initialization is not done after 1 second and then dbScanLock will complain !!! if(prpvt->caLinkStat == CA_LINKS_NOT_OK) { - watchdogStart(prpvt->wd_id_1, clockGetRate(), (WATCHDOGFUNC)callbackRequest, - (void *)(&prpvt->checkLinkCb)); + callbackRequestDelayed(&prpvt->checkLinkCb->callback,1.0); prpvt->wd_id_1_LOCK = 1; } */ @@ -289,11 +282,8 @@ static long process(pcalc) if(pcalc->odly > 0.0) { pcalc->dlya = 1; db_post_events(pcalc,&pcalc->dlya,DBE_VALUE); - wdDelay = (int)(pcalc->odly * clockGetRate()); callbackSetPriority(pcalc->prio, &prpvt->doOutCb); - watchdogStart(prpvt->wd_id_0, wdDelay, - (WATCHDOGFUNC)callbackRequest, - (void *)(&prpvt->doOutCb)); + callbackRequestDelayed(&prpvt->doOutCb,(double)pcalc->odly); } else { execOutput(pcalc); @@ -349,7 +339,6 @@ static long special(paddr,after) } db_post_events(pcalc,&pcalc->clcv,DBE_VALUE); return(0); - break; case(calcoutRecordOCAL): pcalc->oclv=postfix(pcalc->ocal,pcalc->orpc,&error_number); @@ -360,7 +349,6 @@ static long special(paddr,after) db_post_events(pcalc,&pcalc->oclv,DBE_VALUE); return(0); - break; case(calcoutRecordINPA): case(calcoutRecordINPB): @@ -396,8 +384,7 @@ static long special(paddr,after) *plinkValid = calcoutINAV_EXT_NC; /* DO_CALLBACK, if not already scheduled */ if(!prpvt->wd_id_1_LOCK) { - watchdogStart(prpvt->wd_id_1, clockGetRate()/2, (WATCHDOGFUNC)callbackRequest, - (void *)(&prpvt->checkLinkCb)); + callbackRequestDelayed(&prpvt->checkLinkCb,.5); prpvt->wd_id_1_LOCK = 1; prpvt->caLinkStat = CA_LINKS_NOT_OK; } @@ -406,7 +393,6 @@ static long special(paddr,after) return(0); - break; default: recGblDbaddrError(S_db_badChoice,paddr,"calc: special"); @@ -565,14 +551,13 @@ static void alarm(pcalc) return; } -static void doOutputCallback(pcallback) - struct callback *pcallback; +static void doOutputCallback(CALLBACK *arg) { dbCommon *pcalc; struct rset *prset; - callbackGetUser(pcalc, pcallback); + callbackGetUser(pcalc, arg); prset = (struct rset *)pcalc->rset; dbScanLock((struct dbCommon *)pcalc); (*prset->process)(pcalc); @@ -704,14 +689,13 @@ static int fetch_values(pcalc) return(0); } -static void checkLinksCallback(pcallback) - struct callback *pcallback; +static void checkLinksCallback(CALLBACK *arg) { struct calcoutRecord *pcalc; struct rpvtStruct *prpvt; - callbackGetUser(pcalc, pcallback); + callbackGetUser(pcalc, arg); prpvt = (struct rpvtStruct *)pcalc->rpvt; dbScanLock((struct dbCommon *)pcalc); @@ -769,8 +753,7 @@ static void checkLinks(pcalc) if(!prpvt->wd_id_1_LOCK && caLinkNc) { /* Schedule another CALLBACK */ prpvt->wd_id_1_LOCK = 1; - watchdogStart(prpvt->wd_id_1, clockGetRate()/2, (WATCHDOGFUNC)callbackRequest, - (void *)(&prpvt->checkLinkCb)); + callbackRequestDelayed(&prpvt->checkLinkCb,.5); } } diff --git a/src/rec/histogramRecord.c b/src/rec/histogramRecord.c index f4949a5b9..848fca28d 100644 --- a/src/rec/histogramRecord.c +++ b/src/rec/histogramRecord.c @@ -50,8 +50,6 @@ #include "dbDefs.h" #include "epicsPrint.h" -#include "osiWatchdog.h" -#include "osiClock.h" #include "alarm.h" #include "callback.h" #include "dbAccess.h" @@ -117,26 +115,23 @@ struct histogramdset { /* histogram input dset */ }; /* control block for callback*/ -struct callback { - void (*callback)(); - int priority; - struct dbAddr dbAddr; - watchdogId wd_id; -}; +typedef struct myCallback { + CALLBACK callback; + histogramRecord *phistogram; +}myCallback; -/* -void callbackRequest(); -*/ - static long add_count(); static long clear_histogram(); static void monitor(); static long readValue(); -static void wdogCallback(pcallback) - struct callback *pcallback; +static void wdogCallback(CALLBACK *arg) { - struct histogramRecord *phistogram=(struct histogramRecord *)(pcallback->dbAddr.precord); + myCallback *pcallback; + struct histogramRecord *phistogram; + + callbackGetUser(pcallback,arg); + phistogram = pcallback->phistogram; /* force post events for any count change */ if(phistogram->mcnt>0){ dbScanLock((struct dbCommon *)phistogram); @@ -148,9 +143,7 @@ static void wdogCallback(pcallback) if(phistogram->sdel>0) { /* start new watchdog timer on monitor */ - watchdogStart(pcallback->wd_id, - (int)(phistogram->sdel *clockGetRate()), - (WATCHDOGFUNC)callbackRequest,(void *)pcallback); + callbackRequestDelayed(&pcallback->callback,(double)phistogram->sdel); } return; @@ -158,30 +151,25 @@ static void wdogCallback(pcallback) static long wdogInit(phistogram) struct histogramRecord *phistogram; { - struct callback *pcallback; + myCallback *pcallback; if(phistogram->wdog==NULL && phistogram->sdel>0) { /* initialize a watchdog timer */ - pcallback = (struct callback *)(calloc(1,sizeof(struct callback))); - phistogram->wdog = (void *)pcallback; + pcallback = (myCallback *)(calloc(1,sizeof(myCallback))); + pcallback->phistogram = phistogram; if(!pcallback) return -1; - pcallback->callback = wdogCallback; - pcallback->priority = priorityLow; - pcallback->wd_id = watchdogCreate(); - dbNameToAddr(phistogram->name,&(pcallback->dbAddr)); + callbackSetCallback(wdogCallback,&pcallback->callback); + callbackSetUser(pcallback,&pcallback->callback); + callbackSetPriority(priorityLow,&pcallback->callback); + phistogram->wdog = (void *)pcallback; } if (!phistogram->wdog) return -1; - pcallback = (struct callback *)phistogram->wdog; + pcallback = (myCallback *)phistogram->wdog; if(!pcallback) return -1; - - watchdogCancel(pcallback->wd_id); - if( phistogram->sdel>0) { /* start new watchdog timer on monitor */ - watchdogStart(pcallback->wd_id, - (int)(phistogram->sdel * clockGetRate()), - (WATCHDOGFUNC)callbackRequest,(void *)pcallback); + callbackRequestDelayed(&pcallback->callback,(double)phistogram->sdel); } return 0; } diff --git a/src/rec/palRecord.c b/src/rec/palRecord.c deleted file mode 100644 index f5e40dafb..000000000 --- a/src/rec/palRecord.c +++ /dev/null @@ -1,228 +0,0 @@ -/* recPal.c */ -/* base/src/rec $Id$ */ - -/* recPal.c - Record Support Routines for Pal Emulation records */ -/* - * Original Author: Matthew Stettler - * Date: 12-02-93 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 04-19-94 mcn R3.12ified - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "recSup.h" -#include "pal.h" -#include "special.h" -#define GEN_SIZE_OFFSET -#include "palRecord.h" -#undef GEN_SIZE_OFFSET - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(); -static long process(); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(); -static long get_precision(); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -struct rset palRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double }; - -static void monitor(); -static int fetch_values(); -struct pal * palinit(); - - -#define ARG_MAX 12 -#define OUT_MAX 12 - - -static long init_record(ppal,pass) - struct palRecord *ppal; - int pass; -{ - struct link *plink; - int i; - double *pvalue; - - if (pass==0) return(0); - - plink = &ppal->inpa; - pvalue = &ppal->a; - for(i=0; itype==CONSTANT) { - recGblInitConstantLink(plink,DBF_DOUBLE,pvalue); - } - } - if ((ppal->pptr = palinit(ppal->jedf,ppal->name,&ppal->a0)) == 0) - return -1; - return(0); -} - -static long process(ppal) - struct palRecord *ppal; -{ - unsigned char *temp; - int i; - unsigned int result = 0; - - ppal->pact = TRUE; - - if (fetch_values(ppal)==0) - { - if(pal(ppal->pptr,&ppal->a,12,&result)) - printf("palrec - error, pptr = %p\n",ppal->pptr); - ppal->val = result; - ppal->udf = FALSE; - } - for (i = 0, temp = &ppal->q0; i < OUT_MAX; i++, temp++) - { - *temp = (ppal->val>>i) & 1; - /*printf("%x ",*temp);*/ - } - /*printf("\n");*/ - recGblGetTimeStamp(ppal); - /* check event list */ - monitor(ppal); - /* process the forward scan link record */ - recGblFwdLink(ppal); - ppal->pact = FALSE; - return(0); -} - -static long get_units(paddr,units) - struct dbAddr *paddr; - char *units; -{ - struct palRecord *ppal=(struct palRecord *)paddr->precord; - - strncpy(units,ppal->egu,DB_UNITS_SIZE); - return(0); -} - -static long get_precision(paddr,precision) - struct dbAddr *paddr; - long *precision; -{ - struct palRecord *ppal=(struct palRecord *)paddr->precord; - - *precision = ppal->prec; - if(paddr->pfield == (void *)&ppal->val) return(0); - recGblGetPrec(paddr,precision); - return(0); -} - -static void monitor(ppal) - struct palRecord *ppal; -{ - unsigned short monitor_mask; - double *pnew; - double *pprev; - int i; - unsigned char *temp; - - monitor_mask = recGblResetAlarms(ppal); - - /* check for value change */ - if (ppal->val != ppal->mlst) - { - monitor_mask |= DBE_VALUE; /* post events for value change */ - } - - /* send out monitors connected to the value field */ - if (monitor_mask) - { - db_post_events(ppal,&ppal->val,monitor_mask); - for (i = 0, temp = &ppal->q0; i < OUT_MAX; i++, temp++) - if (((ppal->mlst>>i) & 1) ^ *temp) /* check each bit */ - db_post_events(ppal,temp,monitor_mask); - ppal->mlst = ppal->val; /* update last value monitored */ - } - /* check all input fields for changes*/ - for(i=0, pnew=&ppal->a, pprev=&ppal->la; iinpa, pvalue=&ppal->a; iname); /* Allocate a callback structure for use in processing */ - pseq->dpvt = (void *)malloc(sizeof(struct callbackSeq)); - pcallbackSeq = (struct callbackSeq *)pseq->dpvt; - pcallbackSeq->callBack.callback = processCallback; - pcallbackSeq->callBack.user = (void *) pseq; - pcallbackSeq->wd_id = watchdogCreate(); + pcallbackSeq = (callbackSeq *)calloc(1,sizeof(callbackSeq)); + pcallbackSeq->pseqRecord = pseq; + callbackSetCallback(processCallback,&pcallbackSeq->callback); + callbackSetUser(pcallbackSeq,&pcallbackSeq->callback); + callbackSetPriority(pseq->prio,&pcallbackSeq->callback); + pseq->dpvt = (void *)pcallbackSeq; /* Get link selection if sell is a constant and nonzero */ if (pseq->sell.type==CONSTANT) @@ -144,7 +143,7 @@ int pass; } /* Copy over ALL the input link constants here */ - plink = (struct linkDesc *)(&(pseq->dly1)); + plink = (linkDesc *)(&(pseq->dly1)); index = 0; while (index < NUM_LINKS) @@ -185,10 +184,10 @@ int pass; ******************************************************************************/ static long process(pseq) -struct seqRecord *pseq; +seqRecord *pseq; { - struct callbackSeq *pcb = (struct callbackSeq *) (pseq->dpvt); - struct linkDesc *plink; + callbackSeq *pcb = (callbackSeq *) (pseq->dpvt); + linkDesc *plink; unsigned short lmask; int tmp; @@ -203,7 +202,7 @@ struct seqRecord *pseq; pseq->pact = TRUE; /* Reset the PRIO in case it was changed */ - pcb->callBack.priority = pseq->prio; + callbackSetPriority(pseq->prio,&pcb->callback); /* * We should not bother supporting seqSELM_All or seqSELM_Specified @@ -247,7 +246,7 @@ struct seqRecord *pseq; } /* Figure out which links are going to be processed */ pcb->index = 0; - plink = (struct linkDesc *)(&(pseq->dly1)); + plink = (linkDesc *)(&(pseq->dly1)); tmp = 1; while (lmask) { @@ -298,9 +297,9 @@ struct seqRecord *pseq; * ******************************************************************************/ int processNextLink(pseq) -struct seqRecord *pseq; +seqRecord *pseq; { - struct callbackSeq *pcb = (struct callbackSeq *) (pseq->dpvt); + callbackSeq *pcb = (callbackSeq *) (pseq->dpvt); int wdDelay; if (seqRecDebug > 5) @@ -315,15 +314,12 @@ struct seqRecord *pseq; { if (pcb->plinks[pcb->index]->dly > 0.0) { - /* Use the watch-dog as a delay mechanism */ - wdDelay = (int)(pcb->plinks[pcb->index]->dly * clockGetRate()); - watchdogStart(pcb->wd_id, wdDelay, - (WATCHDOGFUNC)watchDog, (void *)(&(pcb->callBack))); + callbackRequestDelayed( &pcb->callback,pcb->plinks[pcb->index]->dly); } else { /* No delay, do it now. Avoid recursion by using the callback task */ - watchDog((int)(&(pcb->callBack))); + callbackRequest(&pcb->callback); } } return(0); @@ -338,7 +334,7 @@ struct seqRecord *pseq; ******************************************************************************/ static long asyncFinish(pseq) -struct seqRecord *pseq; +seqRecord *pseq; { unsigned short MonitorMask; @@ -360,22 +356,8 @@ struct seqRecord *pseq; return(0); } - /***************************************************************************** - * - * Schedule the process continuation via the callback tasks. - * - * This function is called by the watchdog task when it is time to process the - * "next" link-group in the sequence record. - * - ******************************************************************************/ -static void -watchDog(pcallback) -CALLBACK *pcallback; -{ - callbackRequest(pcallback); - return; -} - /***************************************************************************** + +/***************************************************************************** * * Link-group processing function. * @@ -391,13 +373,14 @@ CALLBACK *pcallback; * ******************************************************************************/ static void -processCallback(pCallback) -CALLBACK *pCallback; +processCallback(CALLBACK *arg) { - struct seqRecord *pseq = (struct seqRecord *)(pCallback->user); - struct callbackSeq *pcb = (struct callbackSeq *) (pseq->dpvt); - double myDouble; + callbackSeq *pcb; + seqRecord *pseq; + double myDouble; + callbackGetUser(pcb,arg); + pseq = pcb->pseqRecord; dbScanLock((struct dbCommon *)pseq); if (seqRecDebug > 5) @@ -442,7 +425,7 @@ get_precision(paddr, precision) struct dbAddr *paddr; long *precision; { - struct seqRecord *pseq = (struct seqRecord *) paddr->precord; + seqRecord *pseq = (seqRecord *) paddr->precord; *precision = pseq->prec; diff --git a/src/rec/steppermotorRecord.c b/src/rec/steppermotorRecord.c deleted file mode 100644 index 62262f4b4..000000000 --- a/src/rec/steppermotorRecord.c +++ /dev/null @@ -1,955 +0,0 @@ -/* recSteppermotor.c */ -/* base/src/rec $Id$ */ - -/* recSteppermotor.c - Record Support Routines for Steppermotor records */ -/* - * Original Author: Bob Dalesio - * Current Author: Marty Kraimer - * Date: 12-11-89 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 02-07-90 lrd fix initial fetch from within the motor record - * .02 02-07-90 lrd add a motor command for reading current status - * .03 04-11-90 lrd fixed acceleration for velocity mode motor - * .04 04-13-90 lrd make second argument for move = 0 - * .05 04-19-90 lrd keep first error - * add retry deadband - * make the retry count a database field - * .06 04-20-90 lrd make readback occur before setting MOVN to 0 - * .07 07-02-90 lrd make conversion compute in floating point - * .08 10-01-90 lrd modify readbacks to be throttled by delta - * .09 10-23-90 lrd update rbv even when there are no monitors - * .10 10-25-90 lrd change initialization to set all variables to IVAL - * .11 10-26-90 lrd add DMOV to indicate all retries exhausted or - * motor is at position within deadband - * .12 10-31-90 lrd add time stamps - * .13 11-28-90 lrd make initialization work when readbacks are - * from LVDTs, Motor position and encoders. - * Fixed sm_get_position to be aware of the motion - * status before it was set in the record see .06 - * .14 11-29-90 lrd conditionally process soft channels - * .15 12-14-90 lrd fixed limit switch monitor notification - * .16 12-17-90 lrd stop motor on overshoot - * .17 12-17-90 lrd fix limits on initialization - * .18 03-15-91 lrd change acceleration and velocity for positional - * motors - * .19 03-21-91 lrd add forward link processing - * .20 06-04-91 lrd apply drive high and low software clamps before - * checking if the setpoint is different - * move the conversion to steps in line - * apply deadband to overshoot checking - - * .21 06-25-91 mk fix direction indication - * .22 06-25-91 mk/lrd fix encoder position divide by zero - * .23 06-25-91 lrd add DBE_LOG to monitors other than value - * .24 07-02-91 rac avoid gcc warnings - * .25 08-28-91 lrd add open circuit detect on limit switches - * .26 09-16-91 lrd fix IALG not 0 and SCAN not Passive - The motor - * would continually attempt to initialize - * .27 12-09-91 lrd new ININVALID severity for errors that invalidate - * the results - * .28 12-17-91 lrd changed the MDEL and ADEL deadbands so - * the range for exceeding the deadband includes - * the value specified. (i.e. 0 is always violated) - - * .21 10-15-90 mrk extensible record and device support - * .22 10-24-91 jba bug fix to alarms - * .23 11-11-91 jba Moved set and reset of alarm stat and sevr to macros - * .24 02-28-92 jba Changed get_precision,get_graphic_double,get_control_double - * .25 02-28-92 jba ANSI C changes - * .26 03-18-92 mrk move retry to callback - Make STOP stop even if retry>0 - Make motor move whenever VAL field accessed - * .27 04-08-92 mrk break out device support - * .28 04-18-92 jba removed process from dev init_record parms - * .29 07-15-92 jba changed VALID_ALARM to INVALID alarm - * .30 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro - * .31 07-21-92 jba changed alarm limits for non val related fields - * .32 10-10-92 jba replaced code for get of VAL from DOL with recGblGetLinkValue - * .33 01-05-93 jbk force recalc of velo and accel each time rec processed - * .34 07-20-93 jbk fixed accel of zero causing divide by zero - * .35 08-06-93 mrk vel mode: Call recGblFwdLink only when motor - * Stops - * .36 09-15-93 mrk call monitor when starting - * .37 03-29-94 mcn converted to fast links - * .38 09-27-95 lrd fix init to limit in overshoot check and retry - * post monitors for mcw and mccw - * .39 04-09-96 ric Pos/Neg limit algos changed to move max int - * steps. Dev/Drv sup will interpret meaning - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "dbScan.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "special.h" -#define GEN_SIZE_OFFSET -#include "steppermotorRecord.h" -#undef GEN_SIZE_OFFSET -#include "steppermotor.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(); -static long process(); -static long special(); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(); -static long get_precision(); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(); -static long get_control_double(); -static long get_alarm_double(); - -struct rset steppermotorRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double }; - -struct smdset { - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN sm_command; -}; - - -#define VELOCITY 0 -#define POSITION 1 -#define POSITIVE_LIMIT 1 -#define NEGATIVE_LIMIT 2 -#define POSITIVE_HOME 3 -#define NEGATIVE_HOME 4 - -static void alarm(); -static void monitor(); -static void smcb_callback(); -static void init_sm(); -static void positional_sm(); -static void velocity_sm(); -static void sm_get_position(); - - -static long init_record(psm,pass) - struct steppermotorRecord *psm; - int pass; -{ - struct smdset *pdset; - long status; - - if (pass==0) return(0); - - if(!(pdset = (struct smdset *)(psm->dset))) { - recGblRecordError(S_dev_noDSET,(void *)psm,"sm: init_record"); - return(S_dev_noDSET); - } - /* must have sm_command function defined */ - if( (pdset->number < 5) || (pdset->sm_command == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)psm,"sm: init_record"); - return(S_dev_missingSup); - } - if( pdset->init_record ) { - if((status=(*pdset->init_record)(psm))) return(status); - } - - /* get the initial value if dol is a constant*/ - if (psm->dol.type == CONSTANT ){ - if(recGblInitConstantLink(&psm->dol,DBF_FLOAT,&psm->val)) - psm->udf = FALSE; - } - - init_sm(psm); - return(0); -} - - -static long process(psm) - struct steppermotorRecord *psm; -{ - struct smdset *pdset = (struct smdset *)(psm->dset); - - if( (pdset==NULL) || (pdset->sm_command==NULL) ) { - psm->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)psm,"sm_command"); - return(S_dev_missingSup); - } - /* intialize the stepper motor record when the init bit is 0 */ - /* the init is set when the readback returns */ - if (psm->init <= 0){ - if(psm->init==0) init_sm(psm); - recGblGetTimeStamp(psm); - monitor(psm); - return(0); - } - - psm->pact = TRUE; - if(psm->cmod == POSITION) { - positional_sm(psm); - if(!psm->dmov) { - recGblGetTimeStamp(psm); - monitor(psm); - psm->pact=FALSE; - return(0); - } - } - else { - velocity_sm(psm); - } - recGblGetTimeStamp(psm); - /* check event list */ - monitor(psm); - /* process the forward scan link record */ - recGblFwdLink(psm); - psm->pact=FALSE; - return(0); -} - -static long special(paddr,after) - struct dbAddr *paddr; - int after; -{ - struct steppermotorRecord *psm = - (struct steppermotorRecord *)(paddr->precord); - int special_type = paddr->special; - - if(!after) return(0); - switch(special_type) { - case(SPC_MOD): - /* set lval different than val so that motor will move*/ - if(psm->lval==psm->val) psm->lval = psm->val+1.0; - return(0); - default: - recGblDbaddrError(S_db_badChoice,paddr,"stepperMotor: special"); - return(S_db_badChoice); - } -} - -static long get_units(paddr,units) - struct dbAddr *paddr; - char *units; -{ - struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord; - - strncpy(units,psm->egu,DB_UNITS_SIZE); - return(0); -} - -static long get_precision(paddr,precision) - struct dbAddr *paddr; - long *precision; -{ - struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord; - - *precision = psm->prec; - if(paddr->pfield==(void *)&psm->val - || paddr->pfield==(void *)&psm->lval) return(0); - recGblGetPrec(paddr,precision); - return(0); -} - -static long get_graphic_double(paddr,pgd) - struct dbAddr *paddr; - struct dbr_grDouble *pgd; -{ - struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord; - - if(paddr->pfield==(void *)&psm->val - || paddr->pfield==(void *)&psm->mpos - || paddr->pfield==(void *)&psm->rbv - || paddr->pfield==(void *)&psm->epos - || paddr->pfield==(void *)&psm->hihi - || paddr->pfield==(void *)&psm->high - || paddr->pfield==(void *)&psm->low - || paddr->pfield==(void *)&psm->lolo - || paddr->pfield==(void *)&psm->lval){ - pgd->upper_disp_limit = psm->hopr; - pgd->lower_disp_limit = psm->lopr; - } else recGblGetGraphicDouble(paddr,pgd); - return(0); -} - -static long get_control_double(paddr,pcd) - struct dbAddr *paddr; - struct dbr_ctrlDouble *pcd; -{ - struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord; - - if(paddr->pfield==(void *)&psm->val - || paddr->pfield==(void *)&psm->mpos - || paddr->pfield==(void *)&psm->rbv - || paddr->pfield==(void *)&psm->epos - || paddr->pfield==(void *)&psm->hihi - || paddr->pfield==(void *)&psm->high - || paddr->pfield==(void *)&psm->low - || paddr->pfield==(void *)&psm->lolo - || paddr->pfield==(void *)&psm->lval){ - pcd->upper_ctrl_limit = psm->drvh; - pcd->lower_ctrl_limit = psm->drvl; - } else recGblGetControlDouble(paddr,pcd); - return(0); -} - -static long get_alarm_double(paddr,pad) - struct dbAddr *paddr; - struct dbr_alDouble *pad; -{ - struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord; - - if(paddr->pfield==(void *)&psm->val - || paddr->pfield==(void *)&psm->mpos - || paddr->pfield==(void *)&psm->rbv - || paddr->pfield==(void *)&psm->epos - || paddr->pfield==(void *)&psm->lval){ - pad->upper_alarm_limit = psm->hihi; - pad->upper_warning_limit = psm->high; - pad->lower_warning_limit = psm->low; - pad->lower_alarm_limit = psm->lolo; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - - -static void alarm(psm) - struct steppermotorRecord *psm; -{ - float deviation; - - deviation = psm->val - psm->rbv; - - /* alarm condition hihi */ - if (deviation > psm->hihi && recGblSetSevr(psm,HIHI_ALARM,psm->hhsv)){ - return; - } - - /* alarm condition lolo */ - if (deviation < psm->lolo && recGblSetSevr(psm,LOLO_ALARM,psm->llsv)){ - return; - } - - /* alarm condition high */ - if (deviation > psm->high && recGblSetSevr(psm,HIGH_ALARM,psm->hsv)){ - return; - } - - /* alarm condition low */ - if (deviation < psm->low && recGblSetSevr(psm,LOW_ALARM,psm->lsv)){ - return; - } - return; -} - -static void monitor(psm) - struct steppermotorRecord *psm; -{ - unsigned short monitor_mask; - float delta; - - /* get previous stat and sevr and new stat and sevr*/ - monitor_mask = recGblResetAlarms(psm); - /* check for value change */ - delta = psm->mlst - psm->val; - if(delta<0.0) delta = -delta; - if (delta > psm->mdel) { - /* post events for value change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - psm->mlst = psm->val; - } - /* check for archive change */ - delta = psm->alst - psm->val; - if(delta<0.0) delta = -delta; - if (delta > psm->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - /* update last archive value monitored */ - psm->alst = psm->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(psm,&psm->val,monitor_mask); - } - return; -} - -/* - * SMCB_CALLBACK - * - * callback routine when a velocity is read - */ -static void smcb_callback(psm_data,psm) -struct motor_data *psm_data; -struct steppermotorRecord *psm; -{ - struct smdset *pdset = (struct smdset *)(psm->dset); - int intAccept=interruptAccept; - short post_events; - double temp; - short done_move=0; - - if(intAccept) { - dbScanLock((struct dbCommon *)psm); - if(psm->pact) { - dbScanUnlock((struct dbCommon *)psm); - return; - } - psm->pact = TRUE; - recGblGetTimeStamp(psm); - } else psm->mlis.count=0; - if (psm->cmod == VELOCITY){ - /* check velocity */ - if (psm->rrbv != psm_data->velocity){ - psm->rrbv = psm_data->velocity; - psm->rbv = (float)psm_data->velocity / (float)psm->mres; - if (psm->mlis.count){ - db_post_events(psm,&psm->rbv,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->rrbv,DBE_VALUE|DBE_LOG); - } - } - - /* direction */ - if (psm->dir != psm_data->direction){ - psm->dir = psm_data->direction; - if (psm->mlis.count) - db_post_events(psm,&psm->dir,DBE_VALUE|DBE_LOG); - } - - /* constant velocity */ - if (psm->cvel != psm_data->constant_velocity){ - psm->cvel = psm_data->constant_velocity; - if (psm->mlis.count) - db_post_events(psm,&psm->cvel,DBE_VALUE|DBE_LOG); - } - }else{ /* POSITION*/ - /* constant velocity */ - if (psm->cvel != psm_data->constant_velocity){ - psm->cvel = psm_data->constant_velocity; - if (psm->mlis.count) - db_post_events(psm,&psm->cvel,DBE_VALUE|DBE_LOG); - } - - /* direction */ - if (psm->dir != psm_data->direction){ - psm->dir = psm_data->direction; - if (psm->mlis.count) - db_post_events(psm,&psm->dir,DBE_VALUE|DBE_LOG); - } - - /* encoder position */ - /* the encoder is multiplied by 4 on the assumption that all indexers */ - /* use the quardrature encoding technique - if we use an encoder */ - /* that does not, then we need to make quadrature encoder a database */ - /* field and use the 4 on that condition !!!!! */ - if (psm->eres){ - psm->epos = (psm_data->encoder_position * psm->dist * psm->mres) - / (psm->eres * 4); - if (psm->mlis.count) - db_post_events(psm,&psm->epos,DBE_VALUE|DBE_LOG); - } - - /* motor position */ - if (psm->mpos != psm_data->motor_position){ - psm->mpos = psm_data->motor_position * psm->dist; - if (psm->mlis.count) - db_post_events(psm,&psm->mpos,DBE_VALUE|DBE_LOG); - } - - /* limit switches */ - if (psm->mcw != psm_data->cw_limit){ - psm->mcw = psm_data->cw_limit; - psm->cw = (psm->mcw)?0:1; /* change sense for VMS OPI */ - if (psm->mlis.count){ - db_post_events(psm,&psm->cw,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->mcw,DBE_VALUE|DBE_LOG); - } - } - if (psm->mccw != psm_data->ccw_limit){ - psm->mccw = psm_data->ccw_limit; - psm->ccw = (psm->mccw)?0:1; /* change sense for VMS OPI */ - if (psm->mlis.count){ - db_post_events(psm,&psm->ccw,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->mccw,DBE_VALUE|DBE_LOG); - } - } - - /* alarm conditions for limit switches */ - /* get previous stat and sevr and new stat and sevr*/ - recGblResetAlarms(psm); - post_events = FALSE; - if (psm->mccw && psm->mcw){ /* limits disconnected */ - recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); - post_events = TRUE; - }else if ((psm->ccw == 0) || (psm->cw == 0)){ /* limit violation */ - recGblSetSevr(psm,HW_LIMIT_ALARM,psm->hlsv); - post_events = TRUE; - } - - /* moving */ - if (psm->movn != psm_data->moving){ - psm->movn = psm_data->moving; - if (psm->mlis.count) - db_post_events(psm,&psm->movn,DBE_VALUE|DBE_LOG); - } - /* get the read back value */ - sm_get_position(psm); - - /* needs to follow get position to prevent moves with old readback */ - - /* anyone waiting for an event on this record */ - if (psm->mlis.count!=0 && post_events) { - db_post_events(psm,&psm->val,DBE_VALUE|DBE_ALARM|DBE_LOG); - db_post_events(psm,&psm->rbv,DBE_VALUE|DBE_ALARM|DBE_LOG); - db_post_events(psm,&psm->stat,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->sevr,DBE_VALUE|DBE_LOG); - } - /* stop motor on overshoot */ - if ((psm->movn) && (psm->init == 1)){ - if (psm->posm){ /* moving in the positive direction */ - if (psm->rbv > (psm->val + psm->rdbd)) - (*pdset->sm_command)(psm,SM_MOTION,0,0); - }else{ /* moving in the negative direction */ - if (psm->rbv < (psm->val + psm->rdbd) ) - (*pdset->sm_command)(psm,SM_MOTION,0,0); - } - } - if((!psm->movn) && (psm->init == 1)) { - /* difference between desired position and readback pos */ - if ( (psm->rbv < (psm->val - psm->rdbd)) - || (psm->rbv > (psm->val + psm->rdbd)) ){ - /* determine direction */ - psm->posm = (psm->rbv < psm->val); - - /* one attempt was made - record the error */ - if (psm->rcnt == 1){ - psm->miss = (psm->val - psm->rbv); - if (psm->mlis.count) - db_post_events(psm,&psm->miss,DBE_VALUE|DBE_LOG); - } - - /* should we retry */ - if (psm->rcnt < psm->rtry){ - - /* convert */ - temp = psm->val / psm->dist; - psm->rval = temp; - - - /* move motor */ - if ((*pdset->sm_command)(psm,SM_MOVE,psm->rval-psm->rrbv,0) < 0){ - recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); - } else { - psm->rcnt++; - if (psm->mlis.count){ - db_post_events(psm,&psm->rcnt,DBE_VALUE|DBE_LOG); - } - done_move = 0; - } - /* no more retries - put the record in alarm */ - }else{ - done_move = 1; - } - }else{ - /* error doesn't exceed deadband - done moving */ - done_move = 1; - } - } - /* there was a move in progress and now it is complete */ - if (done_move && (psm->dmov == 0)){ - psm->dmov = 1; - if (psm->mlis.count) - db_post_events(psm,&psm->dmov,DBE_VALUE|DBE_LOG); - - /* check for deviation from desired value */ - recGblGetTimeStamp(psm); - alarm(psm); - monitor(psm); - /* process the forward scan link record */ - recGblFwdLink(psm); - } - } - if(intAccept) { - psm->pact = FALSE; - dbScanUnlock((struct dbCommon *)psm); - } - return; -} - -/* - * INIT_SM - */ -static void init_sm(psm) -struct steppermotorRecord *psm; -{ - struct smdset *pdset = (struct smdset *)(psm->dset); - int acceleration,velocity; - short status=0; - - /* acceleration is in terms of seconds to reach velocity */ - if(psm->accl!=0) - acceleration = (1/psm->accl) * psm->velo * psm->mres; - else - acceleration = 0; - - /* velocity is in terms of revolutions per second */ - velocity = psm->velo * psm->mres; - - /* initialize the motor */ - /* set mode - first command checks card present */ - if ((*pdset->sm_command)(psm,SM_MODE,psm->mode,0) < 0){ - recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); - psm->init = 1; - return; - } - - /* set encoder/motor ratio */ - (*pdset->sm_command)(psm,SM_ENCODER_RATIO,psm->mres,psm->eres); - - /* set the velocity */ - (*pdset->sm_command)(psm,SM_VELOCITY,velocity,acceleration); - psm->lvel = psm->velo; - psm->lacc = psm->accl; - - /* set the callback routine */ - (*pdset->sm_command)(psm,SM_CALLBACK,smcb_callback,psm); - - /* initialize the limit values */ - psm->mcw = psm->mccw = -1; - - /* set initial position */ - if (psm->mode == POSITION){ - if (psm->ialg != 0){ - switch (psm->ialg){ - case (POSITIVE_LIMIT): - status = (*pdset->sm_command)(psm,SM_FIND_LIMIT,1,0); - break; - case (NEGATIVE_LIMIT): - status = (*pdset->sm_command)(psm,SM_FIND_LIMIT,-1,0); - break; - case (POSITIVE_HOME): - status = (*pdset->sm_command)(psm,SM_FIND_HOME,1,0); - break; - case (NEGATIVE_HOME): - status = (*pdset->sm_command)(psm,SM_FIND_HOME,-1,0); - break; - } - psm->sthm = 1; - /* force a read of the position and status */ - }else{ - status = (*pdset->sm_command)(psm,SM_READ,0,0); - } - if (status < 0){ - recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); - return; - } - psm->init = -1; - }else if (psm->mode == VELOCITY){ - psm->velo = 0; - psm->init = 1; - } - psm->cmod = psm->mode; - return; -} - -/* - * POSITIONAL_SM - * - * control a stepper motor through position - */ -static void positional_sm(psm) -struct steppermotorRecord *psm; -{ - struct smdset *pdset = (struct smdset *)(psm->dset); - int acceleration,velocity; - long status; - - - /* emergency stop */ - if (psm->stop){ - (*pdset->sm_command)(psm,SM_MOTION,0,0); - psm->stop = 0; - psm->rcnt=psm->rtry+1; - if (psm->mlis.count) db_post_events(psm,&psm->stop,DBE_VALUE|DBE_LOG); - return; - } - - /* no need to do anymore if the motor is in motion */ - if (psm->movn != 0) - return; - - /* set the velocity and acceleration */ - /* jbk change for allowing mres to change */ -/* if ((psm->velo != psm->lvel) || (psm->lacc != psm->accl)){ */ - if(psm->accl!=0) - acceleration = (1/psm->accl) * psm->velo * psm->mres; - else - acceleration = 0; - - velocity = psm->velo * psm->mres; - (*pdset->sm_command)(psm,SM_VELOCITY,velocity,acceleration); - psm->lvel = psm->velo; - psm->lacc = psm->accl; -/* } */ - - /* set home when requested */ - if (psm->sthm != 0){ - psm->sthm = 0; /* reset the set home field */ - psm->val = 0; /* make desired value = home */ - psm->rval = 0; /* make the raw value = 0 */ - psm->rbv = 0; - psm->rrbv = 0; - psm->ival = 0; /* resets initial offset */ - (*pdset->sm_command)(psm,SM_SET_HOME,0,0); - if(psm->mlis.count) { - db_post_events(psm,&psm->rbv,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->val,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->sthm,DBE_VALUE|DBE_LOG); - } - return; - } - - /* fetch the desired value if there is a database link */ - if (psm->omsl == CLOSED_LOOP) { - status=dbGetLink(&(psm->dol),DBR_FLOAT, &(psm->val),0,0); - if (!RTN_SUCCESS(status)) return; - if (psm->dol.type != CONSTANT) psm->udf = FALSE; - } - - /* check drive limits */ - if (psm->dist > 0){ - if (psm->val > psm->drvh) psm->val = psm->drvh; - else if (psm->val < psm->drvl) psm->val = psm->drvl; - }else{ - if (-psm->val > psm->drvh) psm->val = -psm->drvh; - else if (-psm->val < psm->drvl) psm->val = -psm->drvl; - } - - - /* Change of desired position */ - if (psm->lval != psm->val){ - double temp; - - sm_get_position(psm); - psm->rcnt = 0; - psm->lval = psm->val; - psm->dmov = 0; /* start moving to desired location */ - psm->posm = (psm->rbv < psm->val); - temp = psm->val/psm->dist; - psm->rval = temp; - if (psm->mlis.count){ - db_post_events(psm,&psm->rcnt,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->lval,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->dmov,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->posm,DBE_VALUE|DBE_LOG); - db_post_events(psm,&psm->rval,DBE_VALUE|DBE_LOG); - } - /* move motor */ - if ((*pdset->sm_command)(psm,SM_MOVE,psm->rval-psm->rrbv,0) < 0){ - recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); - } - } - - return; -} - -/* - * VELOCITY_SM - * - * control a velocity stepper motor - */ -static void velocity_sm(psm) -struct steppermotorRecord *psm; -{ - struct smdset *pdset = (struct smdset *)(psm->dset); - float chng_vel; - int acceleration,velocity; - long status; - - /* fetch the desired value if there is a database link */ - if (psm->omsl == CLOSED_LOOP){ - status=dbGetLink(&(psm->dol),DBR_FLOAT, &(psm->val),0,0); - if (!RTN_SUCCESS(status)) return; - if (psm->dol.type != CONSTANT) psm->udf = FALSE; - } - - /* Motor not at desired velocity */ - if ((psm->mlst == psm->val) && (psm->val != psm->rbv) && (psm->cvel)) { - alarm(psm); - return; - } - - /* convert the egu velocity to hardware understandable velocity */ - psm->rval = psm->val * psm->mres; - - /* send the new velocity */ - if (psm->rval != 0){ - - /* only if velocity has changed */ - if (psm->velo != psm->val){ - /* acceleration */ - chng_vel = psm->velo - psm->val; - if (chng_vel < 0) chng_vel = -chng_vel; - if(psm->accl!=0) - acceleration = (1/psm->accl) * chng_vel * psm->mres; - else - acceleration = 0; - - /* velocity */ - psm->velo = psm->val; - velocity = ((psm->val >= 0) ? psm->rval : -psm->rval); - - /* motor commands */ - (*pdset->sm_command)(psm,SM_VELOCITY,velocity,acceleration); - - /*the last arg of next call is check for direction */ - if((*pdset->sm_command)(psm,SM_MOTION,1,(psm->val < 0))){ - recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); - return; - } - psm->cvel = 0; - } - }else{ - /* trust it will stop - to read velocity here will not */ - /* work as the motor takes more time to stop than the */ - /* request for velocity takes to return */ - (*pdset->sm_command)(psm,SM_MOTION,0,0); - psm->rbv = 0; - psm->rrbv = 0; - psm->cvel = 0; - psm->velo = psm->val; - - /* post events */ - if(psm->mlis.count) { - db_post_events(psm,&psm->rbv,DBE_VALUE); - db_post_events(psm,&psm->velo,DBE_VALUE); - } - } -} - -/* - * SM_GET_POSITION - * - * get the stepper motor readback position - */ -static void sm_get_position(psm) -struct steppermotorRecord *psm; -{ - struct smdset *pdset = (struct smdset *)(psm->dset); - short reset; - float new_pos,delta; - - /* get readback position */ - if (psm->rdbl.type != CONSTANT){ - /* when readback comes from another field of this record */ - /* the fetch will fail if the record is uninitialized */ - /* also - prdl (process readback location) should be set */ - /* to NO if the readback is from the same record */ - - reset = psm->init; - if (reset == 0) psm->init = 1; - if(dbGetLink(&psm->rdbl,DBR_FLOAT, &new_pos,0,0)) { - recGblSetSevr(psm,READ_ALARM,INVALID_ALARM); - psm->init = reset; - return; - } - psm->init = reset; - /* default is the motor position returned from the driver */ - } - else { - new_pos = psm->mpos; - } - - /* readback position at initialization */ - if ((psm->init <= 0) && (psm->movn == 0)){ - if (psm->sthm){ - (*pdset->sm_command)(psm,SM_SET_HOME,0,0); - psm->sthm = 0; - return; - } - psm->rbv = psm->val = psm->lval = psm->ival + new_pos; - psm->rval = psm->rrbv = psm->rbv / psm->dist; - psm->init = 1; - if (psm->mlis.count != 0){ - db_post_events(psm,&psm->val,DBE_VALUE|DBE_ALARM|DBE_LOG); - db_post_events(psm,&psm->rbv,DBE_VALUE|DBE_ALARM|DBE_LOG); - } - /* readback normally */ - }else{ - if (psm->ival != 0){ - /* adjust if initial position is not 0 */ - new_pos += psm->ival; - } - /* get the raw readback value */ - psm->rrbv = new_pos / psm->dist; - - /* post events */ - if (psm->mlis.count != 0){ - delta = new_pos - psm->rbv; - if (!psm->movn ||((delta > psm->mdel) || (delta < -psm->mdel))){ - psm->rbv = new_pos; - db_post_events(psm,&psm->rbv,DBE_VALUE|DBE_ALARM); - db_post_events(psm,&psm->rrbv,DBE_VALUE|DBE_ALARM); - } - }else{ - psm->rbv = new_pos; - } - } - -} - diff --git a/src/rec/steppermotorRecord.dbd b/src/rec/steppermotorRecord.dbd deleted file mode 100644 index 2cd072756..000000000 --- a/src/rec/steppermotorRecord.dbd +++ /dev/null @@ -1,307 +0,0 @@ -menu(steppermotorIALG) { - choice(steppermotorIALG_No_Initialization,"No Initialization") - choice(steppermotorIALG_Move_to_the_Positive_Limit,"Move to the Positive Limit") - choice(steppermotorIALG_Move_to_the_Negative_Limit,"Move to the Negative Limit") - choice(steppermotorIALG_Move_to_Positive_Home,"Move to Positive Home") - choice(steppermotorIALG_Move_to_Negative_Home,"Move to Negative Home") -} -menu(steppermotorMODE) { - choice(steppermotorMODE_Velocity,"Velocity") - choice(steppermotorMODE_Position,"Position") -} -recordtype(steppermotor) { - include "dbCommon.dbd" - field(VAL,DBF_FLOAT) { - prompt("Desired Value") - asl(ASL0) - special(SPC_MOD) - pp(TRUE) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup(GUI_OUTPUT) - interest(1) - } - field(RDBL,DBF_INLINK) { - prompt("Readback Location") - promptgroup(GUI_OUTPUT) - interest(1) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup(GUI_OUTPUT) - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup(GUI_OUTPUT) - interest(1) - menu(menuOmsl) - } - field(ACCL,DBF_FLOAT) { - prompt("Seconds to Velocity") - promptgroup(GUI_MOTOR) - interest(1) - } - field(VELO,DBF_FLOAT) { - prompt("Velocity Rotation/Sec") - promptgroup(GUI_MOTOR) - interest(1) - } - field(DIST,DBF_FLOAT) { - prompt("Dist of One Pulse") - promptgroup(GUI_MOTOR) - interest(1) - } - field(IVAL,DBF_FLOAT) { - prompt("Value at init") - promptgroup(GUI_MOTOR) - interest(1) - } - field(MODE,DBF_MENU) { - prompt("Operating Mode") - promptgroup(GUI_MOTOR) - interest(1) - menu(steppermotorMODE) - } - field(CMOD,DBF_MENU) { - prompt("Current Operating Mode") - promptgroup(GUI_MOTOR) - interest(1) - menu(steppermotorMODE) - } - field(IALG,DBF_MENU) { - prompt("Initialization Alg") - promptgroup(GUI_MOTOR) - interest(1) - menu(steppermotorIALG) - } - field(MRES,DBF_USHORT) { - prompt("Motor Pulses/Revolution") - promptgroup(GUI_MOTOR) - interest(1) - } - field(ERES,DBF_USHORT) { - prompt("Encoder Pulses/Rev") - promptgroup(GUI_MOTOR) - interest(1) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup(GUI_DISPLAY) - interest(1) - size(16) - } - field(DRVH,DBF_FLOAT) { - prompt("Drive High Limit") - promptgroup(GUI_OUTPUT) - pp(TRUE) - interest(1) - } - field(DRVL,DBF_FLOAT) { - prompt("Drive Low Limit") - promptgroup(GUI_OUTPUT) - pp(TRUE) - interest(1) - } - field(HOPR,DBF_FLOAT) { - prompt("High Operating Range") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(LOPR,DBF_FLOAT) { - prompt("Low Operating Range") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(HIHI,DBF_FLOAT) { - prompt("Hihi Alarm Limit") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - } - field(LOLO,DBF_FLOAT) { - prompt("Lolo Alarm Limit") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - } - field(HIGH,DBF_FLOAT) { - prompt("High Alarm Limit") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - } - field(LOW,DBF_FLOAT) { - prompt("Low Alarm Limit") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup(GUI_ALARMS) - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HLSV,DBF_MENU) { - prompt("HW Limit Violation Svr") - promptgroup(GUI_MOTOR) - pp(TRUE) - interest(2) - menu(menuAlarmSevr) - } - field(MDEL,DBF_FLOAT) { - prompt("Monitor Deadband") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(ADEL,DBF_FLOAT) { - prompt("Archive Deadband") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(RDBD,DBF_FLOAT) { - prompt("Retry Deadband") - promptgroup(GUI_MOTOR) - interest(1) - } - field(RTRY,DBF_SHORT) { - prompt("Number of retries") - promptgroup(GUI_MOTOR) - interest(1) - } - field(STHM,DBF_SHORT) { - prompt("Set Home") - pp(TRUE) - interest(2) - } - field(STOP,DBF_SHORT) { - prompt("Stop motor") - pp(TRUE) - interest(2) - } - field(DMOV,DBF_SHORT) { - prompt("Done moving to value") - interest(2) - } - field(RVAL,DBF_LONG) { - prompt("Current Raw Value") - pp(TRUE) - } - field(RBV,DBF_FLOAT) { - prompt("Readback Value") - interest(1) - } - field(RRBV,DBF_LONG) { - prompt("Raw Readback Value") - interest(1) - } - field(ALST,DBF_FLOAT) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_FLOAT) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(INIT,DBF_SHORT) { - prompt("Initialize") - interest(2) - } - field(MCW,DBF_SHORT) { - prompt("Mtr Clckws Lim") - pp(TRUE) - interest(2) - } - field(MCCW,DBF_SHORT) { - prompt("Mtr Cntr Clockwise Lmt") - pp(TRUE) - interest(2) - } - field(CW,DBF_SHORT) { - prompt("Clockwise Limit") - pp(TRUE) - interest(2) - } - field(CCW,DBF_SHORT) { - prompt("Counter Clockwise Lmt") - pp(TRUE) - interest(2) - } - field(DIR,DBF_SHORT) { - prompt("Direction of Travel") - pp(TRUE) - interest(2) - } - field(MOVN,DBF_SHORT) { - prompt("Moving Status") - interest(2) - } - field(CVEL,DBF_SHORT) { - prompt("Constant Velocity") - interest(2) - } - field(RCNT,DBF_SHORT) { - prompt("Retry count") - interest(2) - } - field(POSM,DBF_SHORT) { - prompt("Positive motion") - interest(2) - } - field(LVAL,DBF_FLOAT) { - prompt("Last Value") - special(SPC_NOMOD) - interest(3) - } - field(EPOS,DBF_FLOAT) { - prompt("Encoder position rdbck") - interest(2) - } - field(MPOS,DBF_FLOAT) { - prompt("Motor position rdbck") - interest(2) - } - field(MISS,DBF_FLOAT) { - prompt("First attemp error") - interest(2) - } - field(LVEL,DBF_FLOAT) { - prompt("Last Velocity set") - interest(2) - } - field(LACC,DBF_FLOAT) { - prompt("Last acc set") - interest(2) - } -}