Skip to content

Commit

Permalink
devMotorAsyn: remove initEvent in init_record()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tboegi committed Aug 11, 2020
1 parent c764bd6 commit fe884ce
Showing 1 changed file with 31 additions and 27 deletions.
58 changes: 31 additions & 27 deletions motorApp/MotorSrc/devMotorAsyn.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@

#include <asynDriver.h>
#include <asynInt32.h>
#include <asynFloat64SyncIO.h>
#include <asynFloat64.h>
#include <asynDrvUser.h>
#include <asynFloat64Array.h>
Expand Down Expand Up @@ -137,6 +138,7 @@ typedef struct
double param;
int needUpdate;
asynUser *pasynUser;
asynUser *pasynUserSync;
asynInt32 *pasynInt32;
void *asynInt32Pvt;
asynFloat64 *pasynFloat64;
Expand All @@ -148,7 +150,6 @@ typedef struct
asynGenericPointer *pasynGenericPointer;
void *asynGenericPointerPvt;
void *registrarPvt;
epicsEventId initEvent;
int driverReasons[NUM_MOTOR_COMMANDS];
} motorAsynPvt;

Expand All @@ -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:
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 );
}
}

/**
Expand Down

0 comments on commit fe884ce

Please sign in to comment.