compiled soft_proton
This commit is contained in:
3
Makefile
3
Makefile
@@ -29,6 +29,7 @@ DBDS += src/daq.dbd
|
|||||||
|
|
||||||
# Source files to build
|
# Source files to build
|
||||||
SOURCES += src/daq.cpp
|
SOURCES += src/daq.cpp
|
||||||
|
SOURCES += src/daq_soft_proton.c
|
||||||
|
|
||||||
SCRIPTS += scripts/daq_4ch.cmd
|
SCRIPTS += scripts/daq_4ch.cmd
|
||||||
SCRIPTS += scripts/daq_8ch.cmd
|
SCRIPTS += scripts/daq_8ch.cmd
|
||||||
@@ -36,6 +37,6 @@ SCRIPTS += scripts/daq_2nd_gen.cmd
|
|||||||
SCRIPTS += sim/daq_sim.py
|
SCRIPTS += sim/daq_sim.py
|
||||||
|
|
||||||
CXXFLAGS += -std=c++17
|
CXXFLAGS += -std=c++17
|
||||||
USR_CFLAGS += -Wall -Wextra #-Werror
|
USR_CFLAGS += -std=c11 -Wall -Wextra #-Werror
|
||||||
|
|
||||||
# MISCS would be the place to keep the stream device template files
|
# MISCS would be the place to keep the stream device template files
|
||||||
|
|||||||
@@ -5,12 +5,13 @@
|
|||||||
* Typically it is sampling the proton rate from HIPA via
|
* Typically it is sampling the proton rate from HIPA via
|
||||||
* channel access.
|
* channel access.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <dbDefs.h>
|
#include <dbDefs.h>
|
||||||
#include <errlog.h>
|
#include <errlog.h>
|
||||||
|
|
||||||
#include <aSubRecord.h>
|
#include <aSubRecord.h>
|
||||||
#include <epicsTypes.h>
|
#include <epicsTypes.h>
|
||||||
|
#include <epicsString.h>
|
||||||
#include <registryFunction.h>
|
#include <registryFunction.h>
|
||||||
#include <epicsExport.h>
|
#include <epicsExport.h>
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ struct spc_internal {
|
|||||||
epicsUInt32 count_type;
|
epicsUInt32 count_type;
|
||||||
epicsInt64 preset_count;
|
epicsInt64 preset_count;
|
||||||
epicsFloat64 preset_time;
|
epicsFloat64 preset_time;
|
||||||
|
epicsFloat64 average_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Enum with values for all commands
|
/* Enum with values for all commands
|
||||||
@@ -41,7 +43,7 @@ enum commands {
|
|||||||
COUNT_PRESET = 1,
|
COUNT_PRESET = 1,
|
||||||
TIME_PRESET = 2,
|
TIME_PRESET = 2,
|
||||||
PAUSE = 3,
|
PAUSE = 3,
|
||||||
CONTINUE = 4
|
CONTINUE = 4,
|
||||||
STOP = 5,
|
STOP = 5,
|
||||||
FULL_RESET = 6
|
FULL_RESET = 6
|
||||||
};
|
};
|
||||||
@@ -57,45 +59,44 @@ enum status {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int handleNoop(struct spc_internal* spc_int, epicsChar** msg_text) {
|
int handleNoop(struct spc_internal* spc, epicsOldString* msg_text) {
|
||||||
const char[] funcstr = "handleNoop";
|
const char* funcstr = "handleNoop";
|
||||||
/* This shouldn't happen, but let's handle it just in case */
|
/* This shouldn't happen, but let's handle it just in case */
|
||||||
if (spc_int->status >= INVALID || spc->command_trig > FULL_RESET) {
|
if (spc->status >= INVALID || spc->command_trig > FULL_RESET) {
|
||||||
*msg_text = "INVALID STATE!";
|
strcpy(*msg_text, "INVALID STATE!");
|
||||||
errlogPrintf("%s: Status and/or command triggers are invalid \n"
|
errlogPrintf("%s: Status and/or command triggers are invalid \n"
|
||||||
"Status has value %d, \n Command trigger has value %d\n",
|
"Status has value %d, \n Command trigger has value %d\n",
|
||||||
funcstr, spc_int->status, spc_int->command_trig);
|
funcstr, spc->status, spc->command_trig);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if we are idle and have received a noop command */
|
/* Determine if we are idle and have received a noop command */
|
||||||
if (spc_int->status == IDLE) {
|
if (spc->status == IDLE) {
|
||||||
switch (spc_int->command_trig) {
|
switch (spc->command_trig) {
|
||||||
case PAUSE:
|
case PAUSE:
|
||||||
case CONTINUE:
|
case CONTINUE:
|
||||||
case STOP:
|
case STOP:
|
||||||
*msg_text = "Can not PAUSE/CONTINUE/STOP during IDLE.";
|
strcpy(*msg_text, "Can not PAUSE/CONTINUE/STOP during IDLE.");
|
||||||
printf("%s: %s\n"
|
printf("%s: %s\n"
|
||||||
"Status has value %d, \n"
|
"Status has value %d, \n"
|
||||||
"Command trigger has value %d\n",
|
"Command trigger has value %d\n", *msg_text,
|
||||||
funcstr, spc_int->status, spc_int->command_trig);
|
funcstr, spc->status, spc->command_trig);
|
||||||
*exit_status = 1; /* Positive value: No alarm and no output processing */
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if we are counting, low_rate or paused;
|
/* Determine if we are counting, low_rate or paused;
|
||||||
* and have received a noop command */
|
* and have received a noop command */
|
||||||
if (spc_int->status == COUNTING || spc_int->status == LOW_RATE ||
|
if (spc->status == COUNTING || spc->status == LOW_RATE ||
|
||||||
spc_int -> PAUSED) {
|
spc->status == PAUSED) {
|
||||||
switch (spc_int->command_trig) {
|
switch (spc->command_trig) {
|
||||||
case COUNT_PRESET:
|
case COUNT_PRESET:
|
||||||
case TIME_PRESET:
|
case TIME_PRESET:
|
||||||
|
strcpy(*msg_text, "Already counting");
|
||||||
printf("%s: Already counting can not start a new count\n"
|
printf("%s: Already counting can not start a new count\n"
|
||||||
"Status has value %d, \n"
|
"Status has value %d, \n"
|
||||||
"Command trigger has value %d\n",
|
"Command trigger has value %d\n",
|
||||||
funcstr, spc_int->status, spc_int->command_trig);
|
funcstr, spc->status, spc->command_trig);
|
||||||
*exit_status = 0;
|
|
||||||
/* This case could be seen as OK.
|
/* This case could be seen as OK.
|
||||||
* Nothing is keeping us from continuing, so let's do that. */
|
* Nothing is keeping us from continuing, so let's do that. */
|
||||||
return 0;
|
return 0;
|
||||||
@@ -103,12 +104,11 @@ int handleNoop(struct spc_internal* spc_int, epicsChar** msg_text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if we are paused and a pause command */
|
/* Determine if we are paused and a pause command */
|
||||||
if (spc_int->status == PAUSED && spc_int->command_trig == PAUSE) {
|
if (spc->status == PAUSED && spc->command_trig == PAUSE) {
|
||||||
errlogPrintf("%s: Already paused\n"
|
errlogPrintf("%s: Already paused\n"
|
||||||
"Status has value %d, \n"
|
"Status has value %d, \n"
|
||||||
"Command trigger has value %d\n",
|
"Command trigger has value %d\n",
|
||||||
funcstr, spc_int->status, spc_int->command_trig);
|
funcstr, spc->status, spc->command_trig);
|
||||||
*exit_status = 1; /* Positive value: No alarm and no output processing */
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* None of the noop cases detected */
|
/* None of the noop cases detected */
|
||||||
@@ -117,62 +117,60 @@ int handleNoop(struct spc_internal* spc_int, epicsChar** msg_text) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called everytime the record processes.
|
* This function is called everytime the record processes.
|
||||||
* Even though this record can process arrays, we only use it with scalars,
|
* Even though this record can process arrays, we only use it with scalars.
|
||||||
* hence all the [0]'s.
|
|
||||||
*/
|
*/
|
||||||
static long processEmulatedCounter(struct aSubRecord *psub)
|
static long processEmulatedCounter(struct aSubRecord *psub)
|
||||||
{
|
{
|
||||||
const char[] funcstr = "processEmulatedCounter";
|
const char* funcstr = "processEmulatedCounter";
|
||||||
if (softProtonDebug) printf("%s was called\n", funcstr);
|
if (softProtonDebug) printf("%s was called\n", funcstr);
|
||||||
|
|
||||||
/* Declare internal variable */
|
/* Declare internal variable */
|
||||||
struct spc_internal spc_int;
|
struct spc_internal spc_int;
|
||||||
struct spc_internal spc = &spc_int;
|
struct spc_internal* spc = &spc_int;
|
||||||
int exit_status = 0;
|
|
||||||
|
|
||||||
/* Copy input values to a struct on the stack
|
/* Copy input values to a struct on the stack
|
||||||
* to simplify creation of functions */
|
* to simplify creation of functions */
|
||||||
spc->status = psub->a[0];
|
spc->status = *(epicsUInt32*)psub->a;
|
||||||
spc->monitor_count = psub->b[0];
|
spc->monitor_count = *(epicsInt64*)psub->b;
|
||||||
spc->elapsed_time = psub->c[0];
|
spc->elapsed_time = *(epicsFloat64*)psub->c;
|
||||||
spc->command_trig = psub->d[0];
|
spc->command_trig = *(epicsUInt32*)psub->d;
|
||||||
spc->threshold = psub->e[0];
|
spc->threshold = *(epicsFloat64*)psub->e;
|
||||||
spc->count_type = psub->f[0];
|
spc->count_type = *(epicsUInt32*)psub->f;
|
||||||
spc->preset_count = psub->g[0];
|
spc->preset_count = *(epicsInt64*)psub->g;
|
||||||
spc->preset_time = psub->h[0];
|
spc->preset_time = *(epicsFloat64*)psub->h;
|
||||||
spc->prev_proton_rate = psub->j[0];
|
spc->prev_proton_rate = *(epicsFloat64*)psub->j;
|
||||||
spc->proton_rate = psub->l[0];
|
spc->proton_rate = *(epicsFloat64*)psub->l;
|
||||||
|
|
||||||
/* Get the pointer to output values only to increase readability. */
|
/* Get the pointer to output values only to increase readability. */
|
||||||
epicsUInt32* status_out = psub->vala;
|
epicsUInt32* status_out = (epicsUInt32*)psub->vala;
|
||||||
epicsInt64* monitor_count_out = psub->valb;
|
epicsInt64* monitor_count_out = (epicsInt64*)psub->valb;
|
||||||
epicsFloat64* elaped_time_out = psub->valc;
|
epicsFloat64* elapsed_time_out = (epicsFloat64*)psub->valc;
|
||||||
epicsUInt32* command_trig_out = psub->vald;
|
epicsUInt32* command_trig_out = (epicsUInt32*)psub->vald;
|
||||||
epicsFloat64* prev_proton_rate_out = psub->vale;
|
epicsFloat64* prev_proton_rate_out = (epicsFloat64*)psub->vale;
|
||||||
epicsUInt32* is_low_rate_out = psub->valf;
|
epicsUInt32* is_low_rate_out = (epicsUInt32*)psub->valf;
|
||||||
epicsChar* msg_txt_out = &psub->valg;
|
epicsOldString* msg_txt_out = (epicsOldString*)psub->valg;
|
||||||
|
|
||||||
/* Always no matter what, handle the rate */
|
/* Always no matter what, handle the rate */
|
||||||
/* - Calculate average rate */
|
/* - Calculate average rate */
|
||||||
average_rate = (spc->proton_rate + spc->prev_proton_rate) / 2;
|
spc->average_rate = (spc->proton_rate + spc->prev_proton_rate) / 2;
|
||||||
/* - Store current rate as previous rate */
|
/* - Store current rate as previous rate */
|
||||||
*prev_proton_rate_out = spc_int->proton_rate;
|
*prev_proton_rate_out = spc->proton_rate;
|
||||||
|
|
||||||
if (average_rate < spc->threshold) {
|
if (spc->average_rate < spc->threshold) {
|
||||||
*is_low_rate_out = 0; /* Illogical but 0 is low_rate, 1 high rate */
|
*is_low_rate_out = 0; /* Illogical but 0 is low_rate, 1 high rate */
|
||||||
} else {
|
} else {
|
||||||
*is_low_rate_out = 1; /* Illogical but 0 is low_rate, 1 high rate */
|
*is_low_rate_out = 1; /* Illogical but 0 is low_rate, 1 high rate */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle noop situations both valid and invalid */
|
/* Handle noop situations both valid and invalid */
|
||||||
if (handle_noop(spc, &msg_txt_out))
|
if (handleNoop(spc, msg_txt_out))
|
||||||
/* We have state that prohibits further processing */
|
/* We have state that prohibits further processing */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
/* Commands with priority always yielding IDLE status first */
|
/* Commands with priority always yielding IDLE status first */
|
||||||
if (spc->command_trig == FULL_RESET) {
|
if (spc->command_trig == FULL_RESET) {
|
||||||
msg_txt_out = "Full reset!";
|
strcpy(*msg_txt_out, "Full reset!");
|
||||||
/* Reset everything, done! */
|
/* Reset everything, done! */
|
||||||
*status_out = IDLE;
|
*status_out = IDLE;
|
||||||
*monitor_count_out = 0;
|
*monitor_count_out = 0;
|
||||||
@@ -192,7 +190,7 @@ static long processEmulatedCounter(struct aSubRecord *psub)
|
|||||||
} else if (((spc->status == COUNTING || spc->status == LOW_RATE)
|
} else if (((spc->status == COUNTING || spc->status == LOW_RATE)
|
||||||
&& spc->command_trig == PAUSE) ||
|
&& spc->command_trig == PAUSE) ||
|
||||||
(spc->status == PAUSED && spc->command_trig == NONE)) {
|
(spc->status == PAUSED && spc->command_trig == NONE)) {
|
||||||
msg_txt_out = "Stopping!";
|
strcpy(*msg_txt_out, "Stopping!");
|
||||||
/* We are counting or at low rate and received pause.
|
/* We are counting or at low rate and received pause.
|
||||||
* Also we are paused but have received no command, this
|
* Also we are paused but have received no command, this
|
||||||
* is probably slightly inaccurate but simplifies things.*/
|
* is probably slightly inaccurate but simplifies things.*/
|
||||||
@@ -206,7 +204,7 @@ static long processEmulatedCounter(struct aSubRecord *psub)
|
|||||||
/* Determine if we are idle but received a count command */
|
/* Determine if we are idle but received a count command */
|
||||||
if (softProtonDebug) printf("%s: Starting Count!\n", funcstr);
|
if (softProtonDebug) printf("%s: Starting Count!\n", funcstr);
|
||||||
/* Sanity check that count type is properly stored */
|
/* Sanity check that count type is properly stored */
|
||||||
if (command_trig != count_type) {
|
if (spc->command_trig != spc->count_type) {
|
||||||
if (softProtonDebug) printf("%s: Count type not stored!\n", funcstr);
|
if (softProtonDebug) printf("%s: Count type not stored!\n", funcstr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -215,22 +213,22 @@ static long processEmulatedCounter(struct aSubRecord *psub)
|
|||||||
*monitor_count_out = 0;
|
*monitor_count_out = 0;
|
||||||
*elapsed_time_out = 0;
|
*elapsed_time_out = 0;
|
||||||
*command_trig_out = NONE;
|
*command_trig_out = NONE;
|
||||||
if (is_low_rate_out == 1) {
|
if (*is_low_rate_out == 1) {
|
||||||
*status_out = LOW_RATE;
|
*status_out = LOW_RATE;
|
||||||
} else {
|
} else {
|
||||||
*status_out = COUNTING;
|
*status_out = COUNTING;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((((spc_int->status == LOW_RATE && spc_int->command_trig == NONE) ||
|
} else if ((((spc->status == LOW_RATE && spc->command_trig == NONE) ||
|
||||||
(spc_int->status == LOW_RATE && spc_int->command_trig == CONTINUE)))
|
(spc->status == LOW_RATE && spc->command_trig == CONTINUE)))
|
||||||
&& is_low_rate_out == 1) {
|
&& *is_low_rate_out == 1) {
|
||||||
*status_out = LOW_RATE;
|
*status_out = LOW_RATE;
|
||||||
/* LOW_RATE or resuming from PAUSE */
|
/* LOW_RATE or resuming from PAUSE */
|
||||||
*command_trig_out = NONE;
|
*command_trig_out = NONE;
|
||||||
/* Maintain same counter and time*/
|
/* Maintain same counter and time*/
|
||||||
*monitor_count_out = spc_int->monitor_count;
|
*monitor_count_out = spc->monitor_count;
|
||||||
*elapsed_time_out = spc_int->elapsed_time;
|
*elapsed_time_out = spc->elapsed_time;
|
||||||
return 0
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ending up here means:
|
/* Ending up here means:
|
||||||
@@ -247,12 +245,12 @@ static long processEmulatedCounter(struct aSubRecord *psub)
|
|||||||
*status_out = COUNTING;
|
*status_out = COUNTING;
|
||||||
|
|
||||||
/* Increament counter and time */
|
/* Increament counter and time */
|
||||||
*monitor_count_out = spc_int->monitor_count +
|
*monitor_count_out = spc->monitor_count +
|
||||||
average_rate * SOFT_PROTON_SAMPLE_RATE;
|
spc->average_rate * SOFT_PROTON_SAMPLE_RATE;
|
||||||
*elapsed_time_out = spc_int->elapsed_time + SOFT_PROTON_SAMPLE_RATE;
|
*elapsed_time_out = spc->elapsed_time + SOFT_PROTON_SAMPLE_RATE;
|
||||||
|
|
||||||
/* Check if we are below threshold */
|
/* Check if we are below threshold */
|
||||||
if (is_low_rate_out == 1) {
|
if (*is_low_rate_out == 1) {
|
||||||
*status_out = LOW_RATE;
|
*status_out = LOW_RATE;
|
||||||
} else {
|
} else {
|
||||||
*status_out = COUNTING;
|
*status_out = COUNTING;
|
||||||
@@ -261,11 +259,11 @@ static long processEmulatedCounter(struct aSubRecord *psub)
|
|||||||
/* Check if count is finished normally.
|
/* Check if count is finished normally.
|
||||||
* Higher priority than low rate */
|
* Higher priority than low rate */
|
||||||
if (/* Time based count finished */
|
if (/* Time based count finished */
|
||||||
(*elapsed_time_out >= spc_int->preset_time &&
|
(*elapsed_time_out >= spc->preset_time &&
|
||||||
spc_int->count_type = TIME_PRESET) ||
|
spc->count_type == TIME_PRESET) ||
|
||||||
/* Monitor based count finished */
|
/* Monitor based count finished */
|
||||||
(*monitor_count_out >= spc_int->preset_time &&
|
(*monitor_count_out >= spc->preset_time &&
|
||||||
spc_int->count_type = COUNT_PRESET)) {
|
spc->count_type == COUNT_PRESET)) {
|
||||||
*status_out = IDLE;
|
*status_out = IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user