25 #define A4L_CHAN_AREF_GROUND 0x1; 26 #define A4L_CHAN_AREF_COMMON 0x2; 27 #define A4L_CHAN_AREF_DIFF 0x4; 28 #define A4L_CHAN_AREF_OTHER 0x8; 48 for (
int i = 0; i < dsc.nb_subd; i++) {
49 err = a4l_get_subdinfo(&dsc, i, &sbinfo);
52 "AnalogyDriver: a4l_get_subd_info failed, wrong subdevice index %i " 58 if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AI) && (idx_ai < 0))
60 else if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AO) && (idx_ao < 0))
62 else if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_DIO)
69 err = a4l_get_subdinfo(&dsc, idx_ai, &sbinfo);
70 if ((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AI)) {
71 subdevice[
AI].id = idx_ai;
72 subdevice[
AI].active = 0;
73 subdevice[
AI].count = sbinfo->nb_chan;
75 if (!subdevice[
AI].chan)
76 subdevice[
AI].count = 0;
78 for (
size_t i = 0; i < subdevice[
AI].count; ++i) {
79 err = a4l_get_chinfo(&dsc, idx_ai, i, &chinfo);
82 subdevice[
AI].active = 0;
83 subdevice[
AI].count = 0;
84 delete[] subdevice[
AI].chan;
87 subdevice[
AI].chan[i].active =
false;
88 subdevice[
AI].chan[i].analog.maxdata = (1 << chinfo->nb_bits) - 1;
99 subdevice[
AI].active = 0;
100 subdevice[
AI].count = 0;
101 subdevice[
AI].chan = NULL;
105 err = a4l_get_subdinfo(&dsc, idx_ao, &sbinfo);
106 if ((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AO)) {
107 subdevice[
AO].id = idx_ao;
108 subdevice[
AO].active = 0;
109 subdevice[
AO].count = sbinfo->nb_chan;
111 if (!subdevice[
AO].chan)
112 subdevice[
AO].count = 0;
114 for (
size_t i = 0; i < subdevice[
AO].count; ++i) {
115 err = a4l_get_chinfo(&dsc, idx_ao, i, &chinfo);
118 subdevice[
AO].active = 0;
119 subdevice[
AO].count = 0;
120 delete[] subdevice[
AO].chan;
123 subdevice[
AO].chan[i].active =
false;
124 subdevice[
AO].chan[i].analog.maxdata = (1 << chinfo->nb_bits) - 1;
133 subdevice[
AO].active = 0;
134 subdevice[
AO].count = 0;
135 subdevice[
AO].chan = NULL;
141 err = a4l_get_subdinfo(&dsc, idx_dio, &sbinfo);
142 if ((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_DIO)) {
143 subdevice[DIO].id = idx_dio;
144 subdevice[DIO].active = 0;
145 subdevice[DIO].count = sbinfo->nb_chan;
146 subdevice[DIO].chan =
new channel_t[subdevice[DIO].count];
147 if (!subdevice[DIO].chan)
148 subdevice[DIO].count = 0;
150 for (
size_t i = 0; i < subdevice[DIO].count; ++i) {
151 subdevice[DIO].chan[i].active =
false;
152 subdevice[DIO].chan[i].digital.previous_value = 0;
156 subdevice[DIO].active = 0;
157 subdevice[DIO].count = 0;
158 subdevice[DIO].chan = NULL;
165 if (subdevice[
AI].chan)
166 delete[] subdevice[
AI].chan;
167 if (subdevice[
AO].chan)
168 delete[] subdevice[
AO].chan;
169 if (subdevice[DIO].chan)
170 delete[] subdevice[DIO].chan;
175 bool AnalogyDevice::analog_exists(
type_t type,
index_t count)
const 177 if ((type ==
AI && count < subdevice[
AI].count)
178 || (type ==
AO && count < subdevice[
AO].count))
186 if (type !=
AI && type !=
AO && type != DIO)
189 return subdevice[type].count;
197 return subdevice[type].chan[channel].active;
206 output(channel) = 0.0;
208 if (subdevice[type].chan[channel].active && !state)
209 --subdevice[type].active;
210 else if (!subdevice[type].chan[channel].active && state)
211 ++subdevice[type].active;
213 subdevice[type].chan[channel].active = state;
219 if (!analog_exists(type, channel))
223 a4l_chinfo_t* chinfo;
226 err = a4l_get_chinfo(&d, subdevice[type].
id, channel, &chinfo);
230 return static_cast<index_t>(chinfo->nb_rng);
236 if (!analog_exists(type, channel))
244 if (!analog_exists(type, channel))
252 if (!analog_exists(type, channel))
255 return subdevice[type].chan[channel].analog.downsample;
262 if (!analog_exists(type, channel)
266 std::ostringstream rangeString;
268 a4l_rnginfo_t* range;
271 err = a4l_get_rnginfo(&d, subdevice[type].
id, channel, index, &range);
275 rangeString << (double)range->min / 1000000 <<
" to " 276 << (
double)range->max / 1000000;
277 return rangeString.str();
284 if (!analog_exists(type, channel)
294 return "Differential";
306 if (!analog_exists(type, channel)
322 if (!analog_exists(type, channel))
325 return subdevice[type].chan[channel].analog.range;
330 if (!analog_exists(type, channel))
333 return subdevice[type].chan[channel].analog.reference;
338 if (!analog_exists(type, channel))
341 return subdevice[type].chan[channel].analog.units;
346 if (!analog_exists(type, channel))
349 return subdevice[type].chan[channel].analog.offsetunits;
354 if (!analog_exists(type, channel))
357 return subdevice[type].chan[channel].analog.gain;
362 if (!analog_exists(type, channel))
365 return subdevice[type].chan[channel].analog.zerooffset;
370 if (!analog_exists(type, channel)
374 channel_t* chan = &subdevice[type].chan[channel];
376 a4l_rnginfo_t* range;
378 err = a4l_get_rnginfo(&dsc, subdevice[type].
id, channel, index, &range);
382 chan->analog.range = index;
383 chan->analog.conv = (range->max - range->min) / 1e6 / chan->analog.maxdata;
384 chan->analog.offset = -range->min / chan->analog.conv / 1e6;
390 chan->analog.conv = 1 / chan->analog.conv;
399 if (!analog_exists(type, channel)
403 subdevice[type].chan[channel].analog.reference = index;
409 if (!analog_exists(type, channel)
413 subdevice[type].chan[channel].analog.units = index;
421 if (!analog_exists(type, channel)
425 subdevice[type].chan[channel].analog.offsetunits = index;
433 if (!analog_exists(type, channel))
436 subdevice[type].chan[channel].analog.zerooffset = offset;
442 if (!analog_exists(type, channel))
445 subdevice[type].chan[channel].analog.gain = gain;
453 if (!analog_exists(type, channel))
456 subdevice[type].chan[channel].analog.calOffset = value;
463 if (!analog_exists(type, channel))
466 return subdevice[type].chan[channel].analog.calOffset;
471 size_t downsample_rate)
473 if (!analog_exists(type, channel))
476 subdevice[type].chan[channel].analog.downsample = downsample_rate;
482 if (!analog_exists(type, channel))
485 subdevice[type].chan[channel].analog.counter = 0;
492 if (channel >= subdevice[DIO].count)
495 return subdevice[DIO].chan[channel].digital.direction;
501 if (channel >= subdevice[DIO].count)
504 subdevice[DIO].chan[channel].digital.direction = direction;
507 return a4l_config_subd(
508 &dsc, subdevice[DIO].
id, A4L_INSN_CONFIG_DIO_INPUT, channel);
510 return a4l_config_subd(
511 &dsc, subdevice[DIO].
id, A4L_INSN_CONFIG_DIO_OUTPUT, channel);
523 analog_channel_t* channel;
524 a4l_chinfo_t* chinfo;
525 a4l_rnginfo_t* rnginfo;
528 for (
size_t i = 0; i < subdevice[
AI].count; ++i)
529 if (subdevice[
AI].chan[i].active) {
530 channel = &subdevice[
AI].chan[i].analog;
531 if (!channel->counter++) {
533 switch (channel->reference) {
549 err = a4l_get_chinfo(&dsc, subdevice[
AI].
id, i, &chinfo);
552 stderr,
"analogy_device::read::a4l_get_chinfo error: %d\n", err);
555 err = a4l_get_rnginfo(
556 &dsc, subdevice[
AI].
id, i, channel->range, &rnginfo);
559 stderr,
"analogy_device::read::a4l_get_rnginfo error: %d\n", err);
560 size = a4l_sizeof_chan(chinfo);
563 err = a4l_sync_read(&dsc,
565 PACK(i, channel->range, ref),
571 stderr,
"analogy_device::read::a4l_sync_read error: %d\n", err);
574 err = a4l_rawtod(chinfo, rnginfo, &value, &
sample, 1);
577 stderr,
"analogy_device::read::a4l_rawtod error: %d\n", err);
581 channel->gain * value + channel->zerooffset - channel->calOffset;
583 channel->counter %= channel->downsample;
587 unsigned int data = 0, mask = 0;
590 for (
size_t i = 0; i < subdevice[DIO].count; ++i)
591 if (subdevice[DIO].chan[i].active
592 && subdevice[DIO].chan[i].digital.direction ==
DAQ::INPUT)
596 err = a4l_sync_dio(&dsc, subdevice[DIO].
id, &mask, &data);
598 rt_fprintf(stderr,
"analogy_device::read::a4l_sync_dio error: %d\n", err);
601 for (
size_t i = 0; i < subdevice[DIO].count; ++i)
602 if (subdevice[DIO].chan[i].active
603 && subdevice[DIO].chan[i].digital.direction ==
DAQ::INPUT)
606 output(i + offset) = (data & mask) == 0 ? 0 : 5;
615 analog_channel_t* channel;
618 a4l_chinfo_t* chinfo;
621 for (
size_t i = 0; i < subdevice[
AO].count; ++i)
622 if (subdevice[
AO].chan[i].active) {
623 channel = &subdevice[
AO].chan[i].analog;
624 value = round(channel->gain * channel->conv
625 * (input(i) - channel->zerooffset)
626 + channel->offset - channel->calOffset);
629 if (value > channel->maxdata)
630 value = channel->maxdata;
631 else if (value < 0.0)
633 sample =
static_cast<lsampl_t
>(value);
636 switch (channel->reference) {
651 err = a4l_get_chinfo(&dsc, subdevice[
AO].
id, i, &chinfo);
654 stderr,
"analogy_device::write::a4l_get_chinfo error: %d\n", err);
655 size = a4l_sizeof_chan(chinfo);
658 err = a4l_sync_write(&dsc,
660 PACK(i, channel->range, ref),
666 stderr,
"analogy_device::read::a4l_sync_write error: %d\n", err);
672 unsigned int data = 0, mask = 0;
675 for (
size_t i = 0; i < subdevice[DIO].count; ++i) {
676 value = input(i + offset) != 0.0;
677 if (subdevice[DIO].chan[i].active
678 && subdevice[DIO].chan[i].digital.direction ==
DAQ::OUTPUT 679 && subdevice[DIO].chan[i].digital.previous_value != value)
681 subdevice[DIO].chan[i].digital.previous_value = value;
690 a4l_sync_dio(&dsc, subdevice[DIO].
id, &mask, &data);
696 for (
size_t i = 0; i < subdevice[
AI].count
697 && i < static_cast<size_t>(s.loadInteger(
"AI Count"));
700 std::ostringstream str;
708 if (s.loadDouble(str.str() +
" AI Calibration Value"))
710 AI, i, s.loadDouble(str.str() +
" AI Calibration Value"));
711 if (s.loadInteger(str.str() +
" AI Downsample"))
715 for (
size_t i = 0; i < subdevice[
AO].count
716 && i < static_cast<size_t>(s.loadInteger(
"AO Count"));
719 std::ostringstream str;
727 if (s.loadDouble(str.str() +
" AO Calibration Value"))
729 AO, i, s.loadDouble(str.str() +
" AO Calibration Value"));
732 for (
size_t i = 0; i < subdevice[DIO].count
733 && i < static_cast<size_t>(s.loadInteger(
"DIO Count"));
736 std::ostringstream str;
741 s.loadInteger(str.str() +
" DIO Direction")));
747 s.saveInteger(
"AI Count", subdevice[
AI].count);
748 for (
size_t i = 0; i < subdevice[
AI].count; ++i) {
749 std::ostringstream str;
752 s.saveDouble(str.str() +
" AI Calibration Value",
762 s.saveInteger(
"AO Count", subdevice[
AO].count);
763 for (
size_t i = 0; i < subdevice[
AO].count; ++i) {
764 std::ostringstream str;
767 s.saveDouble(str.str() +
" AO Calibration Value",
776 s.saveInteger(
"DIO Count", subdevice[DIO].count);
777 for (
size_t i = 0; i < subdevice[DIO].count; ++i) {
778 std::ostringstream str;
781 s.saveInteger(str.str() +
" DIO Direction",
782 subdevice[DIO].chan[i].digital.direction);
#define A4L_CHAN_AREF_COMMON
#define A4L_CHAN_AREF_DIFF
#define A4L_CHAN_AREF_GROUND
#define A4L_CHAN_AREF_OTHER
int setAnalogCounter(DAQ::type_t, DAQ::index_t)
size_t getAnalogUnitsCount(DAQ::type_t, DAQ::index_t) const
std::string getAnalogRangeString(DAQ::type_t, DAQ::index_t, DAQ::index_t) const
int setAnalogGain(DAQ::type_t, DAQ::index_t, double)
int setAnalogUnits(DAQ::type_t, DAQ::index_t, DAQ::index_t)
AnalogyDevice(a4l_desc_t *, std::string, IO::channel_t *, size_t)
int setAnalogZeroOffset(DAQ::type_t, DAQ::index_t, double)
double getAnalogCalibrationValue(DAQ::type_t, DAQ::index_t) const
int setAnalogDownsample(DAQ::type_t, DAQ::index_t, size_t)
double getAnalogZeroOffset(DAQ::type_t, DAQ::index_t) const
int setDigitalDirection(DAQ::index_t, DAQ::direction_t)
double getAnalogGain(DAQ::type_t, DAQ::index_t) const
std::string getAnalogReferenceString(DAQ::type_t, DAQ::index_t, DAQ::index_t) const
virtual void doSave(Settings::Object::State &) const
virtual void doLoad(const Settings::Object::State &)
DAQ::index_t getAnalogRange(DAQ::type_t, DAQ::index_t) const
size_t getChannelCount(DAQ::type_t) const
bool getChannelActive(DAQ::type_t, DAQ::index_t) const
size_t getAnalogDownsample(DAQ::type_t, DAQ::index_t) const
std::string getAnalogUnitsString(DAQ::type_t, DAQ::index_t, DAQ::index_t) const
DAQ::direction_t getDigitalDirection(DAQ::index_t) const
int setAnalogReference(DAQ::type_t, DAQ::index_t, DAQ::index_t)
int setAnalogCalibrationValue(DAQ::type_t, DAQ::index_t, double)
size_t getAnalogReferenceCount(DAQ::type_t, DAQ::index_t) const
size_t getAnalogRangeCount(DAQ::type_t, DAQ::index_t) const
int setChannelActive(DAQ::type_t, DAQ::index_t, bool)
DAQ::index_t getAnalogReference(DAQ::type_t, DAQ::index_t) const
int setAnalogOffsetUnits(DAQ::type_t, DAQ::index_t, DAQ::index_t)
int setAnalogRange(DAQ::type_t, DAQ::index_t, DAQ::index_t)
DAQ::index_t getAnalogOffsetUnits(DAQ::type_t, DAQ::index_t) const
DAQ::index_t getAnalogUnits(DAQ::type_t, DAQ::index_t) const
void ERROR_MSG(const std::string &errmsg, Args... args)
struct IO::channel_t channel_t
struct Oscilloscope::sample sample