7 Commits
1.1.2 ... sinq

Author SHA1 Message Date
3c67d7c041 Add sinq specific make files 2025-10-17 11:05:59 +02:00
Marco Filho
38218b883e Merge branch 'ICSHWI-22046' into 'master'
Overwrite default initial values

See merge request epics-modules/adorca!30
2025-10-15 16:52:00 +02:00
marcofilho
77b5441d23 Overwrite default initial values 2025-10-15 16:48:35 +02:00
marcofilho
7ee6421657 Update example st.cmd
From this version onwards, it is possible to pass all the data to
ndpluginschemas and then to kafka newest versions, intead of passing
straight to kafka.
2025-10-15 13:09:47 +02:00
Marco Filho
def770e2f8 Merge branch 'improve-timestamp' into 'master'
Pass timestamp to epicsTS instead of timeStamp

See merge request epics-modules/adorca!29
2025-10-15 13:03:58 +02:00
marcofilho
cceb18989b Make epicsTS carry the proper EVR timestamp
epicsTS is the one passed to kafka: https://gitlab.esss.lu.se/epics-modules/ADPluginKafka/-/blob/2.0.2/adpluginkafkaApp/src/KafkaPlugin.cpp?ref_type=tags#L40
The documentation is a bit confusing on what is the difference between
epicsTS and timeStamp, but apparently both can be modified with no
problems.

After [this discussion](github.com/areaDetector/ADCore/issues?q=is%3Aissue%20state%3Aclosed)
I decided it was fine to keep the epicsTS in nanoseconds with the EVR
values.
2025-10-15 13:00:16 +02:00
marcofilho
e2d6d48cde Decrease image-timestamp latency.
The timestamp buffer is now filled unconditionally, always after
dcamcap_transferinfo is called. It is only used, however, if trigger
mode is external.

This reduces time between detecting an image and getting the timestamp
from around 1.6 ms to around 200 ns.
2025-10-10 16:48:07 +02:00
6 changed files with 67 additions and 15 deletions

View File

