can readback correlation unit status
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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(¤tTime, &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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user