can readback correlation unit status
Some checks failed
Test And Build / Build (push) Failing after 2s
Test And Build / Lint (push) Successful in 2s

This commit is contained in:
2025-11-19 14:08:06 +01:00
parent 594bb6d320
commit 5b65a01e51
3 changed files with 59 additions and 31 deletions

View File

@@ -13,9 +13,17 @@ record(bo, "$(INSTR)$(NAME):Enable")
field(DESC, "Electronics Status")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) EN_EL")
field(VAL, 1)
field(ZNAM, "OFF")
field(ONAM, "ON")
field(PINI, 1)
}
record(bi, "$(INSTR)$(NAME):Enable_RBV")
{
field(DESC, "Electronics Status")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),0,$(TIMEOUT=1)) EN_EL_RBV")
field(ZNAM, "OFF")
field(ONAM, "ON")
field(SCAN, ".5 second")
}

View File

@@ -162,7 +162,9 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(
asynStatus status = asynSuccess;
status = createInt32Param(status, P_EnableElectronicsString,
&P_EnableElectronics);
&P_EnableElectronics, 1);
status = createInt32Param(status, P_EnableElectronicsRBVString,
&P_EnableElectronicsRBV);
status = createInt32Param(status, P_StatusString, &P_Status, STATUS_IDLE);
status = createInt32Param(status, P_ResetString, &P_Reset);
status = createInt32Param(status, P_StopString, &P_Stop);
@@ -395,10 +397,10 @@ asynStatus asynStreamGeneratorDriver::writeInt32(asynUser *pasynUser,
// TODO should check everything...
if (function == P_CountPreset) {
if (!currentStatus) {
// slightly longer than the status update frequency
// i.e. "$(INSTR)$(NAME):RAW-STATUS" SCAN seconds
// to ensure that the counts have all had a chance
// to update their values before starting a count
// slightly longer than the status update frequency
// i.e. "$(INSTR)$(NAME):RAW-STATUS" SCAN seconds
// to ensure that the counts have all had a chance
// to update their values before starting a count
epicsThreadSleep(0.12); // seconds
setIntegerParam(function, value);
setIntegerParam(P_Status, STATUS_COUNTING);
@@ -407,10 +409,10 @@ asynStatus asynStreamGeneratorDriver::writeInt32(asynUser *pasynUser,
}
} else if (function == P_TimePreset) {
if (!currentStatus) {
// slightly longer than the status update frequency
// i.e. "$(INSTR)$(NAME):RAW-STATUS" SCAN seconds
// to ensure that the counts have all had a chance
// to update their values before starting a count
// slightly longer than the status update frequency
// i.e. "$(INSTR)$(NAME):RAW-STATUS" SCAN seconds
// to ensure that the counts have all had a chance
// to update their values before starting a count
epicsThreadSleep(0.12); // seconds
setIntegerParam(function, value);
setIntegerParam(P_Status, STATUS_COUNTING);
@@ -456,7 +458,7 @@ asynStatus asynStreamGeneratorDriver::writeInt32(asynUser *pasynUser,
}
} else {
setIntegerParam(function, value);
//status = (asynStatus)callParamCallbacks();
// status = (asynStatus)callParamCallbacks();
}
if (status)
@@ -492,16 +494,32 @@ void asynStreamGeneratorDriver::receiveUDP() {
if (received) {
const uint16_t bufferLength = ((uint16_t *)buffer)[0];
const std::size_t headerLength = 42;
const bool isCmdBuffer = ((uint16_t *)buffer)[1] && 0x8000;
const std::size_t minDataBufferHeaderLength = 42;
const std::size_t minCmdBufferHeaderLength = 20;
if (received >= headerLength && received == bufferLength * 2) {
if (received >= minDataBufferHeaderLength &&
received == bufferLength * 2 && !isCmdBuffer) {
epicsRingBytesPut(this->udpQueue, (char *)buffer, bufferSize);
} else if (received >= minCmdBufferHeaderLength && isCmdBuffer) {
const CommandId cmd =
static_cast<CommandId>(((uint16_t *)buffer)[4]);
if (cmd == CommandId::start) {
setIntegerParam(this->P_EnableElectronicsRBV, 1);
} else if (cmd == CommandId::stop) {
setIntegerParam(this->P_EnableElectronicsRBV, 0);
}
} else {
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: invalid UDP packet\n", driverName,
functionName);
"%s:%s: invalid UDP packet of length %" PRIu64
" (cmd_id %d)\n",
driverName, functionName, received,
((uint16_t *)buffer)[4]);
}
}
}
@@ -704,12 +722,12 @@ void asynStreamGeneratorDriver::processEvents() {
// wait for mininmum packet frequency or enough packets to ensure we
// could potentially have at least 1 packet per mcpdid
// IMPORTANT: if you start counts faster than this poll period (so
// either the time or number of events incoming below), you will
// find that it doesn't have time to switch back to idle within
// this loop and so will just keep counting. If you need counts
// that are started more often than the below currently 250ms
// then that value will need to be adjusted.
// IMPORTANT: if you start counts faster than this poll period (so
// either the time or number of events incoming below), you will
// find that it doesn't have time to switch back to idle within
// this loop and so will just keep counting. If you need counts
// that are started more often than the below currently 250ms
// then that value will need to be adjusted.
while (queuedEvents < bufferedEvents &&
epicsTimeDiffInNS(&currentTime, &lastProcess) < 250'000'000ll) {
epicsThreadSleep(0.0001); // seconds
@@ -758,7 +776,6 @@ void asynStreamGeneratorDriver::processEvents() {
for (std::size_t i = 0; i < this->num_channels; ++i) {
counts[i] = 0;
}
}
if (currStatus == STATUS_COUNTING) {

View File

@@ -19,16 +19,16 @@ enum class CommandId : std::uint16_t {
cont = 3
};
// TODO these headers are actually the same, but with different bodies.
struct __attribute__((__packed__)) CommandHeader {
uint16_t BufferLength;
uint16_t BufferType;
uint16_t HeaderLength;
uint16_t BufferNumber;
uint16_t Command;
uint16_t McpdIdStatus;
uint16_t TimeStampLo;
uint16_t TimeStampMid;
uint16_t TimeStampHigh;
uint16_t Status : 8;
uint16_t McpdID : 8;
uint16_t TimeStamp[3];
uint16_t Checksum;
uint16_t Finalizer;
@@ -37,12 +37,13 @@ struct __attribute__((__packed__)) CommandHeader {
BufferNumber(0),
Command(
static_cast<std::underlying_type<CommandId>::type>(commandId)),
McpdIdStatus(0), TimeStampLo(0), TimeStampMid(0), TimeStampHigh(0),
Checksum(0), Finalizer(0xffff) {
Status(0), McpdID(0), TimeStamp{0, 0, 0}, Checksum(0),
Finalizer(0xffff) {
Checksum = BufferLength ^ BufferType ^ HeaderLength ^ BufferNumber ^
Command ^ McpdIdStatus ^ TimeStampLo ^ TimeStampMid ^
TimeStampHigh;
uint16_t checksum = 0x0000;
for (std::size_t i = 0; i < BufferLength; ++i)
checksum ^= ((uint16_t *)this)[i];
Checksum = checksum;
}
};
@@ -121,6 +122,7 @@ struct __attribute__((__packed__)) NormalisedEvent {
*/
constexpr static char P_EnableElectronicsString[]{"EN_EL"};
constexpr static char P_EnableElectronicsRBVString[]{"EN_EL_RBV"};
constexpr static char P_StatusString[]{"STATUS"};
constexpr static char P_ResetString[]{"RESET"};
@@ -168,6 +170,7 @@ class asynStreamGeneratorDriver : public asynPortDriver {
protected:
// Parameter Identifying IDs
int P_EnableElectronics;
int P_EnableElectronicsRBV;
int P_Status;
int P_Reset;
int P_Stop;