@@ -109,6 +109,14 @@ record("*", "$(P)$(R)AcquirePeriod_RBV") {
field(FLNK, "$(P)$(R)#EVRAcquireTime-S.PROC PP MS")
}
record("*", "$(P)$(R)AcquireTime") {
field(VAL, "0.9")
}
record("*", "$(P)$(R)AcquirePeriod") {
field(VAL, "1")
}
record(calcout, "$(P)$(R)#EVRAcquireTime-S") {
field(DESC, "Set EVR acquire time in seconds")
field(CALC, "A=0?B:A*B")

View File

@@ -834,6 +834,7 @@ void Orca::imageTask() {
uint64_t prevAcquisitionCount = 0;
DCAMCAP_TRANSFERINFO captransferinfo;
epicsTimeStamp prevAcqTime, currentAcqTime;
epicsTimeStamp acqTimestamp;
epicsTimeStamp prev_trigger_time, current_trigger_time;
double elapsedTime;
int evr_counts = 0;
@@ -841,6 +842,7 @@ void Orca::imageTask() {
double maxAcqusitionTime, acqusitionRate;
int triggerMode = DCAMPROP_TRIGGERSOURCE__INTERNAL;
int triggerActive;
char buf[256];
lock();
while (1) {
@@ -875,7 +877,7 @@ void Orca::imageTask() {
// get image transfer status.
unlock();
imageTransferStatus(m_hdcam, captransferinfo);
imageTransferStatus(m_hdcam, captransferinfo, buf);
lock();
if (prevAcquisitionCount < (uint64_t)captransferinfo.nFrameCount) {
@@ -926,18 +928,19 @@ void Orca::imageTask() {
// Update asyn parameters
setIntegerParam(evrCountsSinceAcqStart, evr_counts_since_last_start);
setIntegerParam(evrTriggerDropped, evr_trigger_dropped);
char buf[256];
getStringParam(evrTimeStamp, 256, buf);
// remember parsed timestamp values
sscanf(buf, "%u.%u", &mTimeStampSec, &mTimeStampNsec);
timestamp = mTimeStampSec + mTimeStampNsec / 1.e9;
FLOW_ARGS("mTimeStampSec: %u - mTimeStampNsec: %u\n", mTimeStampSec,
mTimeStampNsec);
sscanf(buf, "%u.%u", &acqTimestamp.secPastEpoch, &acqTimestamp.nsec);
acqTimestamp.secPastEpoch -= POSIX_TIME_AT_EPICS_EPOCH;
timestamp = acqTimestamp.secPastEpoch + acqTimestamp.nsec / 1.e9;
FLOW_ARGS("acqTimestamp.secPastEpoch: %u - acqTimestamp.nsec: %u\n", acqTimestamp.secPastEpoch,
acqTimestamp.nsec);
FLOW_ARGS("Timestamp from evr: %f\n", timestamp);
} else {
updateTimeStamp(&acqTimestamp);
timestamp =
(ts_sec + ts_microsec / 1.0e6) - (exposure_time + readout_time);
FLOW_ARGS("Timestamp from camera: %f\n", timestamp);
@@ -967,7 +970,7 @@ void Orca::imageTask() {
if (pImage) {
pImage->uniqueId = count;
pImage->timeStamp = timestamp;
updateTimeStamp(&pImage->epicsTS);
pImage->epicsTS = acqTimestamp;
memcpy(pImage->pData, (epicsUInt16*)image, pImage->dataSize);
@@ -1742,7 +1745,7 @@ void Orca::getImageInformation(HDCAM hdcam, int32& pixeltype, int32& width,
}
asynStatus Orca::imageTransferStatus(HDCAM hdcam,
DCAMCAP_TRANSFERINFO& captransferinfo) {
DCAMCAP_TRANSFERINFO& captransferinfo, char *buf) {
DCAMERR err;
const char* functionName = "imageTransferStatus";
memset(&captransferinfo, 0, sizeof(captransferinfo));
@@ -1750,6 +1753,7 @@ asynStatus Orca::imageTransferStatus(HDCAM hdcam,
// get number of captured image
err = dcamcap_transferinfo(m_hdcam, &captransferinfo);
getStringParam(evrTimeStamp, 256, buf);
if (failed(err)) {
ERR_ARGS("DCAMERR: 0x%08X [%s]", m_err, "dcamcap_transferinfo");
return asynError;

View File

@@ -189,9 +189,6 @@ class epicsShareClass Orca : public ADDriver {
int readParameter(int propertyID, bool processPV = true);
int readParameterStr(int paramIndex);
epicsUInt32 mTimeStampSec;
epicsUInt32 mTimeStampNsec;
void imageTask();
void temperatureTask();
@@ -333,7 +330,7 @@ class epicsShareClass Orca : public ADDriver {
int32 rowbytes, int32 cx, int32 cy,
epicsUInt32& ts_sec, epicsUInt32& ts_microsec);
asynStatus imageTransferStatus(HDCAM hdcam,
DCAMCAP_TRANSFERINFO& captransferinfo);
DCAMCAP_TRANSFERINFO& captransferinfo, char *buf);
// wrapper functions for dcamapi
int allocateBuffers(unsigned int);

22
GNUmakefile Normal file
View File

@@ -0,0 +1,22 @@
include /ioc/tools/driver.makefile
REQUIRED += ADCore busy orca_dcamapi
ARCH_FILTER += RHEL%
LIBVERSION = 1.1.4
APP := ADOrcaApp
APPDB := $(APP)/Db
APPSRC := $(APP)/src
APPCMDS := $(APP)/cmds
TEMPLATES += $(wildcard $(APPDB)/*.db)
TEMPLATES += $(wildcard $(ADCORE_DIR)/*.db)
TEMPLATES += $(wildcard $(APPDB)/*.template)
SOURCES += $(APPSRC)/orca.cpp
DBDS += $(APPSRC)/orca.dbd
SCRIPTS += $(wildcard iocsh/*.iocsh)

17
Makefile.sdk Normal file
View File

@@ -0,0 +1,17 @@
include /ioc/tools/driver.makefile
BUILDCLASSES = Linux
MODULE = orca_dcamapi
LIBVERSION = 4.0.6269
ARCH_FILTER += RHEL%
SUPPORT:= support/dcamsdk4/lib/linux-x86_64
SHRLIBS += $(SUPPORT)/libdcamapi.so.4
SHRLIBS += $(SUPPORT)/libdcamapi.so.4.0.6269
SHRLIBS += $(SUPPORT)/libdcamapi.so
HEADERS = $(wildcard support/dcamsdk4/inc/*.h)

View File

@@ -1,4 +1,5 @@
require adorca
require ndpluginschemas
require adpluginkafka
epicsEnvSet("PREFIX", "YMIR-Det1:")
@@ -34,6 +35,9 @@ NDPvaConfigure("PVA1", $(QSIZE), 0, "$(PORT)", 0, "$(PREFIX)Pva1:Image", 0, 0, 0
dbLoadRecords("$(adcore_DIR)/db/NDPva.template", "P=$(PREFIX),R=Pva1:, PORT=PVA1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#
NDSchemasConfigure("Schemas1", "$(QSIZE)", 0, "$(PORT)", 0, 0, 0, "test-orca-lab", 0)
dbLoadRecords("$(ndpluginschemas_DB)/NDPluginSchemas.template", "P=$(PREFIX), R=schemas:, PORT=Schemas1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=$(PORT)")
# Create a standard arrays plugin, set it to get data from orca driver.
NDStdArraysConfigure("Image1", "$(QSIZE)", 0, "$(PORT)", 0, 0)
dbLoadRecords("NDStdArrays.template", "P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),TYPE=Int32,FTVL=LONG,NELEMENTS=$(NELEMENTS)")
@@ -44,8 +48,8 @@ epicsEnvSet("KFK_TOPIC", "ymir_camera")
# Kafka plugin
#epicsEnvSet("KFK_CONFIG_FILE_PATH", "/etc/kafka/kafka.conf")
#KafkaPluginConfigure("KFK1", 3, 1, "$(PORT)", 0, -1, "$(KFK_TOPIC)", "hama_kfk1","$(KFK_CONFIG_FILE_PATH)")
#dbLoadRecords("$(adpluginkafka_DIR)db/adpluginkafka.db", "P=$(PREFIX), R=Kfk1:, PORT=KFK1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=$(PORT)")
KafkaPluginConfigure("Kafka1", 3, 1, "Schemas1", 0, -1, "$(KFK_TOPIC)","$(KFK_CONFIG_FILE_PATH)")
dbLoadRecords("$(adpluginkafka_DB)/adpluginkafka.db", "P=$(PREFIX), R=Kfk1:, PORT=Kafka1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=Schemas1")
# startPVAServer
iocInit()