diff --git a/README.md b/README.md index 7f1d21a..57abd2d 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,15 @@ It calls `doReset` and performs some fast polls after `doReset` returns. - `doMove`: This is an empty function which should be overwritten by concrete driver implementations. - `home`: This function sets the internal status flags for the homing process and then calls doHome. - `doHome`: This is an empty function which should be overwritten by concrete driver implementations. -- `poll`: This is a wrapper around `doPoll` which performs some bookkeeping tasks before and after calling `doPoll`: +- `poll`: This is a wrapper around `forcedPoll` which does the following checks before calling `forcedPoll`: + - Are there any outstanding fast polls (method `outstandingForcedFastPolls` of the controller returns a value greater zero)? + - Was the axis moving last time its status was polled? + - Is adaptive polling disabled? + - Did an idle period pass since the last poll? +If all of these conditions are false, no poll is performed. Otherwise, the `forcedPoll` method is called. +This method should not be called in the driver code itself if a poll is needed - use `forcedPoll` instead! + +- `forcedPoll`: This is a wrapper around `doPoll` which performs some bookkeeping tasks before and after calling `doPoll`: Before calling `doPoll`: - Check if the paramLib already contains an old error message. If so, put it into a temporary bufffer diff --git a/src/sinqAxis.cpp b/src/sinqAxis.cpp index 06cd0a5..92945a0 100644 --- a/src/sinqAxis.cpp +++ b/src/sinqAxis.cpp @@ -171,14 +171,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo) sinqAxis::~sinqAxis() = default; asynStatus sinqAxis::poll(bool *moving) { - - // Local variable declaration - asynStatus pl_status = asynSuccess; - asynStatus poll_status = asynSuccess; - int homing = 0; int adaptivePolling = 0; - char waitingMessage[pC_->MAXBUF_] = {0}; - char newMessage[pC_->MAXBUF_] = {0}; /* If adaptive polling is enabled: @@ -201,22 +194,33 @@ asynStatus sinqAxis::poll(bool *moving) { Check if both adaptive polling is enabled and no forced fast polls are still required. */ - if (adaptivePolling != 0 && pC_->outstandingForcedFastPolls() == 0) { - // Motor wasn't moving during the last poll - if (!pSinqA_->wasMoving) { + if (adaptivePolling != 0 && pC_->outstandingForcedFastPolls() == 0 && + !pSinqA_->wasMoving) { - // Add the idle poll period - epicsTimeStamp earliestTimeNextPoll = pSinqA_->lastPollTime; - epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod()); + // Add the idle poll period + epicsTimeStamp earliestTimeNextPoll = pSinqA_->lastPollTime; + epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod()); - if (epicsTimeLessThanEqual(&earliestTimeNextPoll, &ts) == 0) { - *moving = false; - return asynSuccess; - } + if (epicsTimeLessThanEqual(&earliestTimeNextPoll, &ts) == 0) { + *moving = false; + return asynSuccess; } } + return forcedPoll(moving); +} + +asynStatus sinqAxis::forcedPoll(bool *moving) { + + // Local variable declaration + asynStatus pl_status = asynSuccess; + asynStatus poll_status = asynSuccess; + int homing = 0; + char waitingMessage[pC_->MAXBUF_] = {0}; + char newMessage[pC_->MAXBUF_] = {0}; // Update the start time of the last poll + epicsTimeStamp ts; + epicsTimeGetCurrent(&ts); pSinqA_->lastPollTime = ts; /* diff --git a/src/sinqAxis.h b/src/sinqAxis.h index cf5584b..d210a9d 100644 --- a/src/sinqAxis.h +++ b/src/sinqAxis.h @@ -31,6 +31,27 @@ class epicsShareClass sinqAxis : public asynMotorAxis { */ ~sinqAxis(); + /** + * @brief Check if a poll should be performed. If yes, call `forcedPoll`. + * + This is a wrapper around `forcedPoll` which does the following checks before + calling `forcedPoll`: + - Are there any outstanding fast polls (method `outstandingForcedFastPolls` + of the controller returns a value greater zero)? + - Was the axis moving last time its status was polled? + - Is adaptive polling disabled? + - Did an idle period pass since the last poll? + If all of these conditions are false, no poll is performed. Otherwise, the + `forcedPoll` method is called. This method should not be called in the + driver code itself if a poll is needed - use `forcedPoll` instead! + * + * @param moving Forwarded to `forcedPoll` or set to false + (depending on whether `forcedPoll was called`). + * @return asynStatus Forward the status of `forcedPoll` or set to + asynSuccess (depending on whether `forcedPoll was called`). + */ + virtual asynStatus poll(bool *moving); + /** * @brief Perform some standardized operations before and after the concrete `doPoll` implementation. @@ -46,7 +67,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis { - The flags `motorStatusHome_`, `motorStatusHomed_` and `motorStatusAtHome_` are set to their idle values (0, 1 and 1 respectively) - in the `poll()` method once the homing procedure is finished. See the + in the `forcedPoll()` method once the homing procedure is finished. See the documentation of the `home()` method for more details. - Run `callParamCallbacks()` @@ -56,9 +77,9 @@ class epicsShareClass sinqAxis : public asynMotorAxis { * @param moving Forwarded to `doPoll`. * @return asynStatus Forward the status of `doPoll`, unless one of the parameter library operation fails (in that case, returns the status of - the failed operation. + the failed operation). */ - virtual asynStatus poll(bool *moving); + virtual asynStatus forcedPoll(bool *moving); /** * @brief Implementation of the "proper", device-specific poll method. This @@ -142,7 +163,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis { * * The flags `motorStatusHome_`, `motorStatusHomed_` and `motorStatusAtHome_` are set to their idle values (0, 1 and 1 respectively) - in the `poll()` method once the homing procedure is finished. + in the `forcedPoll())` method once the homing procedure is finished. * * @param minVelocity Forwarded to `doHome`. * @param maxVelocity Forwarded to `doHome`.