From 43fff62788fb803e3f3e6549f40ac3cc0a0cd863 Mon Sep 17 00:00:00 2001 From: Ron Sluiter Date: Thu, 26 Jul 2012 19:18:18 +0000 Subject: [PATCH] Added OMS board reboot detection test. --- motorApp/OmsSrc/drvOms.cc | 56 ++++++++++++++++++----- motorApp/OmsSrc/drvOms.h | 95 ++++++++++++++++++++------------------- 2 files changed, 92 insertions(+), 59 deletions(-) diff --git a/motorApp/OmsSrc/drvOms.cc b/motorApp/OmsSrc/drvOms.cc index 972b2312..b56fd1f1 100644 --- a/motorApp/OmsSrc/drvOms.cc +++ b/motorApp/OmsSrc/drvOms.cc @@ -1,6 +1,6 @@ /* FILENAME... drvOms.cc -USAGE... Driver level support for OMS models VME8, VME44 and VS4. +USAGE... Driver level support for OMS models VME8, VME44, VS4 and VX2. Version: $Revision$ Modified By: $Author$ @@ -79,6 +79,9 @@ HeadURL: $URL$ * .16 04-12-10 rls - enable interrupts after encoder check in motor_init() so * user does not see "motorIsr: command error" messages at * iocInit time. + * .17 07-26-12 rls - Added reboot flag to IRQ control register. Driver + * sets IRQ_RESET_ID bit on; set_status() and send_mess() + * read IRQ register and disable board if flag is off. */ /*========================stepper motor driver ======================== @@ -206,6 +209,7 @@ struct drvOms_drvet extern "C" {epicsExportAddress(drvet, drvOms);} static struct thread_args targs = {SCAN_RATE, &oms_access, 0.010}; +static char rebootmsg[] = "\n\n*** OMS card #%d Disabled *** Reboot Detected.\n\n"; /*----------------functions-----------------*/ @@ -257,11 +261,27 @@ static int set_status(int card, int signal) int rtn_state; bool ls_active = false; msta_field status; + struct controller *pmotorState; + struct vmex_motor *pmotor; - motor_info = &(motor_state[card]->motor_info[signal]); + if ((pmotorState = motor_state[card]) == NULL || + (pmotor = (struct vmex_motor *) pmotorState->localaddr) == NULL) + return(rtn_state = 1); /* End move. */ + + motor_info = &(pmotorState->motor_info[signal]); nodeptr = motor_info->motor_motion; status.All = motor_info->status.All; + if ((pmotor->control & IRQ_RESET_ID) != 0x01) /* Test if board has rebooted. */ + { + errlogPrintf(rebootmsg, card); + status.Bits.RA_PROBLEM = 1; + motor_info->status.All = status.All; + /* Disable board. */ + motor_state[card] = (struct controller *) NULL; + return(rtn_state = 1); /* End move. */ + } + if (motor_state[card]->motor_info[signal].encoder_present == YES) { /* get 4 peices of info from axis */ @@ -440,6 +460,8 @@ static RTN_STATUS send_mess(int card, char const *com, char *name) { char outbuf[MAX_MSG_SIZE]; RTN_STATUS return_code; + volatile struct controller *pmotorState; + volatile struct vmex_motor *pmotor; if (strlen(com) > MAX_MSG_SIZE) { @@ -448,12 +470,22 @@ static RTN_STATUS send_mess(int card, char const *com, char *name) } /* Check that card exists */ - if (!motor_state[card]) + if ((pmotorState = motor_state[card]) == NULL) { errlogPrintf("drvOms.cc:send_mess() - invalid card #%d\n", card); return(ERROR); } + pmotor = (struct vmex_motor *) pmotorState->localaddr; + + if ((pmotor->control & IRQ_RESET_ID) != 0x01) /* Test if board has rebooted. */ + { + errlogPrintf(rebootmsg, card); + /* Disable board. */ + motor_state[card] = (struct controller *) NULL; + return(ERROR); + } + /* Check/Clear command errors */ omsError(card); @@ -689,7 +721,8 @@ static RTN_STATUS omsPut(int card, char *pmess) struct irqdatastr *irqdata; int key, msgsize; - pmotorState = motor_state[card]; + if ((pmotorState = motor_state[card]) == NULL) + return(ERROR); irqdata = (struct irqdatastr *) pmotorState->DevicePrivate; pmotor = (struct vmex_motor *) pmotorState->localaddr; msgsize = strlen(pmess); @@ -902,7 +935,7 @@ static int motorIsrEnable(int card) "Can't connect to vector %d\n", omsInterruptVector + card); irqdata->irqEnable = FALSE; /* Interrupts disable on card */ - pmotor->control = 0; + pmotor->control = IRQ_RESET_ID; return(ERROR); } @@ -914,7 +947,7 @@ static int motorIsrEnable(int card) "Can't enable enterrupt level %d\n", omsInterruptLevel); irqdata->irqEnable = FALSE; /* Interrupts disable on card */ - pmotor->control = 0; + pmotor->control = IRQ_RESET_ID; return(ERROR); } } @@ -935,7 +968,7 @@ static int motorIsrEnable(int card) cardStatus = pmotor->status; /* enable interrupt-when-done and input-buffer-full interrupts */ - pmotor->control = IRQ_ENABLE_ALL; + pmotor->control = (IRQ_ENABLE_ALL | IRQ_RESET_ID); return(OK); } @@ -953,11 +986,10 @@ static void motorIsrDisable(int card) pmotor = (struct vmex_motor *) (pmotorState->localaddr); /* Disable interrupts */ - pmotor->control = 0; + pmotor->control = IRQ_RESET_ID; #ifdef vxWorks - status = pdevLibVirtualOS->pDevDisconnectInterruptVME( - omsInterruptVector + card, (void (*)(void *)) motorIsr); + status = pdevLibVirtualOS->pDevDisconnectInterruptVME(omsInterruptVector + card, (void (*)(void *)) motorIsr); #endif if (!RTN_SUCCESS(status)) @@ -1136,7 +1168,7 @@ static int motor_init() irqdata = (struct irqdatastr *) malloc(sizeof(struct irqdatastr)); pmotorState->DevicePrivate = irqdata; irqdata->irqEnable = FALSE; - pmotor->control = 0; + pmotor->control = IRQ_RESET_ID; send_mess(card_index, "EF", (char) NULL); send_mess(card_index, ERROR_CLEAR, (char) NULL); @@ -1237,7 +1269,7 @@ static void oms_reset(void *arg) if (motor_state[card] != NULL) { pmotor = (struct vmex_motor *) motor_state[card]->localaddr; - pmotor->control = 0; /* Disable all interrupts. */ + pmotor->control = IRQ_RESET_ID; /* Disable all interrupts. */ } } } diff --git a/motorApp/OmsSrc/drvOms.h b/motorApp/OmsSrc/drvOms.h index 89e298a1..36b1938b 100644 --- a/motorApp/OmsSrc/drvOms.h +++ b/motorApp/OmsSrc/drvOms.h @@ -1,11 +1,11 @@ /* -FILENAME... drvOms.h +FILENAME... drvOms.h USAGE... This file contains OMS driver "include" information that is - specific to OMS models VME8 and VME44. + specific to OMS models VME8 and VME44. -Version: $Revision$ -Modified By: $Author$ -Last Modified: $Date$ +Version: $Revision$ +Modified By: $Author$ +Last Modified: $Date$ */ /* @@ -19,26 +19,26 @@ Last Modified: $Date$ * 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 + * 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 + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory * * Modification Log: * ----------------- * .00 10-23-03 rls - VX2 spurious interrupt fix; enable all interrupts, including - * transmit buffer empty. + * transmit buffer empty. * .01 10-28-03 rls - moved OMS specific "irqdatastr" from motordrvCom.h to here. */ -#ifndef INCdrvOmsh -#define INCdrvOmsh 1 +#ifndef INCdrvOmsh +#define INCdrvOmsh 1 #include "drvOmsCom.h" #include "epicsRingBytes.h" @@ -47,39 +47,40 @@ Last Modified: $Date$ * VME8/44 default profile */ -#define OMS_NUM_CARDS 8 -#define OMS_NUM_CHANNELS 8 -#define OMS_NUM_ADDRS 0xFC00 -#define OMS_BRD_SIZE 0x10 /* card address boundary */ -#define OMS_RESP_Q_SZ 0x100 /* maximum oms response message size */ +#define OMS_NUM_CARDS 8 +#define OMS_NUM_CHANNELS 8 +#define OMS_NUM_ADDRS 0xFC00 +#define OMS_BRD_SIZE 0x10 /* card address boundary */ +#define OMS_RESP_Q_SZ 0x100 /* maximum oms response message size */ /* status register */ -#define STAT_IRQ 0x80 -#define STAT_TRANS_BUF_EMPTY 0x40 -#define STAT_INPUT_BUF_FULL 0x20 -#define STAT_DONE 0x10 -#define STAT_OVERTRAVEL 0x08 -#define STAT_ENCODER_REQ 0x04 -#define STAT_UNUSED 0x02 -#define STAT_ERROR 0x01 +#define STAT_IRQ 0x80 +#define STAT_TRANS_BUF_EMPTY 0x40 +#define STAT_INPUT_BUF_FULL 0x20 +#define STAT_DONE 0x10 +#define STAT_OVERTRAVEL 0x08 +#define STAT_ENCODER_REQ 0x04 +#define STAT_INIT 0x02 +#define STAT_ERROR 0x01 /* done flag register */ -#define DONE_X 0x01 -#define DONE_Y 0x02 -#define DONE_Z 0x04 -#define DONE_T 0x08 -#define DONE_U 0x10 -#define DONE_V 0x20 -#define DONE_R 0x40 -#define DONE_S 0x80 +#define DONE_X 0x01 +#define DONE_Y 0x02 +#define DONE_Z 0x04 +#define DONE_T 0x08 +#define DONE_U 0x10 +#define DONE_V 0x20 +#define DONE_R 0x40 +#define DONE_S 0x80 /* interrupt control register */ -#define IRQ_ENABLE 0x80 -#define IRQ_TRANS_BUF 0x40 -#define IRQ_INPUT_BUF 0x20 -#define IRQ_DONE 0x10 +#define IRQ_ENABLE 0x80 +#define IRQ_TRANS_BUF 0x40 +#define IRQ_INPUT_BUF 0x20 +#define IRQ_DONE 0x10 +#define IRQ_RESET_ID 0x01 -#define IRQ_ENABLE_ALL (IRQ_ENABLE|IRQ_TRANS_BUF|IRQ_INPUT_BUF|IRQ_DONE) +#define IRQ_ENABLE_ALL (IRQ_ENABLE|IRQ_TRANS_BUF|IRQ_INPUT_BUF|IRQ_DONE) struct vmex_motor { @@ -96,14 +97,14 @@ struct vmex_motor epicsUInt8 unused5[6]; }; -struct irqdatastr /* Used only for VME44. */ +struct irqdatastr /* Used only for VME44. */ { /* Interrupt Handling control elements */ - int irqErrno; /* Error indicator from isr */ + int irqErrno; /* Error indicator from isr */ epicsUInt8 irqEnable; - epicsRingBytesId recv_rng; /* message receiving control */ + epicsRingBytesId recv_rng; /* message receiving control */ epicsEvent *recv_sem; - epicsRingBytesId send_rng; /* message transmitting control */ + epicsRingBytesId send_rng; /* message transmitting control */ }; -#endif /* INCdrvOmsh */ +#endif /* INCdrvOmsh */