24 #define A4L_CHAN_AREF_GROUND 0x1; 25 #define A4L_CHAN_AREF_COMMON 0x2; 26 #define A4L_CHAN_AREF_DIFF 0x4; 27 #define A4L_CHAN_AREF_OTHER 0x8; 43 for (
int i=0; i < dsc.nb_subd; i++)
45 err = a4l_get_subdinfo(&dsc, i, &sbinfo);
48 ERROR_MSG(
"AnalogyDriver: a4l_get_subd_info failed, wrong subdevice index %i (err=%d)\n", i, err);
51 if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AI) && (idx_ai < 0))
53 else if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AO) && (idx_ao < 0))
55 else if (((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_DIO) && (idx_dio < 0))
62 err = a4l_get_subdinfo(&dsc, idx_ai, &sbinfo);
63 if((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AI))
65 subdevice[
AI].id = idx_ai;
66 subdevice[
AI].active = 0;
67 subdevice[
AI].count = sbinfo->nb_chan;
68 subdevice[
AI].chan =
new channel_t[subdevice[
AI].count];
69 if(!subdevice[
AI].chan)
70 subdevice[
AI].count = 0;
72 for(
size_t i=0; i<subdevice[
AI].count; ++i)
74 err = a4l_get_chinfo(&dsc, idx_ai, i, &chinfo);
78 subdevice[
AI].active = 0;
79 subdevice[
AI].count = 0;
80 delete[] subdevice[
AI].chan;
83 subdevice[
AI].chan[i].active =
false;
84 subdevice[
AI].chan[i].analog.maxdata = (1<<chinfo->nb_bits)-1;
97 subdevice[
AI].active = 0;
98 subdevice[
AI].count = 0;
99 subdevice[
AI].chan = NULL;
103 err = a4l_get_subdinfo(&dsc, idx_ao, &sbinfo);
104 if((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_AO))
106 subdevice[
AO].id = idx_ao;
107 subdevice[
AO].active = 0;
108 subdevice[
AO].count = sbinfo->nb_chan;
109 subdevice[
AO].chan =
new channel_t[subdevice[
AO].count];
110 if(!subdevice[
AO].chan)
111 subdevice[
AO].count = 0;
113 for(
size_t i=0; i<subdevice[
AO].count; ++i)
115 err = a4l_get_chinfo(&dsc, idx_ao, i, &chinfo);
119 subdevice[
AO].active = 0;
120 subdevice[
AO].count = 0;
121 delete[] subdevice[
AO].chan;
124 subdevice[
AO].chan[i].active =
false;
125 subdevice[
AO].chan[i].analog.maxdata = (1<<chinfo->nb_bits)-1;
136 subdevice[
AO].active = 0;
137 subdevice[
AO].count = 0;
138 subdevice[
AO].chan = NULL;
144 err = a4l_get_subdinfo(&dsc, idx_dio, &sbinfo);
145 if((err == 0) && ((sbinfo->flags & A4L_SUBD_TYPES) == A4L_SUBD_DIO))
147 subdevice[
DIO].id = idx_dio;
148 subdevice[
DIO].active = 0;
149 subdevice[
DIO].count = sbinfo->nb_chan;
150 subdevice[
DIO].chan =
new channel_t[subdevice[
DIO].count];
151 if(!subdevice[
DIO].chan)
152 subdevice[
DIO].count = 0;
154 for(
size_t i=0; i<subdevice[
DIO].count; ++i)
156 subdevice[
DIO].chan[i].active =
false;
157 subdevice[
DIO].chan[i].digital.previous_value = 0;
163 subdevice[
DIO].active = 0;
164 subdevice[
DIO].count = 0;
165 subdevice[
DIO].chan = NULL;
172 if(subdevice[
AI].chan)
delete[] subdevice[
AI].chan;
173 if(subdevice[
AO].chan)
delete[] subdevice[
AO].chan;
174 if(subdevice[
DIO].chan)
delete[] subdevice[
DIO].chan;
175 if(dsc.sbdata) a4l_close(&dsc);
178 bool AnalogyDevice::analog_exists(
type_t type,
index_t count)
const 180 if((type ==
AI && count < subdevice[
AI].count) ||
181 (type ==
AO && count < subdevice[
AO].count))
189 if(type !=
AI && type !=
AO && type !=
DIO)
192 return subdevice[type].count;
200 return subdevice[type].chan[channel].active;
211 if(subdevice[type].chan[channel].active && !state)
212 --subdevice[type].active;
213 else if(!subdevice[type].chan[channel].active && state)
214 ++subdevice[type].active;
216 subdevice[type].chan[channel].active = state;
222 if(!analog_exists(type,channel))
226 a4l_chinfo_t *chinfo;
229 err = a4l_get_chinfo(&d, subdevice[type].
id, channel, &chinfo);
233 return static_cast<index_t>(chinfo->nb_rng);
238 if(!analog_exists(type,channel))
246 if(!analog_exists(type,channel))
254 if(!analog_exists(type,channel))
257 return subdevice[type].chan[channel].analog.downsample;
265 std::ostringstream rangeString;
267 a4l_rnginfo_t *range;
270 err = a4l_get_rnginfo(&d, subdevice[type].
id, channel, index, &range);
274 rangeString << (double)range->min/1000000 <<
" to " << (
double)range->max/1000000;
275 return rangeString.str();
290 return "Differential";
316 if(!analog_exists(type,channel))
319 return subdevice[type].chan[channel].analog.range;
324 if(!analog_exists(type,channel))
327 return subdevice[type].chan[channel].analog.reference;
332 if(!analog_exists(type,channel))
335 return subdevice[type].chan[channel].analog.units;
340 if(!analog_exists(type,channel))
343 return subdevice[type].chan[channel].analog.offsetunits;
348 if(!analog_exists(type,channel))
351 return subdevice[type].chan[channel].analog.gain;
356 if(!analog_exists(type,channel))
359 return subdevice[type].chan[channel].analog.zerooffset;
367 channel_t *chan = &subdevice[type].chan[channel];
369 a4l_rnginfo_t *range;
371 err = a4l_get_rnginfo(&dsc, subdevice[type].
id, channel, index, &range);
375 chan->analog.range = index;
376 chan->analog.conv = (range->max-range->min)/1e6/chan->analog.maxdata;
377 chan->analog.offset = -range->min/chan->analog.conv/1e6;
383 chan->analog.conv = 1/chan->analog.conv;
393 subdevice[type].chan[channel].analog.reference = index;
402 subdevice[type].chan[channel].analog.units = index;
411 subdevice[type].chan[channel].analog.offsetunits = index;
417 if(!analog_exists(type,channel))
420 subdevice[type].chan[channel].analog.zerooffset = offset;
426 if(!analog_exists(type,channel))
429 subdevice[type].chan[channel].analog.gain = gain;
434 if(!analog_exists(type,channel))
437 subdevice[type].chan[channel].analog.calOffset = value;
443 if(!analog_exists(type,channel))
446 return subdevice[type].chan[channel].analog.calOffset;
451 if(!analog_exists(type,channel))
454 subdevice[type].chan[channel].analog.downsample = downsample_rate;
460 if(!analog_exists(type,channel))
463 subdevice[type].chan[channel].analog.counter = 0;
470 if(channel >= subdevice[
DIO].count)
473 return subdevice[
DIO].chan[channel].digital.direction;
479 if(channel >= subdevice[
DIO].count)
482 subdevice[
DIO].chan[channel].digital.direction = direction;
485 return a4l_config_subd(&dsc, subdevice[
DIO].
id, A4L_INSN_CONFIG_DIO_INPUT, channel);
487 return a4l_config_subd(&dsc, subdevice[
DIO].
id, A4L_INSN_CONFIG_DIO_OUTPUT, channel);
499 analog_channel_t *channel;
500 a4l_chinfo_t *chinfo;
501 a4l_rnginfo_t *rnginfo;
504 for(
size_t i=0; i < subdevice[
AI].count; ++i)
505 if(subdevice[
AI].chan[i].active)
507 channel = &subdevice[
AI].chan[i].analog;
508 if(!channel->counter++)
512 switch (channel->reference)
529 err = a4l_get_chinfo(&dsc, subdevice[
AI].
id, i, &chinfo);
531 rt_fprintf(stderr,
"analogy_device::read::a4l_get_chinfo error: %d\n", err);
534 err = a4l_get_rnginfo(&dsc, subdevice[
AI].
id, i, channel->range, &rnginfo);
536 rt_fprintf(stderr,
"analogy_device::read::a4l_get_rnginfo error: %d\n", err);
537 size = a4l_sizeof_chan(chinfo);
540 err = a4l_sync_read(&dsc, subdevice[
AI].
id, PACK(i,channel->range,ref), 0, &sample, size);
542 rt_fprintf(stderr,
"analogy_device::read::a4l_sync_read error: %d\n", err);
545 err = a4l_rawtod(chinfo, rnginfo, &value, &sample, 1);
547 rt_fprintf(stderr,
"analogy_device::read::a4l_rawtod error: %d\n", err);
550 output(i) = channel->gain * value + channel->zerooffset - channel->calOffset;
552 channel->counter %= channel->downsample;
556 unsigned int data = 0, mask = 0;
559 for(
size_t i=0; i < subdevice[
DIO].count; ++i)
560 if(subdevice[
DIO].chan[i].active && subdevice[
DIO].chan[i].digital.direction ==
DAQ::INPUT)
564 err = a4l_sync_dio(&dsc, subdevice[
DIO].
id, &mask, &data);
566 rt_fprintf(stderr,
"analogy_device::read::a4l_sync_dio error: %d\n", err);
569 for(
size_t i=0; i < subdevice[
DIO].count; ++i)
570 if(subdevice[
DIO].chan[i].active && subdevice[
DIO].chan[i].digital.direction ==
DAQ::INPUT)
573 output(i+offset) = (data & mask) == 0 ? 0 : 5;
582 analog_channel_t *channel;
585 a4l_chinfo_t *chinfo;
588 for(
size_t i=0; i < subdevice[
AO].count; ++i)
589 if(subdevice[
AO].chan[i].active)
591 channel = &subdevice[
AO].chan[i].analog;
592 value = round(channel->gain * channel->conv * (
input(i) - channel->zerooffset) + channel->offset - channel->calOffset);
595 if(value > channel->maxdata)
596 value = channel->maxdata;
599 sample =
static_cast<lsampl_t
>(value);
602 switch (channel->reference)
618 err = a4l_get_chinfo(&dsc, subdevice[
AO].
id, i, &chinfo);
620 rt_fprintf(stderr,
"analogy_device::write::a4l_get_chinfo error: %d\n", err);
621 size = a4l_sizeof_chan(chinfo);
624 err = a4l_sync_write(&dsc, subdevice[
AO].
id, PACK(i,channel->range,ref), 0, &sample, size);
626 rt_fprintf(stderr,
"analogy_device::read::a4l_sync_write error: %d\n", err);
632 unsigned int data = 0, mask = 0;
635 for(
size_t i=0; i < subdevice[
DIO].count; ++i)
637 value =
input(i+offset) != 0.0;
638 if(subdevice[
DIO].chan[i].active && subdevice[
DIO].chan[i].digital.direction ==
DAQ::OUTPUT && subdevice[
DIO].chan[i].digital.previous_value != value)
640 subdevice[
DIO].chan[i].digital.previous_value = value;
641 data |= value == 0 ? (0<<i) : (1<<i);
647 a4l_sync_dio(&dsc, subdevice[
DIO].
id, &mask, &data);
653 for(
size_t i = 0; i < subdevice[
AI].count && i < static_cast<size_t>(s.
loadInteger(
"AI Count")); ++i)
655 std::ostringstream str;
663 if(s.
loadDouble(str.str()+
" AI Calibration Value"))
669 for(
size_t i = 0; i < subdevice[
AO].count && i < static_cast<size_t>(s.
loadInteger(
"AO Count")); ++i)
671 std::ostringstream str;
679 if(s.
loadDouble(str.str()+
" AO Calibration Value"))
683 for(
size_t i = 0; i < subdevice[
DIO].count && i < static_cast<size_t>(s.
loadInteger(
"DIO Count")); ++i)
685 std::ostringstream str;
695 for(
size_t i = 0; i < subdevice[
AI].count; ++i)
697 std::ostringstream str;
710 for(
size_t i = 0; i < subdevice[
AO].count; ++i)
712 std::ostringstream str;
724 for(
size_t i = 0; i < subdevice[
DIO].count; ++i)
726 std::ostringstream str;
729 s.
saveInteger(str.str()+
" DIO Direction",subdevice[
DIO].chan[i].digital.direction);