diff --git a/.gitmodules b/.gitmodules index 41e7f055..f1c9286b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "modules/motorDeltaTau"] path = modules/motorDeltaTau url = https://github.com/epics-motor/motorDeltaTau.git +[submodule "modules/motorFaulhaber"] + path = modules/motorFaulhaber + url = https://github.com/epics-motor/motorFaulhaber.git diff --git a/iocBoot/iocWithAsyn/st.cmd.Vx b/iocBoot/iocWithAsyn/st.cmd.Vx index 8bfd7743..804a0e64 100644 --- a/iocBoot/iocWithAsyn/st.cmd.Vx +++ b/iocBoot/iocWithAsyn/st.cmd.Vx @@ -173,22 +173,6 @@ dbLoadRecords("$(MOTOR)/db/motorUtil.db", "P=IOC:") #!SC800Config(0, "L0", 0) #!drvSC800debug=4 -# Faulhaber MCDC2805 driver setup parameters: -# (1)Max. controller count -# (2)Polling rate -#!MCDC2805Setup(1, 10) - -# Faulhaber MCDC2805 driver configuration parameters: -# (1)Card being configured -# (2)# modules on this serial port -# (3)asyn port name -#!MCDC2805Config(0, 1, "L0") -#!drvMCDC2805debug=4 - -# The MCDC2805 driver does not set end of string (EOS). -#!asynOctetSetInputEos("L0",0,"\r") -#!asynOctetSetOutputEos("L0",0,"\r") - # Aerotech Ensemble digital servo controller Setup # (1) maximum number of controllers in system diff --git a/iocBoot/iocWithAsyn/st.cmd.unix b/iocBoot/iocWithAsyn/st.cmd.unix index 93a3b5a3..3c19cf66 100644 --- a/iocBoot/iocWithAsyn/st.cmd.unix +++ b/iocBoot/iocWithAsyn/st.cmd.unix @@ -129,22 +129,6 @@ asynSetOption("L0", -1, "crtscts", "N") #!SC800Config(0, "L0", 0) #!var drvSC800debug 4 -# Faulhaber MCDC2805 driver setup parameters: -# (1)Max. controller count -# (2)Polling rate -#!MCDC2805Setup(1, 10) - -# Faulhaber MCDC2805 driver configuration parameters: -# (1)Card being configured -# (2)# modules on this serial port -# (3)asyn port name -#!MCDC2805Config(0, 1, "L0") -#!var drvMCDC2805debug 4 - -# The MCDC2805 driver does not set end of string (EOS). -#!asynOctetSetInputEos("L0",0,"\r") -#!asynOctetSetOutputEos("L0",0,"\r") - # Aerotech Ensemble digital servo controller Setup # (1) maximum number of controllers in system diff --git a/iocBoot/iocWithAsyn/st.cmd.win32 b/iocBoot/iocWithAsyn/st.cmd.win32 index dad4d231..5f817076 100755 --- a/iocBoot/iocWithAsyn/st.cmd.win32 +++ b/iocBoot/iocWithAsyn/st.cmd.win32 @@ -95,23 +95,6 @@ dbLoadRecords("$(MOTOR)/db/motorUtil.db", "P=IOC:") #!MDriveConfig(0, "L0") #!var drvMDrivedebug 4 -# Faulhaber MCDC2805 driver setup parameters: -# (1)Max. controller count -# (2)Polling rate -#!MCDC2805Setup(1, 10) - -# Faulhaber MCDC2805 driver configuration parameters: -# (1)Card being configured -# (2)# modules on this serial port -# (3)asyn port name -#!MCDC2805Config(0, 1, "L0") -#!var drvMCDC2805debug 4 - -# The MCDC2805 driver does not set end of string (EOS). -#!asynOctetSetInputEos("L0",0,"\r") -#!asynOctetSetOutputEos("L0",0,"\r") - - # Aerotech Ensemble digital servo controller Setup # (1) maximum number of controllers in system # (2) motor task polling rate (min=1Hz,max=60Hz) diff --git a/modules/Makefile b/modules/Makefile index ff617688..1b1ba24d 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -8,6 +8,7 @@ SUBMODULES += motorNewport SUBMODULES += motorAcsTech80 SUBMODULES += motorAttocube SUBMODULES += motorDeltaTau +SUBMODULES += motorFaulhaber # Allow sites to add extra submodules -include Makefile.local diff --git a/modules/motorFaulhaber b/modules/motorFaulhaber new file mode 160000 index 00000000..e4bf561d --- /dev/null +++ b/modules/motorFaulhaber @@ -0,0 +1 @@ +Subproject commit e4bf561d14f36d2c5f35009abb1ca6f90af35ea3 diff --git a/motorApp/FaulhaberSrc/Makefile b/motorApp/FaulhaberSrc/Makefile deleted file mode 100644 index da7b4581..00000000 --- a/motorApp/FaulhaberSrc/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Makefile -TOP = ../.. -include $(TOP)/configure/CONFIG - -# The following are used for debugging messages. -#USR_CXXFLAGS += -DDEBUG - -DBD += devFaulhaberMotor.dbd - -LIBRARY_IOC = Faulhaber - -# Intelligent Motion Systems driver support. -SRCS += devMCDC2805.cc drvMCDC2805.cc - -Faulhaber_LIBS += motor asyn -Faulhaber_LIBS += $(EPICS_BASE_IOC_LIBS) - -include $(TOP)/configure/RULES - diff --git a/motorApp/FaulhaberSrc/README b/motorApp/FaulhaberSrc/README deleted file mode 100644 index 945b377c..00000000 --- a/motorApp/FaulhaberSrc/README +++ /dev/null @@ -1,52 +0,0 @@ - Faulhaber MCDC2805 driver - Mark Rivers - Nov. 4, 2005 - -This driver supports the Faulhaber MCDC2805 servo controller. - -It assumes the following wiring: - Analog input = Input 1 = Home input - Fault pin = Input 2 = CW limit - Input 3 Input 3 = CCW limit - -There is a currently a problem with the Home input, and its status cannot be read. The reason for this -is being investigated, but until it is resolved the home functions in the motor record do not work. - -The following commands are send to the MCDC2805 when the EPICS software initializes: - -/* Set the velocity control to be RS-232 */ -SOR 0 - -/* Program fault pin as limit switch input */ -REFIN - -/* Program limit polarity for rising edge and high level */ -HP7 - -/* Program the motor to hard block on the the limit switch inputs */ -HB6 - -/* Program the limit switch directions to block - * + direction on input 2, - direction on input 3 */ -HD2 - -/* Program homing sequence on input 1*/ -HL1 -HA1 -CAHOSEQ - -It is a good idea to set the power-up behavior of the device to be "disabled" by sending the following -commands once: -DI -EEPSAV - -It is also necessary to change the address of the board from the default address of 0 if daisy chaining -multiple modules. To change to address 1, send the following commands once: - -NODEADR 1 -EEPSAV - - - - - diff --git a/motorApp/FaulhaberSrc/devFaulhaberMotor.dbd b/motorApp/FaulhaberSrc/devFaulhaberMotor.dbd deleted file mode 100644 index 3b9e8f74..00000000 --- a/motorApp/FaulhaberSrc/devFaulhaberMotor.dbd +++ /dev/null @@ -1,5 +0,0 @@ -# Intelligent Motion Systems driver support. -device(motor,VME_IO,devMCDC2805, "MCDC2805") -driver(drvMCDC2805) -registrar(MCDC2805Register) -variable(drvMCDC2805debug) diff --git a/motorApp/FaulhaberSrc/devMCDC2805.cc b/motorApp/FaulhaberSrc/devMCDC2805.cc deleted file mode 100644 index ffce31de..00000000 --- a/motorApp/FaulhaberSrc/devMCDC2805.cc +++ /dev/null @@ -1,346 +0,0 @@ -/* -FILENAME... devMCDC2805.cc -USAGE... Motor record device level support for Intelligent Motion - Systems, Inc. MCDC2805 series of controllers. - -*/ - -/* - * Original Author: Mark Rivers - * Date: 10/20/05 - * - * 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 10/20/05 mlr Initialize from ImsSrc/devMDrive.cc - */ - -#include -#include - -#include "motorRecord.h" -#include "motor.h" -#include "motordevCom.h" -#include "drvMCDC2805.h" -#include "epicsExport.h" - -#define STATIC static - -extern struct driver_table MCDC2805_access; - -/* ----------------Create the dsets for devMCDC2805----------------- */ -STATIC struct driver_table *drvtabptr; -STATIC long MCDC2805_init(int); -STATIC long MCDC2805_init_record(void *); -STATIC long MCDC2805_start_trans(struct motorRecord *); -STATIC RTN_STATUS MCDC2805_build_trans(motor_cmnd, double *, struct motorRecord *); -STATIC RTN_STATUS MCDC2805_end_trans(struct motorRecord *); - -struct motor_dset devMCDC2805 = -{ - {8, NULL, (DEVSUPFUN) MCDC2805_init, (DEVSUPFUN) MCDC2805_init_record, NULL}, - motor_update_values, - MCDC2805_start_trans, - MCDC2805_build_trans, - MCDC2805_end_trans -}; - -extern "C" {epicsExportAddress(dset,devMCDC2805);} - -/* --------------------------- program data --------------------- */ - -/* This table is used to define the command types */ -/* WARNING! this must match "motor_cmnd" in motor.h */ - -static msg_types MCDC2805_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 */ -}; - - -static struct board_stat **MCDC2805_cards; - -/* --------------------------- program data --------------------- */ - - -/* initialize device support for MCDC2805 stepper motor */ -STATIC long MCDC2805_init(int after) -{ - long rtnval; - - if (!after) - { - drvtabptr = &MCDC2805_access; - (drvtabptr->init)(); - } - - rtnval = motor_init_com(after, *drvtabptr->cardcnt_ptr, drvtabptr, &MCDC2805_cards); - return(rtnval); -} - - -/* initialize a record instance */ -STATIC long MCDC2805_init_record(void *arg) -{ - struct motorRecord *mr = (struct motorRecord *) arg; - return(motor_init_record_com(mr, *drvtabptr->cardcnt_ptr, drvtabptr, MCDC2805_cards)); -} - - -/* start building a transaction */ -STATIC long MCDC2805_start_trans(struct motorRecord *mr) -{ - return(OK); -} - - -/* end building a transaction */ -STATIC RTN_STATUS MCDC2805_end_trans(struct motorRecord *mr) -{ - return(OK); -} - - -/* add a part to the transaction */ -STATIC RTN_STATUS MCDC2805_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 MCDC2805controller *cntrl; - char buff[110]; - int axis, card, intval; - int rpm; - unsigned int size; - RTN_STATUS rtnval; - bool send; - msta_field msta; - - send = true; /* Default to send motor command. */ - rtnval = OK; - buff[0] = '\0'; - - /* Protect against NULL pointer with WRTITE_MSG(GO/STOP_AXIS/GET_INFO, NULL). */ - intval = (parms == NULL) ? 0 : NINT(parms[0]); - - msta.All = mr->msta; - - motor_start_trans_com(mr, MCDC2805_cards); - - motor_call = &(trans->motor_call); - card = motor_call->card; - axis = motor_call->signal + 1; - brdptr = (*trans->tabptr->card_array)[card]; - if (brdptr == NULL) - return(rtnval = ERROR); - - cntrl = (struct MCDC2805controller *) brdptr->DevicePrivate; - - if (MCDC2805_table[command] > motor_call->type) - motor_call->type = MCDC2805_table[command]; - - if (trans->state != BUILD_STATE) - return(rtnval = ERROR); - - if (command == PRIMITIVE && mr->init != NULL && strlen(mr->init) != 0) - { - strcat(motor_call->message, " "); - strcat(motor_call->message, mr->init); - } - - switch (command) - { - case MOVE_ABS: - case MOVE_REL: - case HOME_FOR: - case HOME_REV: - case JOG: - if (strlen(mr->prem) != 0) - { - strcat(motor_call->message, mr->prem); - strcat(motor_call->message, " "); - } - if (strlen(mr->post) != 0) - motor_call->postmsgptr = (char *) &mr->post; - break; - - default: - break; - } - - - switch (command) - { - case MOVE_ABS: - sprintf(buff, "LA %d", intval); - break; - - case MOVE_REL: - sprintf(buff, "LR %d", intval); - break; - - case HOME_FOR: - case HOME_REV: - rpm = NINT(mr->velo / mr->srev * 60.); - if (command == HOME_REV) rpm = -rpm; - /* Need to send multiple messages */ - sprintf(buff, "ENCRES%d", mr->srev); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - rtnval = (RTN_STATUS) motor_start_trans_com(mr, MCDC2805_cards); - sprintf(buff, "HOSP%d", rpm); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - rtnval = (RTN_STATUS) motor_start_trans_com(mr, MCDC2805_cards); - sprintf(buff, "GOHOSEQ"); - motor_call->type = MCDC2805_table[command]; - break; - - case LOAD_POS: - sprintf(buff, "HO %d", intval); - break; - - case SET_VEL_BASE: - /* Not supported */ - send = false; - break; - - case SET_VELOCITY: - /* The input speed is in steps/second. The controller wants RPM */ - rpm = NINT(parms[0] / mr->srev * 60.); - /* Need to send multiple messages */ - sprintf(buff, "ENCRES%d", mr->srev); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - rtnval = (RTN_STATUS) motor_start_trans_com(mr, MCDC2805_cards); - sprintf(buff, "SP %d", rpm); - motor_call->type = MCDC2805_table[command]; - break; - - case SET_ACCEL: - /* The input speed is in steps/s/s. The controller wants Revs/s/s */ - rpm = NINT(parms[0] / mr->srev); - /* Need to send multiple messages */ - sprintf(buff, "ENCRES%d", mr->srev); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - rtnval = (RTN_STATUS) motor_start_trans_com(mr, MCDC2805_cards); - sprintf(buff, "AC %d", rpm); - motor_call->type = MCDC2805_table[command]; - break; - - case GO: - sprintf(buff, "M"); - break; - - case PRIMITIVE: - 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, "V 0"); - break; - - case JOG_VELOCITY: - case JOG: - rpm = NINT(parms[0] / mr->srev * 60.); - /* Need to send multiple messages */ - sprintf(buff, "ENCRES%d", mr->srev); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - rtnval = (RTN_STATUS) motor_start_trans_com(mr, MCDC2805_cards); - sprintf(buff, "SP %d", rpm); - strcpy(motor_call->message, buff); - rtnval = motor_end_trans_com(mr, drvtabptr); - rtnval = (RTN_STATUS) motor_start_trans_com(mr, MCDC2805_cards); - sprintf(buff, "V %d", rpm); - motor_call->type = MCDC2805_table[command]; - break; - - case SET_PGAIN: - sprintf(buff, "POR %ld", NINT(parms[0]*255.)); - break; - - case SET_IGAIN: - sprintf(buff, "I %ld", NINT(parms[0]*255.)); - break; - - case SET_DGAIN: - send = false; - break; - - case ENABLE_TORQUE: - sprintf(buff, "EN"); - break; - - case DISABL_TORQUE: - sprintf(buff, "DI"); - break; - - case SET_HIGH_LIMIT: - case SET_LOW_LIMIT: - case SET_ENC_RATIO: - trans->state = IDLE_STATE; /* No command sent to the controller. */ - send = false; - break; - - default: - send = false; - rtnval = ERROR; - } - - size = strlen(buff); - if (send == false) - return(rtnval); - else if (size > sizeof(buff) || (strlen(motor_call->message) + size) > MAX_MSG_SIZE) - errlogMessage("MCDC2805_build_trans(): buffer overflow.\n"); - else - { - strcat(motor_call->message, buff); - motor_end_trans_com(mr, drvtabptr); - } - return(rtnval); -} diff --git a/motorApp/FaulhaberSrc/drvMCDC2805.cc b/motorApp/FaulhaberSrc/drvMCDC2805.cc deleted file mode 100644 index 63876c1d..00000000 --- a/motorApp/FaulhaberSrc/drvMCDC2805.cc +++ /dev/null @@ -1,688 +0,0 @@ -/* -FILENAME... drvMCDC2805.cc -USAGE... Motor record driver level support for Faulhaber MCDC2805 - -*/ - -/* - * Original Author: Mark Rivers - * Date: 10/20/2005 - * - * 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 10/20/05 mlr Initialize from ImsDrc/MDrive.cc - */ - -/* -DESIGN LIMITATIONS... - 1 - Like all controllers, the MCDC2805 must be powered-on when EPICS is first - booted up. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "motor.h" -#include "drvMCDC2805.h" -#include "asynOctetSyncIO.h" -#include "epicsExport.h" - -#define MCDC2805_NUM_CARDS 8 -#define BUFF_SIZE 100 /* Maximum length of string to/from MCDC2805 */ - -/*----------------debugging-----------------*/ -volatile int drvMCDC2805debug = 0; -extern "C" {epicsExportAddress(int, drvMCDC2805debug);} - -static inline void Debug(int level, const char *format, ...) { - #ifdef DEBUG - if (level < drvMCDC2805debug) { - va_list pVar; - va_start(pVar, format); - vprintf(format, pVar); - va_end(pVar); - } - #endif -} - -/* --- Local data. --- */ -int MCDC2805_num_cards = 0; -static char *MCDC2805_axis[] = {"0", "1", "2", "3", "4", "5", "6", "7"}; - -/* 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 *); -static int set_status(int, int); -static long report(int); -static long init(); -static int motor_init(); -static void query_done(int, int, struct mess_node *); - -/*----------------functions-----------------*/ - -struct driver_table MCDC2805_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, - MCDC2805_axis -}; - -struct drvMCDC2805_drvet -{ - long number; - long (*report) (int); - long (*init) (void); -} drvMCDC2805 = {2, report, init}; - -extern "C" {epicsExportAddress(drvet, drvMCDC2805);} - -static struct thread_args targs = {SCAN_RATE, &MCDC2805_access, 0.0}; - - -/********************************************************* - * Print out driver status report - *********************************************************/ -static long report(int level) -{ - int card; - - if (MCDC2805_num_cards <=0) - printf(" No MCDC2805 controllers configured.\n"); - else - { - for (card = 0; card < MCDC2805_num_cards; card++) - { - struct controller *brdptr = motor_state[card]; - - if (brdptr == NULL) - printf(" MCDC2805 controller %d connection failed.\n", card); - else - { - struct MCDC2805controller *cntrl; - - cntrl = (struct MCDC2805controller *) brdptr->DevicePrivate; - printf(" MCDC2805SM controller #%d, port=%s, id: %s \n", card, - cntrl->asyn_port, brdptr->ident); - } - } - } - return(OK); -} - - -static long init() -{ - /* - * We cannot call motor_init() here, because that function can do serial I/O, - * and hence requires that the serial port have already been initialized. - * That cannot be guaranteed, so we need to call motor_init from device - * support - */ - /* Check for setup */ - if (MCDC2805_num_cards <= 0) - { - Debug(1, "init(): MCDC2805 driver disabled. MCDC2805Setup() missing from startup script.\n"); - } - return((long) 0); -} - - -static void query_done(int card, int axis, struct mess_node *nodeptr) -{ -} - - -/******************************************************************************** -* * -* FUNCTION NAME: set_status * -* * -* LOGIC: * -* Initialize. * -* Send "Moving Status" query. * -* Read response. * -* IF normal response to query. * -* Set communication status to NORMAL. * -* ELSE * -* IF communication status is NORMAL. * -* Set communication status to RETRY. * -* NORMAL EXIT. * -* ELSE * -* Set communication status error. * -* ERROR EXIT. * -* ENDIF * -* ENDIF * -* * -* IF "Moving Status" indicates any motion (i.e. status != 0). * -* Clear "Done Moving" status bit. * -* ELSE * -* Set "Done Moving" status bit. * -* ENDIF * -* * -* * -********************************************************************************/ - -static int set_status(int card, int signal) -{ - struct MCDC2805controller *cntrl; - struct mess_node *nodeptr; - register struct mess_info *motor_info; - /* Message parsing variables */ - char buff[BUFF_SIZE]; - char status_buff[BUFF_SIZE]; - int rtnval, rtn_state; - double motorData; - epicsUInt8 Lswitch; - bool plusdir, ls_active = false; - msta_field status; - - cntrl = (struct MCDC2805controller *) motor_state[card]->DevicePrivate; - motor_info = &(motor_state[card]->motor_info[signal]); - nodeptr = motor_info->motor_motion; - status.All = motor_info->status.All; - - send_mess(card, "GST", MCDC2805_axis[signal]); - rtn_state = recv_mess(card, status_buff, 1); - if (rtn_state > 0) - { - cntrl->status = NORMAL; - status.Bits.CNTRL_COMM_ERR = 0; - } - else - { - if (cntrl->status == NORMAL) - { - cntrl->status = RETRY; - rtn_state = OK; - goto exit; - } - else - { - cntrl->status = COMM_ERR; - status.Bits.CNTRL_COMM_ERR = 1; - status.Bits.RA_PROBLEM = 1; - rtn_state = 1; - goto exit; - } - } - - rtnval = status_buff[4] == '1'; - - /* We can't use this logic for done, because it won't work in jog mode or when - * a move is stopped by setting velocity=0. */ - - /* status.Bits.RA_DONE = (rtnval == 0) ? 0 : 1; */ - - /* - * Parse motor position - * Position string format: 1TP5.012,2TP1.123,3TP-100.567,... - * Skip to substring for this motor, convert to double - */ - - send_mess(card, "POS", MCDC2805_axis[signal]); - recv_mess(card, buff, 1); - - motorData = atof(buff); - - if (motorData == motor_info->position) - { - if (nodeptr != 0) /* Increment counter only if motor is moving. */ - motor_info->no_motion_count++; - } - else - { - epicsInt32 newposition; - - newposition = NINT(motorData); - status.Bits.RA_DIRECTION = (newposition >= motor_info->position) ? 1 : 0; - motor_info->position = newposition; - motor_info->no_motion_count = 0; - } - - plusdir = (status.Bits.RA_DIRECTION) ? true : false; - - send_mess(card, "GAST", MCDC2805_axis[signal]); - recv_mess(card, buff, 1); - Lswitch = buff[0] == '1'; - - /* Set limit Lswitch error indicators. */ - if (Lswitch != 0) - { - status.Bits.RA_PLUS_LS = 1; - if (plusdir == true) - ls_active = true; - } - else - status.Bits.RA_PLUS_LS = 0; - - Lswitch = buff[1] == '1'; - - if (Lswitch != 0) - { - status.Bits.RA_MINUS_LS = 1; - if (plusdir == false) - ls_active = true; - } - else - status.Bits.RA_MINUS_LS = 0; - - /* If there is an active limit switch (i.e. one that stopped motion) then - * we need to do an absolute move to the current position. - * If this is not done then as soon as the limit switch is released the motor will - * start moving, which is not good. - */ - if (ls_active) { - sprintf(buff, "LA %ld", NINT(motorData)); - send_mess(card, buff, MCDC2805_axis[signal]); - send_mess(card, "M", MCDC2805_axis[signal]); - } - - Lswitch = status_buff[6] == '1'; - status.Bits.RA_HOME = (Lswitch) ? 1 : 0; - - /* !!! Assume no closed-looped control!!!*/ - status.Bits.EA_POSITION = 0; - - /* encoder status */ - status.Bits.EA_SLIP = 0; - status.Bits.EA_SLIP_STALL = 0; - status.Bits.EA_HOME = 0; - - if (motor_state[card]->motor_info[signal].encoder_present == NO) - motor_info->encoder_position = 0; - else - { - motor_info->encoder_position = (int) motorData; - } - - status.Bits.RA_PROBLEM = 0; - - /* Read the actual velocity. Use this to set the DONE bit. - * This is needed because the "reached command position bit in GST does - * not work for jog commands or when move is stopped by setting velocity=0 */ - send_mess(card, "GV", MCDC2805_axis[signal]); - recv_mess(card, buff, 1); - motor_info->velocity = NINT(atof(buff)); - status.Bits.RA_DONE = (motor_info->velocity == 0) ? 1 : 0; - - if (!status.Bits.RA_DIRECTION) - motor_info->velocity *= -1; - - rtn_state = (!motor_info->no_motion_count || ls_active == true || - status.Bits.RA_DONE | status.Bits.RA_PROBLEM) ? 1 : 0; - - /* Test for post-move string. */ - if ((status.Bits.RA_DONE || ls_active == true) && nodeptr != 0 && - nodeptr->postmsgptr != 0) - { - strcpy(buff, nodeptr->postmsgptr); - send_mess(card, buff, MCDC2805_axis[signal]); - nodeptr->postmsgptr = NULL; - } - -exit: - motor_info->status.All = status.All; - return(rtn_state); -} - - -/*****************************************************/ -/* send a message to the MCDC2805 board */ -/* send_mess() */ -/*****************************************************/ -static RTN_STATUS send_mess(int card, char const *com, char *name) -{ - char local_buff[MAX_MSG_SIZE]; - struct MCDC2805controller *cntrl; - int comsize, namesize; - size_t nwrite; - - comsize = (com == NULL) ? 0 : strlen(com); - namesize = (name == NULL) ? 0 : strlen(name); - - if ((comsize + namesize) > MAX_MSG_SIZE) - { - errlogMessage("drvMCDC2805.c:send_mess(); message size violation.\n"); - return(ERROR); - } - else if (comsize == 0) /* Normal exit on empty input message. */ - return(OK); - - if (!motor_state[card]) - { - errlogPrintf("drvMCDC2805.c:send_mess() - invalid card #%d\n", card); - return(ERROR); - } - - /* Make a local copy of the string and add the command line terminator. */ - if (namesize != 0) - { - strcpy(local_buff, name); /* put in axis */ - strcat(local_buff, com); - } - else - strcpy(local_buff, com); - - Debug(2, "send_mess(): message = %s\n", local_buff); - - cntrl = (struct MCDC2805controller *) motor_state[card]->DevicePrivate; - pasynOctetSyncIO->write(cntrl->pasynUser, local_buff, strlen(local_buff), - COMM_TIMEOUT, &nwrite); - - return(OK); -} - - -/*****************************************************/ -/* receive a message from the MCDC2805 board */ -/* recv_mess() */ -/*****************************************************/ -static int recv_mess(int card, char *com, int flag) -{ - struct MCDC2805controller *cntrl; - const double timeout = 1.0; - size_t nread = 0; - asynStatus status = asynError; - int eomReason; - - /* Check that card exists */ - if (!motor_state[card]) - return(ERROR); - - cntrl = (struct MCDC2805controller *) motor_state[card]->DevicePrivate; - - if (flag == FLUSH) - pasynOctetSyncIO->flush(cntrl->pasynUser); - else - status = pasynOctetSyncIO->read(cntrl->pasynUser, com, BUFF_SIZE, - timeout, &nread, &eomReason); - - if ((status != asynSuccess) || (nread <= 0)) - { - com[0] = '\0'; - nread = 0; - } - - Debug(2, "recv_mess(): message = \"%s\"\n", com); - return(nread); -} - - -/*****************************************************/ -/* Setup system configuration */ -/* MCDC2805Setup() */ -/*****************************************************/ -RTN_STATUS -MCDC2805Setup(int num_cards, /* maximum number of chains in system. */ - int scan_rate) /* polling rate - 1/60 sec units. */ -{ - int itera; - - if (num_cards < 1 || num_cards > MCDC2805_NUM_CARDS) - MCDC2805_num_cards = MCDC2805_NUM_CARDS; - else - MCDC2805_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 MCDC2805Config 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(MCDC2805_num_cards * - sizeof(struct controller *)); - - for (itera = 0; itera < MCDC2805_num_cards; itera++) - motor_state[itera] = (struct controller *) NULL; - - return(OK); -} - - -/*****************************************************/ -/* Configure a controller */ -/* MCDC2805Config() */ -/*****************************************************/ -RTN_STATUS -MCDC2805Config(int card, /* chain being configured */ - int num_motors, /* Number of MCDC-2805 units on this serial port */ - const char *name) /* ASYN port name */ -{ - struct MCDC2805controller *cntrl; - - if (card < 0 || card >= MCDC2805_num_cards) - return(ERROR); - - motor_state[card] = (struct controller *) malloc(sizeof(struct controller)); - motor_state[card]->DevicePrivate = malloc(sizeof(struct MCDC2805controller)); - cntrl = (struct MCDC2805controller *) motor_state[card]->DevicePrivate; - - cntrl->num_motors = num_motors; - strcpy(cntrl->asyn_port, name); - 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 MCDC2805controller *cntrl; - int card_index, motor_index; - char buff[BUFF_SIZE]; - int total_axis = 0; - int status; - asynStatus success_rtn; - - initialized = true; /* Indicate that driver is initialized. */ - - /* Check for setup */ - if (MCDC2805_num_cards <= 0) - return(ERROR); - - for (card_index = 0; card_index < MCDC2805_num_cards; card_index++) - { - if (!motor_state[card_index]) - continue; - - brdptr = motor_state[card_index]; - brdptr->ident[0] = (char) NULL; /* No controller identification message. */ - brdptr->cmnd_response = false; - total_cards = card_index + 1; - cntrl = (struct MCDC2805controller *) brdptr->DevicePrivate; - - /* Initialize communications channel */ - success_rtn = pasynOctetSyncIO->connect(cntrl->asyn_port, 0, - &cntrl->pasynUser, NULL); - - if (success_rtn == asynSuccess) - { - /* Send a message to the board, see if it exists */ - /* flush any junk at input port - should not be any data available */ - pasynOctetSyncIO->flush(cntrl->pasynUser); - - for (total_axis = 0; total_axis < cntrl->num_motors; total_axis++) - { - int retry = 0; - - /* Try 3 times to connect to controller. */ - do - { - send_mess(card_index, "VER", MCDC2805_axis[total_axis]); - status = recv_mess(card_index, buff, 1); - retry++; - } while (status == 0 && retry < 3); - - if (status <= 0) - break; - else if (total_axis == 0) - strcpy(brdptr->ident, buff); - } - brdptr->total_axis = total_axis; - } - - if (success_rtn == asynSuccess && total_axis > 0) - { - brdptr->localaddr = (char *) NULL; - brdptr->motor_in_motion = 0; - - for (motor_index = 0; motor_index < total_axis; 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; - - motor_info->pid_present = YES; - motor_info->status.Bits.GAIN_SUPPORT = 1; - motor_info->encoder_present = YES; - motor_info->status.Bits.EA_PRESENT = 1; - - /* Set the velocity control to be RS-232 */ - send_mess(card_index, "SOR 0", MCDC2805_axis[motor_index]); - - /* Set the limit switch configuration. */ - /* We assume the following: - * Analog input = Input 1 = Home input = 1 bit - * Fault pin = Input 2 = CW limit = 2 bit - * Input 3 Input 3 = CCW limit = 4 bit - */ - /* Program fault pin as limit switch input */ - send_mess(card_index, "REFIN", MCDC2805_axis[motor_index]); - /* Program limit polarity for rising edge and high level */ - send_mess(card_index, "HP7", MCDC2805_axis[motor_index]); - /* Program the motor to hard block on the the limit switch inputs */ - send_mess(card_index, "HB6", MCDC2805_axis[motor_index]); - /* Program the limit switch directions to block - * + direction on input 2, - direction on input 3 */ - send_mess(card_index, "HD2", MCDC2805_axis[motor_index]); - /* Program homing sequence on input 1*/ - send_mess(card_index, "HL1", MCDC2805_axis[motor_index]); - send_mess(card_index, "HA1", MCDC2805_axis[motor_index]); - send_mess(card_index, "CAHOSEQ", MCDC2805_axis[motor_index]); - - set_status(card_index, motor_index); /* Read status of each motor */ - } - } - 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 *) "MCDC2805_motor", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - (EPICSTHREADFUNC) motor_task, (void *) &targs); - - return(OK); -} - -extern "C" -{ - -// Faulhaber Setup arguments -static const iocshArg setupArg0 = {"Max. controller count", iocshArgInt}; -static const iocshArg setupArg1 = {"Polling rate", iocshArgInt}; -// Faulhaber Config arguments -static const iocshArg configArg0 = {"Card being configured", iocshArgInt}; -static const iocshArg configArg1 = {"# modules on this serial port", iocshArgInt}; -static const iocshArg configArg2 = {"asyn port name", iocshArgString}; - -static const iocshArg * const setupArgs[2] = {&setupArg0, - &setupArg1}; - -static const iocshArg * const configArgs[3] = {&configArg0, - &configArg1, - &configArg2}; - -static const iocshFuncDef setupMCDC2805 = {"MCDC2805Setup", 2, setupArgs}; - -static const iocshFuncDef configMCDC2805 = {"MCDC2805Config", 3, configArgs}; - -static void setupMCDC2805CallFunc(const iocshArgBuf *args) -{ - MCDC2805Setup(args[0].ival, args[1].ival); -} - -static void configMCDC2805CallFunc(const iocshArgBuf *args) -{ - MCDC2805Config(args[0].ival, args[1].ival, args[2].sval); -} - - -static void MCDC2805Register(void) -{ - iocshRegister(&setupMCDC2805, setupMCDC2805CallFunc); - iocshRegister(&configMCDC2805, configMCDC2805CallFunc); -} - -epicsExportRegistrar(MCDC2805Register); - -} // extern "C" - - diff --git a/motorApp/FaulhaberSrc/drvMCDC2805.h b/motorApp/FaulhaberSrc/drvMCDC2805.h deleted file mode 100644 index 9dae1533..00000000 --- a/motorApp/FaulhaberSrc/drvMCDC2805.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -FILENAME... drvMCDC2805.h -USAGE... This file contains driver "include" information for the Faulhaber MCDC 2805 controller. - -*/ - -/* - * Original Author: Mark Rivers - * Date: 10/20/2005 - * - * 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 10/20/2005 mlr Converted from MDrive.h - */ - -#ifndef INCdrvMCDC2805h -#define INCdrvMCDC2805h 1 - -#include "motordrvCom.h" -#include "asynDriver.h" -#include "asynOctetSyncIO.h" - -#define COMM_TIMEOUT 2 /* Timeout in seconds */ - -/* MCDC-2805 specific data is stored in this structure. */ -struct MCDC2805controller -{ - asynUser *pasynUser; /* For RS-232 */ - char asyn_port[80]; /* asyn port name */ - int num_motors; /* Number of MCDC-2805 modules on this serial port */ - CommStatus status; /* Controller communication status. */ -}; - -/* Function prototypes. */ -extern RTN_STATUS MCDC2805Config(int, const char *); -extern RTN_STATUS MCDC2805Config(int, const char *); - -#endif /* INCdrvMCDC2805h */ - diff --git a/motorApp/Makefile b/motorApp/Makefile index 3fd75372..580cbf41 100644 --- a/motorApp/Makefile +++ b/motorApp/Makefile @@ -42,9 +42,6 @@ MicroMoSrc_DEPEND_DIRS = MotorSrc DIRS += MicosSrc MicosSrc_DEPEND_DIRS = MotorSrc -DIRS += FaulhaberSrc -FaulhaberSrc_DEPEND_DIRS = MotorSrc - DIRS += PC6KSrc PC6KSrc_DEPEND_DIRS = MotorSrc