From fe884ceb59f032b90df4ed65bcc16575cbd60a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20B=C3=B6gershausen?= Date: Tue, 11 Aug 2020 14:00:06 +0200 Subject: [PATCH] devMotorAsyn: remove initEvent in init_record() When the motorRecord is initialized, init_record() is called. For asynMotors init_record() calls init_controller() in devMotorAsyn.c From here, the encoder ratio is send to the driver. After doing that, the code "locks" the execution waiting for a callback to call epicsEventSignal(pPvt->initEvent) which "unlocks" the code. As Mark Clift points out, this code can be simplified and the initEvent can be removed. Mark Rivers suggested to use the asynFloat64SyncIO interface, which locks the asyn port when calling the driver. --- motorApp/MotorSrc/devMotorAsyn.c | 58 +++++++++++++++++--------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/motorApp/MotorSrc/devMotorAsyn.c b/motorApp/MotorSrc/devMotorAsyn.c index aa02f9e2..2397bb28 100644 --- a/motorApp/MotorSrc/devMotorAsyn.c +++ b/motorApp/MotorSrc/devMotorAsyn.c @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -137,6 +138,7 @@ typedef struct double param; int needUpdate; asynUser *pasynUser; + asynUser *pasynUserSync; asynInt32 *pasynInt32; void *asynInt32Pvt; asynFloat64 *pasynFloat64; @@ -148,7 +150,6 @@ typedef struct asynGenericPointer *pasynGenericPointer; void *asynGenericPointerPvt; void *registrarPvt; - epicsEventId initEvent; int driverReasons[NUM_MOTOR_COMMANDS]; } motorAsynPvt; @@ -170,16 +171,23 @@ static void init_controller(struct motorRecord *pmr, asynUser *pasynUser ) motorAsynPvt *pPvt = (motorAsynPvt *)pmr->dpvt; double position = pPvt->status.position; double rdbd = (fabs(pmr->rdbd) < fabs(pmr->mres) ? fabs(pmr->mres) : fabs(pmr->rdbd) ); - double encRatio[2] = {pmr->mres, pmr->eres}; int use_rel = (pmr->rtry != 0 && pmr->rmod != motorRMOD_I && (pmr->ueip || pmr->urip)); int dval_non_zero_pos_near_zero = (fabs(pmr->dval) > rdbd) && (pmr->mres != 0) && (fabs(position * pmr->mres) < rdbd); + epicsFloat64 eratio = pmr->mres / pmr->eres; int initPos = 0; + int status; - /*Before setting position, set the correct encoder ratio.*/ - start_trans(pmr); - build_trans(SET_ENC_RATIO, encRatio, pmr); - end_trans(pmr); + /* Write encoder ratio to the driver.*/ + pPvt->pasynUserSync->reason = pPvt->driverReasons[motorEncRatio]; + status = pasynFloat64SyncIO->write(pPvt->pasynUserSync, eratio, pasynUser->timeout); + if (status) { + asynPrint(pasynUser, ASYN_TRACE_ERROR, + "devMotorAsyn::init_controller, %s failed to set encoder ratio to %2.6lf\n", pmr->name, eratio ); + } else { + asynPrint(pasynUser, ASYN_TRACE_FLOW, + "devMotorAsyn::init_controller, %s set encoder ratio to %2.6lf\n", pmr->name, eratio ); + } switch (pmr->rstm) { case motorRSTM_NearZero: @@ -202,30 +210,19 @@ static void init_controller(struct motorRecord *pmr, asynUser *pasynUser ) if (initPos) { double setPos = pmr->dval / pmr->mres; - epicsEventId initEvent = epicsEventCreate( epicsEventEmpty ); - RTN_STATUS rtnval; - - pPvt->initEvent = initEvent; - start_trans(pmr); - rtnval = build_trans(LOAD_POS, &setPos, pmr); - end_trans(pmr); - if (rtnval != OK) { + /* Write setPos to the driver */ + pPvt->pasynUserSync->reason = pPvt->driverReasons[motorPosition]; + status = pasynFloat64SyncIO->write(pPvt->pasynUserSync, setPos, pasynUser->timeout); + if (status) { asynPrint(pasynUser, ASYN_TRACE_ERROR, - "devMotorAsyn::init_controller, %s failed to set position to %f\n", + "devMotorAsyn::init_controller, %s failed to set position to %2.6lf\n", pmr->name, setPos ); } else { asynPrint(pasynUser, ASYN_TRACE_FLOW, - "devMotorAsyn::init_controller, %s set position to %f\n", + "devMotorAsyn::init_controller, %s set position to %2.6lf\n", pmr->name, setPos ); } - - if ( initEvent ) - { - epicsEventMustWait(initEvent); - epicsEventDestroy(initEvent); - pPvt->initEvent = 0; - } } else asynPrint(pasynUser, ASYN_TRACE_FLOW, @@ -307,6 +304,14 @@ static long init_record(struct motorRecord * pmr ) pPvt->pasynFloat64 = (asynFloat64 *)pasynInterface->pinterface; pPvt->asynFloat64Pvt = pasynInterface->drvPvt; + /* Initialize Float64 synchronous interface */ + status = pasynFloat64SyncIO->connect(port, signal, &pPvt->pasynUserSync, userParam); + if (status != asynSuccess) { + asynPrint(pasynUser, ASYN_TRACE_ERROR, + "devMotorAsyn::init_record, %s connect Float64SyncIO interface failed\n", pmr->name); + goto bad; + } + /* Get the asynDrvUser interface */ pasynInterface = pasynManager->findInterface(pasynUser, asynDrvUserType, 1); if (!pasynInterface) { asynPrint(pasynUser, ASYN_TRACE_ERROR, @@ -408,6 +413,9 @@ static long init_record(struct motorRecord * pmr ) * set, a callback will be generated */ + /* Finished using the Float64 SyncIO interface */ + pasynFloat64SyncIO->disconnect(pPvt->pasynUserSync); + /* Finally, indicate to the motor record that these values can be used. */ pasynManager->freeAsynUser(pasynUser); pPvt->needUpdate = 1; @@ -720,10 +728,6 @@ static void asynCallback(asynUser *pasynUser) "devMotorAsyn::asynCallback: %s error in freeAsynUser, %s\n", pmr->name, pasynUser->errorMessage); } - - if ( pPvt->initEvent && pmsg->command == motorPosition) { - epicsEventSignal( pPvt->initEvent ); - } } /**