mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
uldaq: working on uldaq_parse() and uldaq_print() for parsing signal/channel list
This commit is contained in:
parent
01fb1f05d0
commit
7f770d2e90
1 changed files with 186 additions and 66 deletions
|
@ -28,6 +28,25 @@
|
|||
#include <villas/nodes/uldaq.h>
|
||||
#include <villas/memory.h>
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
AiInputMode mode;
|
||||
} input_modes[] = {
|
||||
{ "differential", AI_DIFFERENTIAL },
|
||||
{ "single-ended", AI_SINGLE_ENDED },
|
||||
{ "pseudo-differential", AI_PSEUDO_DIFFERENTIAL }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
DaqDeviceInterface interface;
|
||||
} interface_types[] = {
|
||||
{ "usb", USB_IFC },
|
||||
{ "bluetooth", BLUETOOTH_IFC },
|
||||
{ "ethernet", ETHERNET_IFC },
|
||||
{ "any", ANY_IFC }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
Range range;
|
||||
|
@ -78,43 +97,65 @@ static const struct {
|
|||
{ "unipolar-0.005", UNIPT005VOLTS, 0.0, +0.005 }
|
||||
};
|
||||
|
||||
static UlError uldag_range_info(DaqDeviceHandle daqDeviceHandle, AiInputMode inputMode, int *numberOfRanges, Range* ranges)
|
||||
__attribute__((unused))
|
||||
static UlError uldag_range_info(DaqDeviceHandle device_handle, AiInputMode input_mode, int *number_of_ranges, Range* ranges)
|
||||
{
|
||||
UlError err = ERR_NO_ERROR;
|
||||
int i = 0;
|
||||
long long numRanges = 0;
|
||||
long long rng;
|
||||
UlError err;
|
||||
long long num_ranges = 0;
|
||||
long long range;
|
||||
|
||||
if (inputMode == AI_SINGLE_ENDED)
|
||||
{
|
||||
err = ulAIGetInfo(daqDeviceHandle, AI_INFO_NUM_SE_RANGES, 0, &numRanges);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ulAIGetInfo(daqDeviceHandle, AI_INFO_NUM_DIFF_RANGES, 0, &numRanges);
|
||||
err = input_mode == AI_SINGLE_ENDED
|
||||
? ulAIGetInfo(device_handle, AI_INFO_NUM_SE_RANGES, 0, &num_ranges)
|
||||
: ulAIGetInfo(device_handle, AI_INFO_NUM_DIFF_RANGES, 0, &num_ranges);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return err;
|
||||
|
||||
for (int i = 0; i < num_ranges; i++) {
|
||||
err = input_mode == AI_SINGLE_ENDED
|
||||
? ulAIGetInfo(device_handle, AI_INFO_SE_RANGE, i, &range)
|
||||
: ulAIGetInfo(device_handle, AI_INFO_DIFF_RANGE, i, &range);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return err;
|
||||
|
||||
ranges[i] = (Range) range;
|
||||
}
|
||||
|
||||
for (i=0; i<numRanges; i++)
|
||||
{
|
||||
if (inputMode == AI_SINGLE_ENDED)
|
||||
{
|
||||
err = ulAIGetInfo(daqDeviceHandle, AI_INFO_SE_RANGE, i, &rng);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ulAIGetInfo(daqDeviceHandle, AI_INFO_DIFF_RANGE, i, &rng);
|
||||
}
|
||||
*number_of_ranges = (int) num_ranges;
|
||||
|
||||
ranges[i] = (Range)rng;
|
||||
}
|
||||
|
||||
*numberOfRanges = (int)numRanges;
|
||||
|
||||
return err;
|
||||
return ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static Range uldaq_range_parse(const char *str)
|
||||
static AiInputMode uldaq_parse_input_mode(const char *str)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LEN(input_modes); i++) {
|
||||
if (!strcmp(input_modes[i].name, str))
|
||||
return input_modes[i].mode;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static DaqDeviceInterface uldaq_parse_interface_type(const char *str)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LEN(interface_types); i++) {
|
||||
if (!strcmp(interface_types[i].name, str))
|
||||
return interface_types[i].interface;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char * uldaq_print_interface_type(DaqDeviceInterface iftype)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LEN(interface_types); i++) {
|
||||
if (interface_types[i].interface == iftype)
|
||||
return interface_types[i].name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Range uldaq_parse_range(const char *str)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LEN(ranges); i++) {
|
||||
if (!strcmp(ranges[i].name, str))
|
||||
|
@ -128,6 +169,8 @@ int uldaq_init(struct node *n)
|
|||
{
|
||||
struct uldaq *u = (struct uldaq *) n->_vd;
|
||||
|
||||
u->device_interface_type = ANY_IFC;
|
||||
|
||||
u->in.queues = NULL;
|
||||
u->in.sample_rate = 1000;
|
||||
u->in.scan_options = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
|
||||
|
@ -151,35 +194,92 @@ int uldaq_parse(struct node *n, json_t *cfg)
|
|||
int ret;
|
||||
struct uldaq *u = (struct uldaq *) n->_vd;
|
||||
|
||||
const char *range = NULL;
|
||||
const char *default_range_str = NULL;
|
||||
const char *default_input_mode_str = NULL;
|
||||
const char *interface_type = NULL;
|
||||
|
||||
size_t i;
|
||||
json_t *json_signals;
|
||||
json_t *json_signal;
|
||||
json_error_t err;
|
||||
|
||||
ret = json_unpack_ex(cfg, &err, 0, "{ s: { s: o, s: F } }",
|
||||
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s: { s: o, s: F, s?: s, s?: s } }",
|
||||
"interface_type", &interface_type,
|
||||
"in",
|
||||
"signals", &json_signals,
|
||||
"sample_rate", &u->in.sample_rate,
|
||||
"range", &range
|
||||
"range", &default_range_str,
|
||||
"input_mode", &default_input_mode_str
|
||||
);
|
||||
if (ret)
|
||||
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
|
||||
|
||||
if (interface_type) {
|
||||
int iftype = uldaq_parse_interface_type(interface_type);
|
||||
if (iftype < 0)
|
||||
error("Invalid interface type: %s for node '%s'", interface_type, node_name(n));
|
||||
|
||||
u->device_interface_type = iftype;
|
||||
}
|
||||
|
||||
u->in.queues = realloc(u->in.queues, sizeof(struct AiQueueElement) * list_length(&n->signals));
|
||||
|
||||
json_array_foreach(json_signals, i, json_signal) {
|
||||
const char *range_str = NULL, *input_mode_str = NULL;
|
||||
int channel = -1, input_mode, range;
|
||||
|
||||
json_unpack_ex(json_signal, &err, 0, "{ s?: s, s?: s, s?: i }",
|
||||
"range", &range,
|
||||
"input_mode", &input_mode,
|
||||
"channel", &channel
|
||||
);
|
||||
if (ret)
|
||||
jerror(&err, "Failed to parse signal configuration of node %s", node_name(n));
|
||||
|
||||
if (!range_str)
|
||||
range_str = default_range_str;
|
||||
|
||||
if (!input_mode_str)
|
||||
input_mode_str = default_input_mode_str;
|
||||
|
||||
if (channel < 0)
|
||||
channel = i;
|
||||
|
||||
if (!range_str)
|
||||
error("No input range specified for signal %zu of node %s.", i, node_name(n));
|
||||
|
||||
if (!input_mode_str)
|
||||
error("No input mode specified for signal %zu of node %s.", i, node_name(n));
|
||||
|
||||
range = uldaq_parse_range(range_str);
|
||||
if (range < 0)
|
||||
error("Invalid input range specified for signal %zu of node %s.", i, node_name(n));
|
||||
|
||||
input_mode = uldaq_parse_input_mode(input_mode_str);
|
||||
if (input_mode < 0)
|
||||
error("Invalid input mode specified for signal %zu of node %s.", i, node_name(n));
|
||||
|
||||
u->in.queues[i].range = range;
|
||||
u->in.queues[i].inputMode = input_mode;
|
||||
u->in.queues[i].channel = channel;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char * uldaq_print(struct node *n)
|
||||
{
|
||||
return strf("TODO");
|
||||
struct uldaq *u = (struct uldaq *) n->_vd;
|
||||
|
||||
char *buf = NULL;
|
||||
char *uid = u->device_descriptor.uniqueId;
|
||||
char *name = u->device_descriptor.productName;
|
||||
const char *iftype = uldaq_print_interface_type(u->device_interface_type);
|
||||
|
||||
buf = strcatf(&buf, "device=%s (%s), interface=%s", uid, name, iftype);
|
||||
buf = strcatf(&buf, ", in.sample_rate=%f", u->in.sample_rate);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int uldaq_check(struct node *n)
|
||||
|
@ -210,11 +310,9 @@ int uldaq_start(struct node *n)
|
|||
struct uldaq *u = (struct uldaq *) n->_vd;
|
||||
|
||||
DaqDeviceDescriptor descriptors[ULDAQ_MAX_DEV_COUNT];
|
||||
Range ranges[ULDAQ_MAX_RANGE_COUNT];
|
||||
|
||||
UlError err;
|
||||
unsigned num_devs;
|
||||
int num_ranges;
|
||||
|
||||
// allocate a buffer to receive the data
|
||||
u->in.buffer = (double *) alloc(list_length(&n->signals) * n->in.vectorize * sizeof(double));
|
||||
|
@ -228,23 +326,27 @@ int uldaq_start(struct node *n)
|
|||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
// verify at least one DAQ device is detected
|
||||
/* Verify at least one DAQ device is detected */
|
||||
if (num_devs == 0) {
|
||||
warn("No DAQ devices are connected");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get a handle to the DAQ device associated with the first descriptor
|
||||
/* Get a handle to the DAQ device associated with the first descriptor */
|
||||
u->device_handle = ulCreateDaqDevice(descriptors[0]);
|
||||
if (u->device_handle == 0) {
|
||||
warn ("Unable to create a handle to the specified DAQ device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get the analog input ranges
|
||||
#if 0
|
||||
int num_ranges;
|
||||
Range ranges[ULDAQ_MAX_RANGE_COUNT];
|
||||
/* Get the analog input ranges */
|
||||
err = uldag_range_info(u->device_handle, u->in.input_mode, &num_ranges, ranges);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
err = ulConnectDaqDevice(u->device_handle);
|
||||
if (err != ERR_NO_ERROR)
|
||||
|
@ -254,17 +356,19 @@ int uldaq_start(struct node *n)
|
|||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
// start the acquisition
|
||||
// when using the queue, the lowChan, highChan, u->in.input_mode, and range
|
||||
// parameters are ignored since they are specified in u->queues
|
||||
err = ulAInScan(u->device_handle, 0, 0, u->in.input_mode, 0, u->in.sample_count, &(u->in.sample_rate), u->in.scan_options, u->in.flags, u->in.buffer);
|
||||
if (err == ERR_NO_ERROR) {
|
||||
ScanStatus status;
|
||||
TransferStatus transferStatus;
|
||||
/* Start the acquisition */
|
||||
err = ulAInScan(u->device_handle, 0, 0, 0, 0, n->in.vectorize, &u->in.sample_rate, u->in.scan_options, u->in.flags, u->in.buffer);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
// get the initial status of the acquisition
|
||||
ulAInScanStatus(u->device_handle, &status, &transferStatus);
|
||||
}
|
||||
ScanStatus status;
|
||||
TransferStatus transfer_status;
|
||||
|
||||
/* Get the initial status of the acquisition */
|
||||
ulAInScanStatus(u->device_handle, &status, &transfer_status);
|
||||
|
||||
if (status != SS_RUNNING)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -273,19 +377,29 @@ int uldaq_stop(struct node *n)
|
|||
{
|
||||
struct uldaq *u = (struct uldaq *) n->_vd;
|
||||
|
||||
UlError err = ERR_NO_ERROR;
|
||||
UlError err;
|
||||
ScanStatus status;
|
||||
TransferStatus transferStatus;
|
||||
// get the current status of the acquisition
|
||||
|
||||
/* Get the current status of the acquisition */
|
||||
err = ulAInScanStatus(u->device_handle, &status, &transferStatus);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
// stop the acquisition if it is still running
|
||||
if (status == SS_RUNNING && err == ERR_NO_ERROR)
|
||||
ulAInScanStop(u->device_handle);
|
||||
/* Stop the acquisition if it is still running */
|
||||
if (status == SS_RUNNING) {
|
||||
err = ulAInScanStop(u->device_handle);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: error handling
|
||||
ulDisconnectDaqDevice(u->device_handle);
|
||||
ulReleaseDaqDevice(u->device_handle);
|
||||
err = ulDisconnectDaqDevice(u->device_handle);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
err = ulReleaseDaqDevice(u->device_handle);
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -294,20 +408,26 @@ int uldaq_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *re
|
|||
{
|
||||
struct uldaq *u = (struct uldaq *) n->_vd;
|
||||
|
||||
UlError err = ERR_NO_ERROR;
|
||||
UlError err;
|
||||
ScanStatus status;
|
||||
TransferStatus transferStatus;
|
||||
// get the current status of the acquisition
|
||||
|
||||
/* Get the current status of the acquisition */
|
||||
err = ulAInScanStatus(u->device_handle, &status, &transferStatus);
|
||||
if (status == SS_RUNNING && err == ERR_NO_ERROR) {
|
||||
if (err == ERR_NO_ERROR) {
|
||||
//int index = transferStatus.currentIndex;
|
||||
//int i=0;//we only read one channel
|
||||
//double currentVal = u->in.buffer[index + i];
|
||||
if (err != ERR_NO_ERROR)
|
||||
return -1;
|
||||
|
||||
if (status == SS_RUNNING) {
|
||||
int index = transferStatus.currentIndex;
|
||||
|
||||
struct sample *smp = smps[0];
|
||||
|
||||
for (int i = 0; i < list_length(&n->signals); i++) {
|
||||
smp->data[i].f = u->in.buffer[index + i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue