mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
comedi: implement ADC and DAC directions, only DAC tested
The write / DAC direction has been tested with two output signals, see etc/comedi.conf for reference. For now, the buffer size may not be (considerably) smaller than 32kB, Comedi stops working for unknown reasons. To compensate for the latency (always approx. one buffer size) if only small sample rates are required, configure the path for upsampling (sample-and-hold via rate parameter) at the same rate as the out direction of the comedi node.
This commit is contained in:
parent
79d5257408
commit
fe302f9649
4 changed files with 948 additions and 123 deletions
84
etc/comedi.conf
Normal file
84
etc/comedi.conf
Normal file
|
@ -0,0 +1,84 @@
|
|||
/** Example configuration file for VILLASnode/comedi.
|
||||
*
|
||||
* The syntax of this file is similar to JSON.
|
||||
* A detailed description of the format can be found here:
|
||||
* http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
|
||||
*
|
||||
* @author Daniel Krebs <github@daniel-krebs.net>
|
||||
* @copyright 2018, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
nodes = {
|
||||
pcie6259 = {
|
||||
type = "comedi",
|
||||
device = "/dev/comedi0",
|
||||
in = {
|
||||
subdevice = 0,
|
||||
rate = 1000,
|
||||
signals = (
|
||||
# note: order in this array defines order in villas sample
|
||||
{ channel = 0, range = 0, aref = 0, name = "temperature_int" },
|
||||
{ channel = 1, range = 0, aref = 0, name = "loopback_ao0" },
|
||||
{ channel = 2, range = 0, aref = 0, name = "loopback_ao1" },
|
||||
{ channel = 3, range = 0, aref = 0, name = "bnc_ext" }
|
||||
)
|
||||
},
|
||||
out = {
|
||||
subdevice = 1,
|
||||
# Note: buffer size and rate shouldn't be changed at the moment
|
||||
# output sample rate
|
||||
rate = 10000,
|
||||
# comedi write buffer in kilobytes
|
||||
bufsize = 32,
|
||||
signals = (
|
||||
# note: order in this array corresponds to order in villas sample
|
||||
{ name = "ao0", channel = 0, range = 0, aref = 0 },
|
||||
{ name = "ao1", channel = 1, range = 0, aref = 0 }
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
remote = {
|
||||
type = "socket",
|
||||
layer = "udp"
|
||||
format = "protobuf",
|
||||
local = "*:12000"
|
||||
remote = "134.130.169.32:12000"
|
||||
},
|
||||
|
||||
sine1 = {
|
||||
type = "signal",
|
||||
signal = "sine",
|
||||
values = 1,
|
||||
frequency = 50,
|
||||
rate = 10000,
|
||||
},
|
||||
|
||||
sine2 = {
|
||||
type = "signal",
|
||||
signal = "sine",
|
||||
values = 1,
|
||||
frequency = 100,
|
||||
rate = 10000,
|
||||
}
|
||||
}
|
||||
|
||||
paths = (
|
||||
{ in = ("sine1.data[0]", "sine2.data[0]"), out = "pcie6259", rate = 10000, mask = () }
|
||||
)
|
|
@ -55,30 +55,31 @@ extern "C" {
|
|||
* To be or-ed with the debug level
|
||||
*/
|
||||
enum log_facilities {
|
||||
LOG_POOL = (1L << 8),
|
||||
LOG_QUEUE = (1L << 9),
|
||||
LOG_POOL = (1L << 8),
|
||||
LOG_QUEUE = (1L << 9),
|
||||
LOG_CONFIG = (1L << 10),
|
||||
LOG_HOOK = (1L << 11),
|
||||
LOG_PATH = (1L << 12),
|
||||
LOG_NODE = (1L << 13),
|
||||
LOG_MEM = (1L << 14),
|
||||
LOG_WEB = (1L << 15),
|
||||
LOG_API = (1L << 16),
|
||||
LOG_LOG = (1L << 17),
|
||||
LOG_VFIO = (1L << 18),
|
||||
LOG_PCI = (1L << 19),
|
||||
LOG_XIL = (1L << 20),
|
||||
LOG_TC = (1L << 21),
|
||||
LOG_IF = (1L << 22),
|
||||
LOG_ADVIO = (1L << 23),
|
||||
LOG_HOOK = (1L << 11),
|
||||
LOG_PATH = (1L << 12),
|
||||
LOG_NODE = (1L << 13),
|
||||
LOG_MEM = (1L << 14),
|
||||
LOG_WEB = (1L << 15),
|
||||
LOG_API = (1L << 16),
|
||||
LOG_LOG = (1L << 17),
|
||||
LOG_VFIO = (1L << 18),
|
||||
LOG_PCI = (1L << 19),
|
||||
LOG_XIL = (1L << 20),
|
||||
LOG_TC = (1L << 21),
|
||||
LOG_IF = (1L << 22),
|
||||
LOG_ADVIO = (1L << 23),
|
||||
|
||||
/* Node-types */
|
||||
LOG_SOCKET = (1L << 24),
|
||||
LOG_FILE = (1L << 25),
|
||||
LOG_FPGA = (1L << 26),
|
||||
LOG_NGSI = (1L << 27),
|
||||
LOG_FILE = (1L << 25),
|
||||
LOG_FPGA = (1L << 26),
|
||||
LOG_NGSI = (1L << 27),
|
||||
LOG_WEBSOCKET = (1L << 28),
|
||||
LOG_OPAL = (1L << 30),
|
||||
LOG_OPAL = (1L << 30),
|
||||
LOG_COMEDI = (1L << 31),
|
||||
|
||||
/* Classes */
|
||||
LOG_NODES = LOG_NODE | LOG_SOCKET | LOG_FILE | LOG_FPGA | LOG_NGSI | LOG_WEBSOCKET | LOG_OPAL,
|
||||
|
|
|
@ -33,15 +33,33 @@
|
|||
|
||||
#include <villas/node.h>
|
||||
#include <villas/list.h>
|
||||
#include <villas/timing.h>
|
||||
|
||||
// whether to use read() or mmap() kernel interface
|
||||
#define COMEDI_USE_READ (1)
|
||||
//#define COMEDI_USE_READ (0)
|
||||
|
||||
struct comedi_chanspec {
|
||||
unsigned int maxdata;
|
||||
comedi_range *range;
|
||||
};
|
||||
|
||||
struct comedi_direction {
|
||||
double rate;
|
||||
int subdevice; ///< Comedi subdevice
|
||||
int buffer_size; ///< Comedi's kernel buffer size
|
||||
int sample_size; ///< Size of a single measurement sample
|
||||
int sample_rate_hz; ///< Sample rate in Hz
|
||||
bool present; ///< Config present
|
||||
bool enabled; ///< Card is started successfully
|
||||
bool running; ///< Card is actively transfering samples
|
||||
struct timespec started; ///< Timestamp when sampling started
|
||||
int counter; ///< Number of villas samples transfered
|
||||
struct comedi_chanspec *chanspecs; ///< Range and maxdata config of channels
|
||||
unsigned *chanlist; ///< Channel list in comedi's packed format
|
||||
size_t chanlist_len; ///< Number of channels for this direction
|
||||
|
||||
bool enabled;
|
||||
int subdevice;
|
||||
|
||||
unsigned *chanlist;
|
||||
size_t chanlist_len;
|
||||
char* buffer;
|
||||
char* bufptr;
|
||||
};
|
||||
|
||||
struct comedi {
|
||||
|
@ -49,7 +67,18 @@ struct comedi {
|
|||
|
||||
struct comedi_direction in, out;
|
||||
|
||||
comedi_t *it;
|
||||
comedi_t *dev;
|
||||
|
||||
#if COMEDI_USE_READ
|
||||
char* buf;
|
||||
char* bufptr;
|
||||
#else
|
||||
char *map;
|
||||
size_t bufpos;
|
||||
size_t front;
|
||||
size_t back;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/** @see node_type::print */
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue