diff --git a/motorApp/AerotechSrc/AerotechRegister.h b/motorApp/AerotechSrc/AerotechRegister.h index 0e91a819..7a9937a0 100644 --- a/motorApp/AerotechSrc/AerotechRegister.h +++ b/motorApp/AerotechSrc/AerotechRegister.h @@ -43,7 +43,6 @@ HeadURL: $URL$ #include "motor.h" #include "motordrvCom.h" #include "drvEnsembleAsyn.h" -#include "drvEnsemble.h" #include "drvSoloist.h" diff --git a/motorApp/AerotechSrc/Makefile b/motorApp/AerotechSrc/Makefile index 7ad5aa71..a4ae8b5f 100644 --- a/motorApp/AerotechSrc/Makefile +++ b/motorApp/AerotechSrc/Makefile @@ -11,7 +11,6 @@ LIBRARY_IOC = Aerotech # Aerotech driver support. SRCS += AerotechRegister.cc -SRCS += devEnsemble.cc drvEnsemble.cc SRCS += devSoloist.cc drvSoloist.cc SRCS += drvEnsembleAsyn.cc diff --git a/motorApp/AerotechSrc/devAerotech.dbd b/motorApp/AerotechSrc/devAerotech.dbd index e92fbab1..fa8b648b 100644 --- a/motorApp/AerotechSrc/devAerotech.dbd +++ b/motorApp/AerotechSrc/devAerotech.dbd @@ -1,13 +1,6 @@ -# Aerotech Ensemble Driver support. -device(motor,VME_IO,devEnsemble,"Ensemble") -driver(drvEnsemble) - # Aerotech Soloist Driver support device(motor,VME_IO,devSoloist,"Soloist") driver(drvSoloist) -# Aerotech Ensemble asynMotor support -driver(motorEnsemble) - registrar(AerotechRegister) diff --git a/motorApp/AerotechSrc/devEnsemble.cc b/motorApp/AerotechSrc/devEnsemble.cc deleted file mode 100644 index b509cf5b..00000000 --- a/motorApp/AerotechSrc/devEnsemble.cc +++ /dev/null @@ -1,376 +0,0 @@ -/* - * FILENAME... devEnsemble.cc - * USAGE... Motor record device level support for Aerotech Ensemble. - * - * Version: $Revision$ - * Modified By: $Author$ - * Last Modified: $Date$ - * HeadURL: $URL$ - */ - -/* - * Original Author: Chad Weimer - * Date: 04/04/08 - * Current Author: Chad Weimer - * - * 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-01-08 caw initialized from devMM4000.cc (Newport) - * .02 11-20-08 rls - support homing in both directions. - * - disable LOAD_POS until ABORT command fixed. - * - SET_VELOCITY sets both default speed and home feedrate. - * .03 01-22-09 rls - enable LOAD_POS; ABORT command fixed with Ensemble - * firmware 2.5.2. - * .04 05-01-09 rls - Fix for jog velocity not adjusted by - * cntrl->drive_resolution. - * .05 03-02-10 rls - removed setting controller's soft limits; see README - * - Depreciated version; use the asyn motor version. - */ - - -#include -#include -#include "motorRecord.h" -#include "motor.h" -#include "motordevCom.h" -#include "drvEnsemble.h" -#include "epicsExport.h" - -extern struct driver_table Ensemble_access; - -/* ----------------Create the dsets for devEnsemble----------------- */ -static struct driver_table *drvtabptr; -static long Ensemble_init (void *); -static long Ensemble_init_record (void *); -static long Ensemble_start_trans (struct motorRecord *); -static RTN_STATUS Ensemble_build_trans (motor_cmnd, double *, - struct motorRecord *); -static RTN_STATUS Ensemble_end_trans (struct motorRecord *); - -struct motor_dset devEnsemble = -{ - {8, NULL, (DEVSUPFUN) Ensemble_init, (DEVSUPFUN) Ensemble_init_record, NULL}, - motor_update_values, - Ensemble_start_trans, - Ensemble_build_trans, - Ensemble_end_trans -}; - -extern "C" {epicsExportAddress (dset, devEnsemble);} -/* --------------------------- program data --------------------- */ - -/* - * This table is used to define the command types - * WARNING! this must match "motor_cmnd" in motor.h - */ - -static msg_types Ensemble_table[] = { - MOTION, /* MOVE_ABS */ - MOTION, /* MOVE_REL */ - MOTION, /* HOME_FOR */ - MOTION, /* HOME_REV */ - IMMEDIATE, /* LOAD_POS */ - IMMEDIATE, /* SET_VEL_BASE */ - IMMEDIATE, /* SET_VELOCITY */ - IMMEDIATE, /* SET_ACCEL */ - IMMEDIATE, /* GO */ - IMMEDIATE, /* SET_ENC_RATIO */ - INFO, /* GET_INFO */ - MOVE_TERM, /* STOP_AXIS */ - VELOCITY, /* JOG */ - IMMEDIATE, /* SET_PGAIN */ - IMMEDIATE, /* SET_IGAIN */ - IMMEDIATE, /* SET_DGAIN */ - IMMEDIATE, /* ENABLE_TORQUE */ - IMMEDIATE, /* DISABL_TORQUE */ - IMMEDIATE, /* PRIMITIVE */ - IMMEDIATE, /* SET_HIGH_LIMIT */ - IMMEDIATE, /* SET_LOW_LIMIT */ - VELOCITY, /* JOG_VELOCITY */ - IMMEDIATE /* SET_RESOLUTION */ -}; - - -static struct board_stat **Ensemble_cards; - -/* --------------------------- program data --------------------- */ - - -// initialize device support for Ensemble -static long Ensemble_init (void *arg) -{ - long rtnval; - int after = (arg == 0) ? 0 : 1; - - if (after == 0) - { - drvtabptr = &Ensemble_access; - (drvtabptr->init)(); - } - - rtnval = motor_init_com(after, *drvtabptr->cardcnt_ptr, - drvtabptr, &Ensemble_cards); - return(rtnval); -} - - -// initialize a record instance -static long Ensemble_init_record (void *arg) -{ - struct motorRecord *mr = (struct motorRecord *) arg; - return(motor_init_record_com(mr, *drvtabptr->cardcnt_ptr, - drvtabptr, Ensemble_cards)); -} - - -// start building a transaction -static long Ensemble_start_trans (struct motorRecord *mr) -{ - return(OK); - //return (motor_start_trans_com(mr, Ensemble_cards)); -} - - -// end building a transaction -static RTN_STATUS Ensemble_end_trans (struct motorRecord * mr) -{ - return(OK); - //return (motor_end_trans_com(mr, drvtabptr)); -} - - -// add a part to the transaction -static RTN_STATUS Ensemble_build_trans (motor_cmnd command, double *parms, - struct motorRecord * mr) -{ - struct motor_trans *trans = (struct motor_trans *) mr->dpvt; - struct mess_node *motor_call; - struct controller *brdptr; - struct Ensemblecontroller *cntrl; - char buff[BUFF_SIZE], temp[BUFF_SIZE]; - int axis, card, maxdigits; - unsigned int size; - double dval, cntrl_units; - RTN_STATUS rtnval; - bool send = true; - - rtnval = OK; - buff[0] = '\0'; - - // Protect against NULL pointer with WRTITE_MSG(GO/STOP_AXIS/GET_INFO, NULL). - dval = (parms == NULL) ? 0.0 : *parms; - - motor_start_trans_com(mr, Ensemble_cards); - - motor_call = &(trans->motor_call); - card = motor_call->card; - axis = motor_call->signal; - brdptr = (*trans->tabptr->card_array)[card]; - if (brdptr == NULL) - return(rtnval = ERROR); - - cntrl = (struct Ensemblecontroller *) brdptr->DevicePrivate; - cntrl_units = dval * cntrl->drive_resolution[axis]; - maxdigits = cntrl->res_decpts[axis]; - - if (Ensemble_table[command] > motor_call->type) - { - motor_call->type = Ensemble_table[command]; - } - - if (trans->state != BUILD_STATE) - { - return(rtnval = ERROR); - } - - switch (command) - { - case MOVE_ABS: - case MOVE_REL: - case HOME_FOR: - case HOME_REV: - case JOG: - if (strlen(mr->prem) != 0) - { - sprintf(temp, "%s%c", mr->prem, ASCII_EOS_CHAR); - strcat(motor_call->message, temp); - } - if (strlen(mr->post) != 0) - { - motor_call->postmsgptr = (char *) &mr->post; - } - break; - - default: - break; - } - - switch (command) - { - case MOVE_ABS: - sprintf(buff, "MOVEABS @%d %.*f", - axis, maxdigits, cntrl_units); - break; - case MOVE_REL: - sprintf(buff, "MOVEINC @%d %.*f", - axis, maxdigits, cntrl_units); - break; - - case HOME_FOR: - case HOME_REV: - { - epicsUInt32 hparam = cntrl->home_dparam[axis]; - if (command == HOME_FOR) - hparam |= 0x00000001; - else - hparam &= 0xFFFFFFFE; - cntrl->home_dparam[axis] = hparam; - - sprintf(buff, "SETPARM @%d, 106, %d", axis, hparam); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - - rtnval = (RTN_STATUS) motor_start_trans_com(mr, Ensemble_cards); - sprintf(buff, "HOME @%d", axis); - motor_call->type = Ensemble_table[command]; - } - break; - - case LOAD_POS: - sprintf(buff, "SETPOSCMD @%d, %.*f", axis, maxdigits, cntrl_units); - break; - - case SET_VEL_BASE: - send = false; - break; // Ensemble does not use base velocity - - case SET_VELOCITY: - sprintf(buff, "SETPARM @%d, 102, %.*f", //DefaultSpeed - axis, maxdigits, cntrl_units); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - - rtnval = (RTN_STATUS) motor_start_trans_com(mr, Ensemble_cards); - sprintf(buff, "SETPARM @%d, 107, %.*f", //HomeFeedRate - axis, maxdigits, cntrl_units); - motor_call->type = Ensemble_table[command]; - break; - - case SET_ACCEL: - sprintf(buff, "SETPARM @%d, 103, %.*f", //DefaultRampRate - axis, maxdigits, cntrl_units); - break; - - case GO: - /* - * The Ensemble starts moving immediately on move commands, GO command - * does nothing - */ - send = false; - break; - - case SET_ENC_RATIO: - //sprintf(buff, "SETPARM @%d, 3, %.*f", //PosScaleFactor - // axis, maxdigits, cntrl_units); - send = false; - break; - - case GET_INFO: - /* - * These commands are not actually done by sending a message, but - * rather they will indirectly cause the driver to read the status - * of all motors - */ - break; - - case STOP_AXIS: - sprintf(buff, "ABORT @%d", axis); - break; - - case JOG_VELOCITY: - case JOG: - sprintf(buff, "FREERUN @%d %.*f", axis, maxdigits, cntrl_units); - break; - - case SET_PGAIN: - sprintf(buff, "SETPARM @%d, 8, %.*f", //GainKp - axis, maxdigits, dval); - break; - - case SET_IGAIN: - sprintf(buff, "SETPARM @%d, 7, %.*f", //GainKi - axis, maxdigits, dval); - break; - - case SET_DGAIN: - sprintf(buff, "SETPARM @%d, 12, %.*f", //GainKpi - axis, maxdigits, dval); // which gain?? - break; - - case ENABLE_TORQUE: - sprintf(buff, "ENABLE @%d", axis); - break; - - case DISABL_TORQUE: - sprintf(buff, "DISABLE @%d", axis); - break; - - case PRIMITIVE: - if (mr->init != NULL && strlen(mr->init) != 0) - { - strcat(motor_call->message, mr->init); - } - break; - - case SET_HIGH_LIMIT: - case SET_LOW_LIMIT: - send = false; - break; - - case SET_RESOLUTION: - sprintf(buff, "SETPARM @%d, 3, %.*f", //PosScaleFactor - axis, maxdigits, 1 / cntrl_units); - break; - - default: - send = false; - rtnval = ERROR; - } - - if (send == true) - { - size = strlen (buff); - if (size > sizeof(buff) || (strlen(motor_call->message) + size) > MAX_MSG_SIZE) - { - errlogMessage("Ensemble_build_trans(): buffer overflow.\n"); - } - else - { - strcat(motor_call->message, buff); - motor_end_trans_com(mr, drvtabptr); - } - } - - return(rtnval); -} diff --git a/motorApp/AerotechSrc/drvEnsemble.cc b/motorApp/AerotechSrc/drvEnsemble.cc deleted file mode 100644 index ba664dbd..00000000 --- a/motorApp/AerotechSrc/drvEnsemble.cc +++ /dev/null @@ -1,750 +0,0 @@ -/* -FILENAME... drvEnsemble.cc -USAGE... Motor record driver level support for Aerotech Ensemble. - -Version: $Revision$ -Modified By: $Author$ -Last Modified: $Date$ -HeadURL: $URL$ -*/ - -/* - * Original Author: Chad Weimer - * Date: 04/04/08 - * Current Author: Chad Weimer - * - * 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 - * - * NOTES - * ----- - * Verified with firmware: - * - ver: 2.5.2 - * - * Modification Log: - * ----------------- - * .01 04-04-08 caw initialized from drvMM4000.cc (Newport) - * .02 05-01-09 rls - Using EOT fault indicators rather than LS's to set - * RA_PLUS/MINUS_LS indicators. - * - Fix HOME_LIMIT/MARKER_BIT mask. - * - More extensive comm. error checks in set_status(); handle - * ASCII_ACK_CHAR as error. - * - cntrl->drive_resolution must be initialized with fabs(). - * .03 03-02-10 rls - Use sign(drive_resolution) to determine +/- limit switch - * status. Removed reading controller's soft limits; see - * README file. This version is depreciated; use the asyn - * motor version. - */ - - -#include -#include -#include -#include -#include -#include -#include "motor.h" -#include "drvEnsemble.h" -#include "asynOctetSyncIO.h" -#include "epicsExport.h" - -/* Status byte bits */ -#define ENABLED_BIT 0x00000001 -#define IN_POSITION_BIT 0x00000004 -#define IN_MOTION_BIT 0x00000008 -#define DIRECTION_BIT 0x00000200 -#define HOME_LIMIT_BIT 0x01000000 -#define HOME_MARKER_BIT 0x02000000 - -/* Fault status bits */ -#define CW_FAULT_BIT 0x004 -#define CCW_FAULT_BIT 0x008 - -// This can really be any number, because there isn't any theoretical -// restriction on the number of Ensembles that can be on a network. -// However, a relatively low number was picked for practical purposes -#define Ensemble_NUM_CARDS 10 - -// Due to the way some of the commands are implemented in the Ensemble, -// such as HOME, the command response is not returned until the command -// has actually finished executing. This requires a fairly large timeout -// value. However, even a large value will not guarantee that the response will -// be sent back in the time alloted. -#define TIMEOUT 20.0 /* Command timeout in sec. */ - -/*----------------debugging-----------------*/ -#ifdef __GNUG__ - #ifdef DEBUG - #define Debug(l, f, args...) { if(l<=drvEnsembledebug) printf(f,## args); } - #else - #define Debug(l, f, args...) - #endif -#else - #define Debug() -#endif -volatile int drvEnsembledebug = 0; -extern "C" {epicsExportAddress(int, drvEnsembledebug);} - -/* --- Local data. --- */ -int Ensemble_num_cards = 0; -int num_cmds = 0; - -/* Local data required for every driver; see "motordrvComCode.h" */ -#include "motordrvComCode.h" - - - -/*----------------functions-----------------*/ -static int recv_mess(int, char *, int); -static RTN_STATUS send_mess(int, char const *, char *name); -static int set_status(int card, int signal); -static long report(int level); -static long init(); -static int motor_init(); -static void query_done(int, int, struct mess_node *); - -/*----------------functions-----------------*/ - -struct driver_table Ensemble_access = -{ - motor_init, - motor_send, - motor_free, - motor_card_info, - motor_axis_info, - &mess_queue, - &queue_lock, - &free_list, - &freelist_lock, - &motor_sem, - &motor_state, - &total_cards, - &any_motor_in_motion, - send_mess, - recv_mess, - set_status, - query_done, - NULL, - &initialized, - NULL -}; - -struct drvEnsemble_drvet -{ - long number; - long (*report) (int); - long (*init) (void); -} drvEnsemble = {2, report, init}; - -extern "C" {epicsExportAddress(drvet, drvEnsemble);} - -static struct thread_args targs = {SCAN_RATE, &Ensemble_access, 0.0}; - -/********************************************************* - * Print out driver status report - *********************************************************/ -static long report(int level) -{ - int card; - - if (Ensemble_num_cards <=0) - printf(" No Ensemble controllers configured.\n"); - else - { - for (card = 0; card < Ensemble_num_cards; card++) - { - struct controller *brdptr = motor_state[card]; - - if (brdptr == NULL) - printf(" Ensemble controller %d connection failed.\n", card); - else - { - struct Ensemblecontroller *cntrl; - - cntrl = (struct Ensemblecontroller *) brdptr->DevicePrivate; - printf(" Ensemble controller %d, port=%s, address=%d, id: %s \n", - card, cntrl->asyn_port, cntrl->asyn_address, - brdptr->ident); - } - } - } - return(OK); -} - - -static long init() -{ - /* - * We cannot call motor_init() here, because that function can do GPIB I/O, - * and hence requires that the drvGPIB have already been initialized. - * That cannot be guaranteed, so we need to call motor_init from device - * support - */ - /* Check for setup */ - if (Ensemble_num_cards <= 0) - { - Debug(1, "init(): Ensemble driver disabled. EnsembleSetup() missing from startup script.\n"); - } - return((long) 0); -} - - -static void query_done(int card, int axis, struct mess_node *nodeptr) -{ -} - - -/************************************************************** - * Parse status and position strings for a card and signal - * set_status() - ************************************************************/ - -static int set_status(int card, int signal) -{ - struct Ensemblecontroller *cntrl; - struct mess_node *nodeptr; - register struct mess_info *motor_info; - double motorData, pfbk; - bool plusdir, ls_active = false; - msta_field status; - int rtn_state, comm_status, axis_status; - char buff[BUFF_SIZE]; - - cntrl = (struct Ensemblecontroller *) motor_state[card]->DevicePrivate; - motor_info = &(motor_state[card]->motor_info[signal]); - status.All = motor_info->status.All; - - // get the axis status - sprintf(buff, "AXISSTATUS(@%d)", signal); - send_mess(card, buff, (char) NULL); - comm_status = recv_mess(card, buff, 1); - - if (comm_status > 0 && buff[0] == ASCII_ACK_CHAR) - { - cntrl->status = NORMAL; - status.Bits.CNTRL_COMM_ERR = 0; - } - else if (comm_status <= 0) - { - if (cntrl->status == NORMAL) - { - cntrl->status = RETRY; - rtn_state = OK; - } - else - { - cntrl->status = COMM_ERR; - status.Bits.CNTRL_COMM_ERR = 1; - status.Bits.RA_PROBLEM = 1; - rtn_state = 1; - } - goto exit; - } - else if (buff[0] != ASCII_ACK_CHAR) - { - cntrl->status = COMM_ERR; - status.Bits.CNTRL_COMM_ERR = 1; - status.Bits.RA_PROBLEM = 1; - rtn_state = 1; - goto exit; - } - - cntrl->status = NORMAL; - status.Bits.CNTRL_COMM_ERR = 0; - - // convert to an integer - axis_status = atoi(&buff[1]); - - nodeptr = motor_info->motor_motion; - - status.Bits.EA_SLIP = 0; - status.Bits.EA_SLIP_STALL = 0; - - // fill in the status - if (cntrl->drive_resolution[signal] > 0.0) - status.Bits.RA_DIRECTION = axis_status & DIRECTION_BIT ? 1 : 0; - else - status.Bits.RA_DIRECTION = axis_status & DIRECTION_BIT ? 0 : 1; - - status.Bits.RA_DONE = axis_status & IN_POSITION_BIT ? 1 : 0; - status.Bits.RA_HOME = axis_status & HOME_LIMIT_BIT ? 1 : 0; - status.Bits.EA_POSITION = axis_status & ENABLED_BIT ? 1 : 0; - status.Bits.EA_HOME = axis_status & HOME_MARKER_BIT ? 1 : 0; - status.Bits.RA_MOVING = axis_status & IN_MOTION_BIT ? 1 : 0; - - /* get the axis fault status */ - sprintf(buff, "AXISFAULT(@%d)", signal); - send_mess(card, buff, (char) NULL); - comm_status = recv_mess(card, buff, 1); - axis_status = atoi(&buff[1]); - if (cntrl->drive_resolution[signal] > 0.0) - { - status.Bits.RA_PLUS_LS = axis_status & CW_FAULT_BIT ? 1 : 0; - status.Bits.RA_MINUS_LS = axis_status & CCW_FAULT_BIT ? 1 : 0; - } - else - { - status.Bits.RA_PLUS_LS = axis_status & CCW_FAULT_BIT ? 1 : 0; - status.Bits.RA_MINUS_LS = axis_status & CW_FAULT_BIT ? 1 : 0; - } - - plusdir = status.Bits.RA_DIRECTION ? true : false; - if ((status.Bits.RA_PLUS_LS && plusdir) || (status.Bits.RA_MINUS_LS && !plusdir)) - { - ls_active = true; - } - - // get the position - sprintf(buff, "PFBKPROG(@%d)", signal); - send_mess(card, buff, (char) NULL); - recv_mess(card, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - { - // convert to an integer - pfbk = atof(&buff[1]); - } - else - { - pfbk = 0; - } - - // fill in the position - motorData = pfbk / fabs(cntrl->drive_resolution[signal]); - - if (motorData == motor_info->position) - { - // only increment the counter if the motor is moving - if (nodeptr != 0) - { - motor_info->no_motion_count++; - } - } - else - { - motor_info->position = NINT(motorData); - if (motor_info->encoder_present == YES) - { - motor_info->encoder_position = NINT(motorData); - } - else - { - motor_info->encoder_position = 0; - } - - motor_info->no_motion_count = 0; - } - - // velocity is not used, so don't bother doing a command down - // to the controller to get it - motor_info->velocity = 0; - - // do this "last", so that we know no errors occurred - status.Bits.RA_PROBLEM = 0; - - rtn_state = (!motor_info->no_motion_count || ls_active || - status.Bits.RA_DONE | status.Bits.RA_PROBLEM) ? 1 : 0; - - // test for post-move string - if ((status.Bits.RA_DONE || ls_active) && nodeptr != 0 && nodeptr->postmsgptr != 0) - { - strcpy(buff, nodeptr->postmsgptr); - send_mess(card, buff, (char) NULL); - nodeptr->postmsgptr = NULL; - } - -exit: - motor_info->status.All = status.All; - return(rtn_state); -} - - -/*****************************************************/ -/* send a message to the Ensemble board */ -/* send_mess() */ -/*****************************************************/ -static RTN_STATUS send_mess(int card, char const *com, char *name) -{ - struct Ensemblecontroller *cntrl; - int size; - size_t nwrite; - char *eos_tok, com_cpy[BUFF_SIZE]; - asynStatus status; - - size = strlen(com); - - if (size > MAX_MSG_SIZE) - { - errlogMessage("drvEnsemble.c:send_mess(); message size violation.\n"); - return(ERROR); - } - else if (size == 0) - { - return(OK); - } - - if (!motor_state[card]) - { - errlogMessage("drvEnsemble.c:send_mess() - invalid card #%d\n"); - return(ERROR); - } - - if (name != NULL) - { - errlogMessage("drvEnsemble.c:send_mess() - invalid argument = %s\n"); - return(ERROR); - } - - Debug(2, "send_mess(): message = %s\n", com); - - // We need to track the number of individual Ensemble commands that are - // being sent, so that we can read back the same number of responses. - // This is necessary, because the Ensemble will send individual responses - // terminated by the EOS char for each command sent, even if those commands - // were all sent as part of one motor record command, such as LOAD_POS - - num_cmds = 0; - strcpy(com_cpy, com); - eos_tok = strtok(com_cpy, ASCII_EOS_STR); - while (eos_tok != NULL) - { - num_cmds++; - eos_tok = strtok(NULL, ASCII_EOS_STR); - } - - cntrl = (struct Ensemblecontroller *) motor_state[card]->DevicePrivate; - - status = pasynOctetSyncIO->write(cntrl->pasynUser, com, size, TIMEOUT, &nwrite); - - if (status != asynSuccess || nwrite <= 0) - { - errlogMessage(cntrl->pasynUser->errorMessage); - return(ERROR); - } - - return(OK); -} - - -/* - * FUNCTION... recv_mess(int card, char *com, int flag) - * - * INPUT ARGUMENTS... - * card - controller card # (0,1,...). - * *com - caller's response buffer. - * flag | FLUSH = flush controller's output buffer; set timeout = 0. - * | !FLUSH = retrieve response into caller's buffer; set timeout. - * - * LOGIC... - * IF controller card does not exist. - * ERROR RETURN. - * ENDIF - * NORMAL RETURN. - */ - -static int recv_mess(int card, char *com, int flag) -{ - struct Ensemblecontroller *cntrl; - double timeout = 0; - size_t nread = 0; - asynStatus status; - int eomReason, i; - char buff[BUFF_SIZE]; - - if (!motor_state[card]) - { - return(ERROR); - } - - cntrl = (struct Ensemblecontroller *) motor_state[card]->DevicePrivate; - - timeout = TIMEOUT; - com[0] = '\0'; - for (i = 0; i < num_cmds; i++) - { - status = pasynOctetSyncIO->read(cntrl->pasynUser, buff, BUFF_SIZE, timeout, &nread, &eomReason); - - if (status == asynSuccess && nread > 0) - { - strcat(com, buff); - } - else - { - com[0] = '\0'; - nread = 0; - break; - } - } - - Debug(2, "recv_mess(): message = \"%s\"\n", com); - return(nread); -} - - -/*****************************************************/ -/* Setup system configuration */ -/* EnsembleSetup() */ -/*****************************************************/ -RTN_STATUS EnsembleSetup(int num_cards, /* maximum number of controllers in system. */ - int scan_rate) /* polling rate - 1/60 sec units. */ -{ - int i; - - if (num_cards < 1 || num_cards > Ensemble_NUM_CARDS) - { - Ensemble_num_cards = Ensemble_NUM_CARDS; - } - else - { - Ensemble_num_cards = num_cards; - } - - // Set motor polling task rate - if (scan_rate >= 1 && scan_rate <= 60) - { - targs.motor_scan_rate = scan_rate; - } - else - { - targs.motor_scan_rate = SCAN_RATE; - } - - /* - * Allocate space for motor_state structures. Note this must be done - * before EnsembleConfig is called, so it cannot be done in motor_init() - * This means that we must allocate space for a card without knowing - * if it really exists, which is not a serious problem - */ - motor_state = (struct controller **) malloc(Ensemble_num_cards * sizeof(struct controller *)); - - for (i = 0; i < Ensemble_num_cards; i++) - { - motor_state[i] = (struct controller *) NULL; - } - - return(OK); -} - - -/*****************************************************/ -/* Configure a controller */ -/* EnsembleConfig() */ -/*****************************************************/ -RTN_STATUS EnsembleConfig(int card, /* card being configured */ - const char *name, /* asyn port name */ - int addr) /* asyn address (GPIB) */ -{ - struct Ensemblecontroller *cntrl; - - if (card < 0 || card >= Ensemble_num_cards) - { - return(ERROR); - } - - motor_state[card] = (struct controller *) malloc(sizeof(struct controller)); - motor_state[card]->DevicePrivate = malloc(sizeof(struct Ensemblecontroller)); - cntrl = (struct Ensemblecontroller *) motor_state[card]->DevicePrivate; - - strcpy(cntrl->asyn_port, name); - cntrl->asyn_address = addr; - - return(OK); -} - - - -/*****************************************************/ -/* initialize all software and hardware */ -/* This is called from the initialization routine in */ -/* device support. */ -/* motor_init() */ -/*****************************************************/ -static int motor_init() -{ - struct controller *brdptr; - struct Ensemblecontroller *cntrl; - int card_index, motor_index, status, digits; - char buff[BUFF_SIZE]; - asynStatus success_rtn; - - // Indicates that the driver is initialized - initialized = true; - - if (Ensemble_num_cards <= 0) - return(ERROR); - - for (card_index = 0; card_index < Ensemble_num_cards; card_index++) - { - int retry = 0; - - if (!motor_state[card_index]) - continue; - - brdptr = motor_state[card_index]; - brdptr->cmnd_response = true; - total_cards = card_index + 1; - cntrl = (struct Ensemblecontroller *)brdptr->DevicePrivate; - - // Initialize communications channel - success_rtn = pasynOctetSyncIO->connect(cntrl->asyn_port, cntrl->asyn_address, &cntrl->pasynUser, NULL); - - if (success_rtn != asynSuccess) - continue; - - // Send a message to the baord, see if it exists - // flush any junk at input port - should not be any data available - pasynOctetSyncIO->flush(cntrl->pasynUser); - - do - { - // we only care if we get a response - // so we don't need to send a valid command - strcpy(buff, "NONE"); - send_mess(card_index, buff, (char) NULL); - status = recv_mess(card_index, buff, 1); - retry++; - } while (!status && retry < 3); - - if (status > 0) - { - brdptr->localaddr = (char *) NULL; - brdptr->motor_in_motion = 0; - // Read controller ID string - strcpy(buff, "GETPARM(CONTROL, 265)"); //UserString1 - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - strcpy(brdptr->ident, &buff[1]); - else - sprintf(brdptr->ident, "Ensemble%d", card_index); - - // Get the number of axes - brdptr->total_axis = 0; - for (motor_index = 0; motor_index < 10; motor_index++) - { - // Does this axis actually exist? - sprintf(buff, "GETPARM(@%d, 257)", motor_index); //AxisName - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - - // We know the axis exists if we got an ACK response - if (buff[0] == ASCII_ACK_CHAR) - { - cntrl->axes[motor_index] = 1; - brdptr->total_axis++; - } - } - - for (motor_index = 0; motor_index < 10; motor_index++) - { - if (cntrl->axes[motor_index]) - { - struct mess_info *motor_info = &brdptr->motor_info[motor_index]; - - motor_info->status.All = 0; - motor_info->no_motion_count = 0; - motor_info->encoder_position = 0; - motor_info->position = 0; - brdptr->motor_info[motor_index].motor_motion = NULL; - - // Determine if encoder present based on open/closed loop mode. - sprintf(buff, "GETPARM(@%d, 58)", motor_index); //CfgFbkPosType - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - { - if (atoi(&buff[1]) > 0) - { - motor_info->encoder_present = YES; - motor_info->status.Bits.EA_PRESENT = 1; - } - } - - // Determine if gains are supported based on the motor type. - sprintf(buff, "GETPARM(@%d, 33)", motor_index); //CfgMotType - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - { - if (atoi(&buff[1]) != 3) - { - motor_info->pid_present = YES; - motor_info->status.Bits.GAIN_SUPPORT = 1; - } - } - - // Stop all motors - sprintf(buff, "ABORT @%d", motor_index); - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - - // Determive drive resolution - sprintf(buff, "GETPARM(@%d, 3)", motor_index); //PosScaleFactor - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - cntrl->drive_resolution[motor_index] = 1 / atof(&buff[1]); - else - cntrl->drive_resolution[motor_index] = 1; - - digits = (int) -log10(fabs(cntrl->drive_resolution[motor_index])) + 2; - if (digits < 1) - digits = 1; - cntrl->res_decpts[motor_index] = digits; - - // Save home preset position - sprintf(buff, "GETPARM(@%d, 108)", motor_index); //HomeOffset - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - cntrl->home_preset[motor_index] = atof(&buff[1]); - - // Save the HomeDirection parameter - sprintf(buff, "GETPARM(@%d, 106)", motor_index); //HomeDirection - send_mess(card_index, buff, (char) NULL); - recv_mess(card_index, buff, 1); - if (buff[0] == ASCII_ACK_CHAR) - cntrl->home_dparam[motor_index] = atoi(&buff[1]); - - // Read status of each motor - set_status(card_index, motor_index); - } - } - } - else - motor_state[card_index] = (struct controller *) NULL; - } - - any_motor_in_motion = 0; - - mess_queue.head = (struct mess_node *) NULL; - mess_queue.tail = (struct mess_node *) NULL; - - free_list.head = (struct mess_node *) NULL; - free_list.tail = (struct mess_node *) NULL; - - epicsThreadCreate((char *) "Ensemble_motor", - epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - (EPICSTHREADFUNC) motor_task, (void *) &targs); - - return(OK); -} - diff --git a/motorApp/AerotechSrc/drvEnsemble.h b/motorApp/AerotechSrc/drvEnsemble.h deleted file mode 100644 index b8e5fd56..00000000 --- a/motorApp/AerotechSrc/drvEnsemble.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -FILENAME... drvEnsemble.h -USAGE... This file contains Aerotech Ensemble driver "include" information. - -Version: $Revision$ -Modified By: $Author$ -Last Modified: $Date$ -HeadURL: $URL$ -*/ - -/* - * Original Author: Chad Weimer - * Date: 10/16/97 - * - * 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: - * ----------------- - * .00 04-01-08 caw initialized from drvMM4000.h (Newport) - */ - -#ifndef INCdrvEnsembleh -#define INCdrvEnsembleh 1 - -#include "motor.h" -#include "motordrvCom.h" -#include "asynDriver.h" -#include "asynOctetSyncIO.h" - - -// The following should be defined to have the same value as -// the Ensemble parameters specified -#define ASCII_EOS_CHAR '\n' // AsciiCmdEOSChar -#define ASCII_EOS_STR "\n" -#define ASCII_ACK_CHAR '%' // AsciiCmdAckChar -#define ASCII_NAK_CHAR '!' // AsciiCmdNakChar -#define ASCII_FAULT_CHAR '#' // AsciiCmdFaultChar -#define ASCII_TIMEOUT_CHAR '$' // AsciiCmdTimeoutChar - -#define BUFF_SIZE 100 /* Maximum length of string to/from Ensemble */ - - -/* Ensemble specific data is stored in this structure. */ -struct Ensemblecontroller -{ - asynUser *pasynUser; /* For RS-232/Ethernet */ - int asyn_address; /* Use for GPIB or other address with asyn */ - char asyn_port[80]; /* asyn port name */ - int axes[MAX_AXIS]; - double drive_resolution[MAX_AXIS]; - int res_decpts[MAX_AXIS]; /* Drive resolution significant dec. pts. */ - double home_preset[MAX_AXIS]; /* Controller's home preset position (XF command). */ - epicsUInt32 home_dparam[MAX_AXIS]; /* Controller's HomeDirection parameter. */ - CommStatus status; /* Controller communication status. */ -}; - -/* Function prototypes. */ -extern RTN_STATUS EnsembleSetup(int, int); -extern RTN_STATUS EnsembleConfig(int, const char *, int); - - -#endif /* INCdrvEnsembleh */ -