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