A text version, for all the crazies
authorDavid Schleef <ds@schleef.org>
Tue, 10 Jul 2001 22:25:26 +0000 (22:25 +0000)
committerDavid Schleef <ds@schleef.org>
Tue, 10 Jul 2001 22:25:26 +0000 (22:25 +0000)
doc/comedilib.txt [new file with mode: 0644]

diff --git a/doc/comedilib.txt b/doc/comedilib.txt
new file mode 100644 (file)
index 0000000..d044ac7
--- /dev/null
@@ -0,0 +1,1716 @@
+  Comedi Documentation
+  David Schleef ds@stm.lbl.gov, Frank Hess fmhess@uiuc.edu
+
+
+  1\b1.\b.  I\bIn\bnt\btr\bro\bod\bdu\buc\bct\bti\bio\bon\bn
+
+  This is preliminary documentation for Comedi and Comedilib.
+
+
+  2\b2.\b.  I\bIn\bns\bst\bta\bal\bll\bla\bat\bti\bio\bon\bn a\ban\bnd\bd c\bco\bon\bnf\bfi\big\bgu\bur\bra\bat\bti\bio\bon\bn
+
+
+  This section covers compiling, installing, and configuring comedi and
+  comedlib.
+
+
+
+  2\b2.\b.1\b1.\b.  C\bCo\bom\bmp\bpi\bil\bli\bin\bng\bg a\ban\bnd\bd I\bIn\bns\bst\bta\bal\bll\bli\bin\bng\bg
+
+
+  This section has not been written.
+
+
+
+  2\b2.\b.2\b2.\b.  I\bIn\bns\bsm\bmo\bod\bd'\b'd\bdi\bin\bng\bg t\bth\bhe\be k\bke\ber\brn\bne\bel\bl m\bmo\bod\bdu\bul\ble\be
+
+
+  This section has not been written.
+
+
+
+  2\b2.\b.3\b3.\b.  C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg c\bco\bom\bme\bed\bdi\bi f\bfo\bor\br y\byo\bou\bur\br h\bha\bar\brd\bdw\bwa\bar\bre\be
+
+
+
+  I assume that your hardware device is in your computer, and that you
+  know the relevant details about it, i.e., what kind of card it is, the
+  I/O base, the IRQ, jumper settings related to input ranges, etc.
+
+  To tell the comedi kernel module that you have a particular device,
+  and some information about it, you will be running the comedi_config
+  command.  Perhaps you should read the man page now.
+
+  In this tutorial, I will go through the process of configuring comedi
+  for two devices, a National Instruments AT-MIO-16E-10 and a Data
+  Translation DT2821-F-8DI.
+
+  The NI board is plug-and-play, and the man page tells me that I need
+  to configure the PnP part of the board with isapnptools.  The
+  isapnptools package is a little cryptic, but the concepts are simple.
+  Once I learned how to use it, I settled on a /etc/isapnp.conf file
+  that contained the lines:
+
+
+
+       # ANSI string -->National Instruments, AT-MIO-16E-10<--
+       (CONFIGURE NIC2400/10725401 (LD 0
+               (IO 0 (BASE 0x0260))
+               (INT 0 (IRQ 3 (MODE +E)))
+       #       (DMA 0 (CHANNEL 5))
+       #       (DMA 1 (CHANNEL 6))
+               (ACT Y)
+       ))
+
+
+  It also contains a few lines about overall configuration and about my
+  sound card.  I found out after a bit of trial-and-error that the NI
+  board does not always work with interrupts other than IRQ 3.  YMMV.
+  Currently, the driver doesn't use DMA, but it may in the future, so I
+  commented out the DMA lines.  It is a curious fact that the device
+  ignores the IRQ and DMA information given here, however, I keep the
+  information here to remind myself that the numbers aren't arbitrary.
+
+  When I run comedi_config (as root, of course), I provide the same
+  information.  Since I want to have the board configured every time I
+  boot, I put the line
+
+
+
+       /usr/sbin/comedi_config /dev/comedi0 atmio-E 0x260,3
+
+
+
+  into /etc/rc.d/rc.local.  You can, of course, run this command at a
+  command prompt.  The man page tells me that the option list is
+  supposed to be "(I/O base),(IRQ)", so I used the same numbers as I put
+  in /etc/isapnp.conf, i.e., 0x260,3.
+
+  For the Data Translation board, I need to have a list of the jumper
+  settings.  Fortunately, I wrote them all down in the manual -- I hope
+  they are still correct.  However, I had to open the case to figure out
+  which board in the series I had.  It is a DT2821-f-8di.  The man page
+  of comedi_config tells me that I need to know the I/O base, IRQ, DMA
+  1, DMA 2.  However, since I wrote the driver, I know that it also
+  recognizes the differential/single-ended and unipolar/bipolar jumpers.
+  As always, the source is the final authority, and looking in
+  module/dt282x.c tells me that the options list is interpreted as:
+
+
+  +\bo  I/O base
+
+  +\bo  IRQ
+
+  +\bo  1=differential, 0=single ended
+
+  +\bo  ai 0=unipolar, 1=bipolar
+
+  +\bo  ao0 0=unipolar, 1=bipolar
+
+  +\bo  ao1 0=unipolar, 1=bipolar
+
+  +\bo  dma1
+
+  +\bo  dma2
+
+  (ai=analog input, ao=analog output.)  From this, I decide that the
+  appropriate options list is
+
+
+
+       0x200,4,,1,1,1
+
+
+
+  I left the differential/single-ended number blank, since the driver
+  already knowns (from the board name), that it is differential.  I
+  also left the DMA numbers blank, since I don't want the driver to use
+  DMA.  (Don't want it to interfere with my sound card -- life is full
+  of difficult choices.)  Keep in mind that things commented in the
+  source, but not in the documentation are about as likely to change as
+  the weather, so I put good comments next to the following line when I
+  put it in rc.local.
+
+
+
+       /usr/sbin/comedi_config /dev/comedi1 dt2821-f-8di 0x200,4,,1,1,1
+
+
+
+  So now I think that I have my boards configured correctly.  Since data
+  acquisition boards are not typically well-engineered, comedi sometimes
+  can't figure out if the board is actually there.  If it can't, it
+  assumes you are right.  Both of these boards are well-made, so comedi
+  will give me an error message if it can't find them.  The comedi
+  kernel module, since it is a part of the kernel, prints messages to
+  the kernel logs, which you can access through the command 'dmesg' or
+  /var/log/messages.  Here is a configuration failure (from dmesg):
+
+
+
+       comedi0: ni_E: 0x0200 can't find board
+
+
+
+  When it does work, I get:
+
+
+
+       comedi0: ni_E: 0x0260 at-mio-16e-10 ( irq = 3 )
+
+
+
+  Note that it also correctly identified my board.
+
+
+
+  2\b2.\b.4\b4.\b.  G\bGe\bet\btt\bti\bin\bng\bg i\bin\bnf\bfo\bor\brm\bma\bat\bti\bio\bon\bn f\bfr\bro\bom\bm c\bco\bom\bme\bed\bdi\bi
+
+
+
+  So now that we have comedi talking to the hardware, we want to talk to
+  comedi.  Here's some pretty low-level information -- it's sometimes
+  useful for debugging:
+
+
+
+       cat /proc/comedi
+
+
+
+  Right now, on my computer, this command gives:
+
+
+
+  comedi version 0.6.4
+  format string
+   0: atmio-E              at-mio-16e-10           7
+   1: dt282x               dt2821-f-8di            4
+
+
+
+  This is a feature that is not well-developed yet.  Basically, it
+  currently tells you driver name, device name, and number of
+  subdevices.
+
+  In the demo/ directory, there is a command called info, which provides
+  information about each subdevice on the board.  The output of it is
+  rather long, since I have 7 subdevices  (4 or fewer is common for
+  other boards.)  Here's part of the output of the NI board (which is on
+  /dev/comedi0.)  ('demo/info /dev/comedi0')
+
+
+
+       overall info:
+         version code: 0x000604
+         driver name: atmio-E
+         board name: at-mio-16e-10
+         number of subdevices: 7
+       subdevice 0:
+         type: 1 (unknown)
+         number of channels: 16
+         max data value: 4095
+
+
+       ...
+
+
+  The overall info gives information about the device -- basically the
+  same information as /proc/comedi.
+
+  This board has 7 subdevices.  Devices are separated into subdevices
+  that each have a distinct purpose -- e.g., analog input, analog
+  output, digital input/output.  This board also has an EEPROM and
+  calibration DACs that are also subdevices.
+
+  Subdevice 0 is the analog input subdevice.  You would have known this
+  from the 'type: 1 (unknown)' line, if I've updated demo/info recently,
+  because it would say 'type: 1 (analog input)' instead.  The other
+  lines should be self-explanitory.  Comedi has more information about
+  the device, but demo/info doesn't currently display this.
+
+
+
+  3\b3.\b.  I\bIn\bnd\bdi\biv\bvi\bid\bdu\bua\bal\bl d\bdr\bri\biv\bve\ber\brs\bs
+
+
+  This section contains information that is specific to each hardware
+  driver.  The most current information about a driver is included in
+  the comedi source.
+
+
+  3\b3.\b.1\b1.\b.  N\bNa\bat\bti\bio\bon\bna\bal\bl I\bIn\bns\bst\btr\bru\bum\bme\ben\bnt\bts\bs A\bAT\bT-\b-M\bMI\bIO\bO E\bE s\bse\ber\bri\bie\bes\bs
+
+
+
+  3\b3.\b.2\b2.\b.  D\bDa\bat\bta\ba T\bTr\bra\ban\bns\bsl\bla\bat\bti\bio\bon\bn
+
+
+
+  4\b4.\b.  W\bWr\bri\bit\bti\bin\bng\bg p\bpr\bro\bog\bgr\bra\bam\bms\bs t\bth\bha\bat\bt u\bus\bse\be c\bco\bom\bme\bed\bdi\bi a\ban\bnd\bd c\bco\bom\bme\bed\bdi\bil\bli\bib\bb
+
+
+
+  4\b4.\b.1\b1.\b.  Y\bYo\bou\bur\br f\bfi\bir\brs\bst\bt c\bco\bom\bme\bed\bdi\bi p\bpr\bro\bog\bgr\bra\bam\bm
+
+
+  This example requires a card that has analog or digital input.  Right
+  to the source:
+
+
+
+       #include <stdio.h>      /* for printf() */
+       #include <comedilib.h>
+
+       int subdev = 0;         /* change this to your input subdevice */
+       int chan = 0;           /* change this to your channel */
+       int range = 0;          /* more on this later */
+       int aref = AREF_GROUND; /* more on this later */
+
+       int main(int argc,char *argv[])
+       {
+               comedi_t *it;
+               int chan=0;
+               lsampl_t data;
+
+               it=comedi_open("/dev/comedi0");
+
+               comedi_data_read(it,subdev,chan,range,aref,XXX data);
+
+               printf("%d\n",data);
+
+               return 0;
+       }
+
+
+
+  Should be understandable.  Open the device, get the data, print it
+  out.  This is basically the guts of demo/inp.c, without error checking
+  or fancy options.  Compile it using
+
+
+
+       cc tut1.c -lcomedi -o tut1
+
+
+
+  A few notes:  The range variable tells comedi which gain to use when
+  measuring an analog voltage.  Since we don't know (yet) which numbers
+  are valid, or what each means, we'll use 0, because it won't cause
+  errors.  Likewise with aref, which determines the analog reference
+  used.
+
+
+
+  4\b4.\b.2\b2.\b.  C\bCo\bon\bnv\bve\ber\brt\bti\bin\bng\bg s\bsa\bam\bmp\bpl\ble\bes\bs t\bto\bo v\bvo\bol\blt\bta\bag\bge\bes\bs
+
+
+  If you selected an analog input subdevice, you should notice that the
+  output of tut1 is a number between 0 and 4095, or 0 and 65535,
+  depending on the number of bits in the A/D converter.  Comedi samples
+  are a\bal\blw\bwa\bay\bys\bs unsigned, with 0 representing the lowest voltage of the
+  ADC, and 4095 the highest.  Comedi compensates for anything else the
+  manual for your device says.  However, you probably prefer to have
+  this number translated to a voltage.  Naturally, as a good programmer,
+  your first question is: "How do I do this in a device-independent
+  manner?"
+
+  Most devices give you a choice of gain and unipolar/bipolar input, and
+  Comedi allows you to select which of these to use.  This parameter is
+  called the "range parameter", since it specifies the "input range" for
+  analog input (or "output range" analog output.)  The range parameter
+  represents both the gain and the unipolar/bipolar aspects.
+
+  Comedi keeps the number of available ranges and the largest sample
+  value for each subdevice/channel combination.  (Some devices allow
+  different input/output ranges for different channels in a subdevice.)
+
+  The largest sample value can be found using the function:
+
+  comedi_get_maxdata()
+
+  The number of available ranges can be found using the function:
+
+  comedi_get_n_ranges()
+
+  For each value of the range parameter for a particular
+  subdevice/channel, you can get range information using the function:
+
+  ptr=comedi_get_range(comedi_file,subdevice,channel, range)
+
+  which returns a pointer to a comedi_range structure.  The comedi_range
+  structure looks like
+
+
+
+       typedef struct{
+               double min;
+               double max;
+               unsigned int unit;
+       }comedi_range;
+
+
+
+  The structure element 'min' represents the voltage corresponding to
+  comedi_data_read() returning 0, and 'max' represents
+  comedi_data_read() returning 'maxdata', (i.e., 4095 for 12 bit A/C
+  converters, 65535 for 16 bit, or, 1 for digital input -- more on this
+  in a bit.)  The max refer to voltage, current, etc.
+
+  "Could it get easier?", you say.  Well, yes.  Use the function
+  comedi_to_phys(), which converts data values to physical units.  Call
+  it using something like
+
+
+
+       volts=comedi_to_phys(it,data,range,maxdata);
+
+
+  and the opposite
+
+
+
+       data=comedi_from_phys(it,volts,range,maxdata);
+
+
+
+  4\b4.\b.3\b3.\b.  A\bAn\bno\bot\bth\bhe\ber\br s\bse\bec\bct\bti\bio\bon\bn
+
+
+
+  In addition to providing low level routines for data access, the
+  comedi library provides higher-level access, much like the standard C
+  library provides fopen(), etc.  as a high-level (and portable)
+  alternative to the direct UNIX system calls open(), etc.  Similarily
+  to fopen(), we have comedi_open():
+
+
+
+       file=comedi_open("/dev/comedi0");
+
+
+
+  where file is of type (comedi_t *).  This function calls open(), like
+  we did explicitly in a previous section, but also fills the comedi_t
+  structure with lots of goodies -- information that we will need to use
+  soon.
+
+  Specifically, we needed to know maxdata for a specific
+  subdevice/channel.  How about:
+
+
+
+       maxdata=comedi_get_maxdata(file,subdevice,channel);
+
+
+
+  Wow.  How easy.  And the range type?
+
+
+
+       range_type=comedi_get_rangetype(file,subdevice,channel);
+
+
+
+  Cool.  Other information you need to know about a channel can be
+  gotten in a similar way.
+
+
+
+  4\b4.\b.4\b4.\b.  Y\bYo\bou\bur\br s\bse\bec\bco\bon\bnd\bd c\bco\bom\bme\bed\bdi\bi p\bpr\bro\bog\bgr\bra\bam\bm
+
+
+
+  Actually, this is the first comedi program again, just that we've
+  added what we've learned.
+       #include <stdio.h>      /* for printf() */
+       #include <comedi.h>     /* also included by comedilib.h */
+       #include <comedilib.h>  /* for comedi_get() */
+
+       int subdev = 0;         /* change this to your input subdevice */
+       int chan = 0;           /* change this to your channel */
+       int range = 0;          /* more on this later */
+       int aref = 0;           /* more on this later */
+
+       int main(int argc,char *argv[])
+       {
+               comedi_t *cf;
+               int chan=0;
+               lsampl_t data;
+               int maxdata,rangetype;
+               double volts;
+
+               cf=comedi_open("/dev/comedi0");
+
+               maxdata=comedi_get_maxdata(cf,subdev,chan);
+
+               rangetype=comedi_get_rangetype(cf,subdev,chan);
+
+               comedi_data_read(cf->fd,subdev,chan,range,aref,XXX data);
+
+               volts=comedi_to_phys(data,rangetype,range,maxdata);
+
+               printf("%d %g\n",data,volts);
+
+               return 0;
+       }
+
+
+
+  5\b5.\b.  A\bAp\bpp\bpl\bli\bic\bca\bat\bti\bio\bon\bn-\b-s\bsp\bpe\bec\bci\bif\bfi\bic\bc f\bfu\bun\bnc\bct\bti\bio\bon\bns\bs
+
+
+
+  5\b5.\b.1\b1.\b.  D\bDi\big\bgi\bit\bta\bal\bl I\bIn\bnp\bpu\but\bt/\b/O\bOu\but\btp\bpu\but\bt
+
+
+  Many boards supported by comedi have digital input and output
+  channels.  Some boards allow the direction of a channel to be
+  specified in software.
+
+  Comedi groups digital channels into subdevice, which is a group of
+  digital channels that have the same characteristics.  For example,
+  digital output lines will be grouped into a digital output subdevice,
+  bidirectional digital lines will be grouped into a digital I/O
+  subdevice.  Thus, there can be multiple digital subdevices on a
+  particular board.
+
+  Individual digital lines can be read and written using the functions
+
+  comedi_dio_read(device,subdevice,channel,unsigned int *bit);
+  comedi_dio_write(device,subdevice,channel,unsigned int bit);
+
+  The direction of bidirectional lines can be configured using the
+  function
+
+  comedi_dio_config(device,subdevice,channel,unsigned int dir);
+
+  The parameter dir should be either COMEDI_INPUT or COMEDI_OUTPUT.
+  Many digital I/O subdevices group channels into blocks for configuring
+  direction.  Changing one channel in a block changes the entire block.
+
+  Multiple channels can be read and written simultaneously using the
+  function
+
+  comedi_dio_bitfield(device,subdevice,unsigned int write_mask,unsigned
+  int *bits);
+
+  Each channel is assigned to a bit in the write_mask and bits bitfield.
+  If a bit in write_mask is set, the corresponding bit in *bits will be
+  written to the corresponding digital output line.  Each digital line
+  is then read and placed into *bits.  The value of bits in *bits
+  corresponding to digital output lines is undefined and device-
+  specific.  Channel 0 is the least significant bit in the bitfield;
+  channel 31 is the most significant bit.  Channels higher than 31
+  cannot be accessed using this method.
+
+
+
+  5\b5.\b.2\b2.\b.  S\bSl\blo\bow\bwl\bly\by-\b-v\bva\bar\bry\byi\bin\bng\bg i\bin\bnp\bpu\but\bts\bs
+
+
+
+  Sometimes, your input channels change slowly enough that you are able
+  to average many sucessive input values to get a more accurate
+  measurement of the actual value.  In general, the more samples you
+  average, the better your estimate gets, roughly by a factor of
+  sqrt(number_of_samples).  Obviously, there are limitations to this:
+
+
+
+  +\bo  you are ultimately limited by "spurious free dynamic range"
+
+  +\bo  you need to have _some_ noise on the input channel, otherwise you
+     will be averaging the same number N times.
+
+  +\bo  the more noise you have, the greater your SFDR, but it takes many
+     more samples to compensate for the increased noise
+
+  +\bo  if you feel the need to average samples for 2 seconds, your signal
+     will need to be _very_ slowly-varying, i.e., not varying more than
+     your target uncertainty for the entire 2 seconds.
+
+  As you might have guessed, the comedi library has functions to help
+  you in your quest to accurately measure slowly varying inputs.  I use
+  these functions to measure thermocouple voltages -- actually, the
+  library functions came from a section of code that was previously part
+  of the thermocouple reading program.
+
+  The comedi self-calibration utility also uses these functions.  On
+  some hardware, it is possible to tell it to measure an internal stable
+  voltage reference, which is typically going to be very slowly varying
+  -- on the kilosecond time scale or more.  So it is reasonable to
+  measure millions of samples, to get a very accurate measurement of the
+  A/D converter output value that corresponds to the voltage reference.
+  Sometimes, however, this is overkill, since there is no need to
+  perform a part-per-million calibration to a standard that is only
+  accurate to part-per-thousand.
+
+
+
+  5\b5.\b.3\b3.\b.  C\bCo\bom\bmm\bma\ban\bnd\bds\bs
+
+
+
+  Many data acquisition devices have the capability to directly control
+  acquisition using either an on-board timer or an external triggering
+  input.  Comedi commands are used to control this kind of acquisition.
+  The ``comedi_cmd'' structure is used to control acquisition and query
+  the capabilities of a device (see also ``comedi_command()'',
+  ``comedi_command_test()'', and ``comedi_get_cmd_src_mask()'').
+
+  Commands specify a particular data acquisition sequence, which is
+  comprised of a number of scans.  Each scan is comprised of a number of
+  conversions, which usually corresponds to a single A/D or D/A
+  conversion.  The start and end of the sequence, and the start and end
+  of each scan, and each conversion is called an event.
+
+  Each of these 5 types of events are caused by a triggering source,
+  specified through the *_src members of the ``comedi_cmd'' structure.
+  The source types are:
+
+
+  +\bo  TRIG_NONE:      don't ever cause an event, sometimes used as a
+     stop_src.
+
+  +\bo  TRIG_NOW:       cause event to occur immediately, the most common
+     start_src.  It is also used sometimes as a convert_src for 'burst
+     mode' aquisition where the individual channels in a scan are
+     scanned through as quickly as possible.
+
+  +\bo  TRIG_FOLLOW:    see notes below, usually used as a scan_begin_src.
+
+  +\bo  TRIG_TIME:      cause event to occur at a particular time
+
+  +\bo  TRIG_TIMER:     cause event to occur repeatedly at a specific rate,
+     often used as a scan_begin_src or convert_src.
+
+  +\bo  TRIG_COUNT:     cause event when count reaches specific value,
+     almost always used as the scan_end_src and often for stop_src.
+
+  +\bo  TRIG_EXT:       external signal causes event, used as start_src for
+     externally triggered conversions, and as scan_begin_src or
+     convert_src for externally paced conversions.
+
+  +\bo  TRIG_INT:       internal signal causes event, will probably be used
+     as start_src for output commands in the future.
+
+  For every trigger, there is a corresponding argument (the *_arg
+  members of the ``comedi_cmd'' structure) whose meaning depends on the
+  type of trigger.  The meanings of the arguments are as follows:
+
+
+  +\bo  trigger src = TRIG_NONE: argument has no meaning
+
+  +\bo  trigger src = TRIG_NOW: argument is the delay in nanoseconds before
+     triggering
+
+  +\bo  trigger src = TRIG_FOLLOW: argument has no meaning
+
+  +\bo  trigger src = TRIG_TIME: argument is the time at which to trigger
+     (in what units??), but no drivers support this yet.
+
+  +\bo  trigger src = TRIG_TIMER: argument is the period in nanoseconds
+     between triggers
+
+
+  +\bo  trigger src = TRIG_COUNT: argument is the number of 'counts' per
+     trigger.  For comedi_cmd.stop_arg, this is the number of scans to
+     perform before ending aquisition.  For comedi_cmd.scan_end_arg,
+     this is the number of conversions to perform per scan.
+
+  +\bo  trigger src = TRIG_EXT: argument is the digital input channel to
+     trigger on.
+
+  +\bo  trigger src = TRIG_INT: argument meaning is unknown??
+
+  Not all triggers are applicable to all events.  Supported triggers for
+  specific events depends significantly on your particular device.
+
+  TRIG_FOLLOW is a special type of trigger for scan_begin events that
+  triggers on the next lower level trigger, in this case, the trigger
+  for convert events.  It may or may not be supported.  Later, it may
+  also be used for start events if you want to chain multiple commands.
+
+  The chanlist member of the ``comedi_cmd'' structure should point to an
+  array whose number of elements is specificed by chanlist_len (this
+  will generally be the same as the scan_end_arg).  The chanlist
+  specifies the sequence of channels and gains (and analog references)
+  that should be stepped through for each scan.  The elements of the
+  chanlist array should be initialized by packing the channel, range and
+  reference information together with the ``CR_PACK(channel, range,
+  aref)'' macro.
+
+  The final member of the ``comedi_cmd'' structure is 'flags'.  The
+  following flags are valid, and can be bitwise-or'd together.
+
+
+  +\bo  TRIG_BOGUS:     do the motions??
+
+  +\bo  TRIG_DITHER:    enable dithering??
+
+  +\bo  TRIG_DEGLITCH:  enable deglitching??
+
+  +\bo  TRIG_RT:        ask driver to use a hard real-time interrupt
+     handler.  This will reduce latency in handling interrupts from your
+     data aquisition hardware.  It can be useful if you are sampling at
+     high frequency, or if your hardware has a small onboard fifo.  You
+     must have a real-time kernel (RTAI or RTLinux) and must compile
+     comedi with real-time support or this flag will do nothing.
+
+  +\bo  TRIG_CONFIG:    perform configuration, not triggering.
+
+  +\bo  TRIG_WAKE_EOS:  some drivers will change their behaviour when this
+     flag is set, trying to transfer data at the end of every scan
+     (instead of, for example, passing data in chunks whenever the
+     board's onboard fifo is half full).  This flag may degrade a
+     driver's performance at higher frequencies.
+
+  +\bo  TRIG_WRITE:     write to bidirectional devices.  Could be useful in
+     principle, if someone wrote a driver that supported commands for a
+     digital i/o device that could do either input or output.
+
+     There are also a few flags that indicate how timing arguments
+     should be rounded if the hardware cannot achieve the exact timing
+     requested.
+
+  +\bo  TRIG_ROUND_NEAREST: round to nearest supported timing period, the
+     default.
+
+  +\bo  TRIG_ROUND_DOWN: round period down.
+
+
+  +\bo  TRIG_ROUND_UP: round period up.
+
+  +\bo  TRIG_ROUND_UP_NEXT: this one doesn't do anything, and I don't know
+     what it was intended to do??
+
+
+
+  6\b6.\b.  L\bLi\bib\bbc\bco\bom\bme\bed\bdi\bi R\bRe\bef\bfe\ber\bre\ben\bnc\bce\be
+
+
+
+  6\b6.\b.1\b1.\b.  C\bCo\bon\bns\bst\bta\ban\bnt\bts\bs a\ban\bnd\bd M\bMa\bac\bcr\bro\bos\bs
+
+
+
+  6\b6.\b.1\b1.\b.1\b1.\b.  C\bCR\bR_\b_P\bPA\bAC\bCK\bK(\b(c\bch\bha\ban\bnn\bne\bel\bl,\b, r\bra\ban\bng\bge\be,\b, a\bar\bre\bef\bf)\b)
+
+
+  undocumented
+
+
+  6\b6.\b.1\b1.\b.2\b2.\b.  R\bRA\bAN\bNG\bGE\bE_\b_L\bLE\bEN\bNG\bGT\bTH\bH(\b()\b) (\b(d\bde\bep\bpr\bre\bec\bca\bat\bte\bed\bd)\b)
+
+
+  RANGE_LENGTH(rangetype)
+
+
+  Rangetype values are library-internal tokens that represent an array
+  of range information structures.  These numbers are primarily used for
+  communication between the kernel and library.
+
+
+  The RANGE_LENGTH() macro returns the length of the array that is
+  specified by the rangetype token.
+
+
+  The RANGE_LENGTH() macro is deprecated, and should not be used in new
+  applications.  It is scheduled to be removed from the header file at
+  version 1.0.  Binary compatibility may be broken for version 1.1.
+
+
+
+  6\b6.\b.2\b2.\b.  D\bDa\bat\bta\ba T\bTy\byp\bpe\bes\bs a\ban\bnd\bd S\bSt\btr\bru\buc\bct\btu\bur\bre\bes\bs
+
+
+  6\b6.\b.2\b2.\b.1\b1.\b.  c\bco\bom\bme\bed\bdi\bi_\b_t\bt
+
+  The data type comedi_t is used to represent an open Comedi device.  A
+  valid comedi_t pointer is returned by a successful call to
+  comedi_open(), and should be used for subsequent access to the device.
+  It is a transparent type, and pointers to type comedi_t should not be
+  dereferenced by the application.
+
+
+
+  6\b6.\b.2\b2.\b.2\b2.\b.  s\bsa\bam\bmp\bpl\bl_\b_t\bt
+
+  The data type sampl_t is one of the generic types used to represent
+  data values in libcomedi.  It is used in a few places where a shorter
+  data type is useful, but is limited to 16 bits on the i386
+  architecture.
+
+  6\b6.\b.2\b2.\b.3\b3.\b.  l\bls\bsa\bam\bmp\bpl\bl_\b_t\bt
+
+  The data type lsampl_t is one of the generic types used to represent
+  data values in libcomedi.  It is currently defined to be unsigned int.
+
+
+
+  6\b6.\b.2\b2.\b.4\b4.\b.  c\bco\bom\bme\bed\bdi\bi_\b_t\btr\bri\big\bg_\b_s\bst\btr\bru\buc\bct\bt (\b(d\bde\bep\bpr\bre\bec\bca\bat\bte\bed\bd)\b)
+
+
+  The comedi_trig structure
+
+
+
+       struct comedi_trig_struct{
+               unsigned int subdev;            /* subdevice */
+               unsigned int mode;              /* mode */
+               unsigned int flags;
+               unsigned int n_chan;            /* number of channels */
+               unsigned int *chanlist;         /* channel/range list */
+               sampl_t *data;                  /* data list, size depends on subd flags */
+               unsigned int n;                 /* number of scans */
+               unsigned int trigsrc;
+               unsigned int trigvar;
+               unsigned int trigvar1;
+               unsigned int data_len;
+               unsigned int unused[3];
+       }
+
+
+
+  The comedi_trig structure is a control structure used by the
+  COMEDI_TRIG ioctl, an older method of communicating instructions to
+  the driver and hardware.  Use of comedi_trig is deprecated, and should
+  not be used in new applications.
+
+
+  This structure is defined as part of the Comedi kernel interface.
+
+
+
+  6\b6.\b.2\b2.\b.5\b5.\b.  c\bco\bom\bme\bed\bdi\bi_\b_s\bsv\bv_\b_t\bt
+
+
+
+       struct comedi_sv_struct{
+               comedi_t *dev;
+               unsigned int subdevice;
+               unsigned int chan;
+
+               /* range policy */
+               int range;
+               int aref;
+
+               /* number of measurements to average (for ai) */
+               int n;
+
+               lsampl_t maxdata;
+       }
+
+
+  The comedi_sv_t structure is used by the comedi_sv_*() functions to
+  provide a simple method of accurately measuring slowly varying inputs.
+  See the relevant section for more details.
+
+
+
+  6\b6.\b.2\b2.\b.6\b6.\b.  c\bco\bom\bme\bed\bdi\bi_\b_c\bcm\bmd\bd
+
+
+  undocumented
+
+
+  Related functions are described in section XXX.
+
+
+  This structure is defined as part of the Comedi kernel interface.
+
+
+
+  6\b6.\b.2\b2.\b.7\b7.\b.  c\bco\bom\bme\bed\bdi\bi_\b_i\bin\bns\bsn\bn
+
+
+  undocumented
+
+
+  Related functions are described in section XXX.
+
+
+  This structure is defined as part of the Comedi kernel interface.
+
+
+
+  6\b6.\b.2\b2.\b.8\b8.\b.  c\bco\bom\bme\bed\bdi\bi_\b_r\bra\ban\bng\bge\be
+
+
+  undocumented
+
+
+
+  6\b6.\b.3\b3.\b.  F\bFu\bun\bnc\bct\bti\bio\bon\bns\bs
+
+
+
+  6\b6.\b.3\b3.\b.1\b1.\b.  c\bco\bom\bme\bed\bdi\bi_\b_c\bcl\blo\bos\bse\be(\b()\b)
+
+
+  void comedi_close(comedi_t *it);
+
+
+  Closes a device previously opened by comedi_open().
+
+
+  The return type of this function will change to int, in order to match
+  fclose.
+
+
+  Source: /lib/comedi.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b2.\b.  c\bco\bom\bme\bed\bdi\bi_\b_c\bco\bom\bmm\bma\ban\bnd\bd(\b()\b)
+
+
+  int comedi_command(comedi_t *it, comedi_cmd *cmd);
+
+  undocumented
+
+  Source: /lib/comedi.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b3.\b.  c\bco\bom\bme\bed\bdi\bi_\b_c\bco\bom\bmm\bma\ban\bnd\bd_\b_t\bte\bes\bst\bt(\b()\b)
+
+
+  int comedi_command_test(comedi_t *it, comedi_cmd *cmd);
+
+  undocumented
+
+  Source: /lib/comedi.c
+
+
+
+  6\b6.\b.3\b3.\b.4\b4.\b.  c\bco\bom\bme\bed\bdi\bi_\b_d\bda\bat\bta\ba_\b_r\bre\bea\bad\bd(\b()\b)
+
+
+  int comedi_data_read(comedi_t *it,unsigned int subd,unsigned int chan,
+  unsigned int range,unsigned int aref,lsampl_t *data);
+
+
+  Reads a single sample on the channel that is specified by the comedi
+  device it, the subdevice subd, and the channel chan.  For the A/D
+  conversion (if appropriate), the device is configured to use range
+  specification range and (if appropriate) analog reference type aref.
+  Analog reference types that are not supported by the device are
+  silently ignored.
+
+
+  comedi_data_read() reads one data value from the specified channel and
+  places the data value that is read in the location pointed to by data.
+
+
+  On sucess, comedi_data_read() returns 0.  If there is an error, -1 is
+  returned.
+
+
+  Valid analog reference numbers are:
+
+
+  +\bo  AREF_GROUND     Reference to analog ground
+
+  +\bo  AREF_COMMON     Reference to analog common
+
+  +\bo  AREF_DIFF               Differential reference
+
+  +\bo  AREF_OTHER      Board-specific meaning
+
+  Valid data values returned by these function is an unsigned integer
+  less than or equal to maxdata, which is channel-dependent.  Conversion
+  of these data value to physical units can be performed by
+  ``comedi_to_phys()''.
+
+  Source: /lib/data.c
+
+
+
+  6\b6.\b.3\b3.\b.5\b5.\b.  c\bco\bom\bme\bed\bdi\bi_\b_d\bda\bat\bta\ba_\b_w\bwr\bri\bit\bte\be(\b()\b)
+
+
+  int comedi_data_write(comedi_t *it,unsigned int subd,unsigned int
+  chan, unsigned int range,unsigned int aref,lsampl_t data);
+
+
+  Writes a single sample on the channel that is specified by the comedi
+  device it, the subdevice subd, and the channel chan.  For the D/A
+  conversion (if appropriate), the device is configured to use range
+  specification range and (if appropriate) analog reference type aref.
+  Analog reference types that are not supported by the device are
+  silently ignored.
+
+  comedi_data_write() writes the data value specified by the argument
+  data to the specified channel.
+
+  On sucess, comedi_data_write() returns 0.  If there is an error, -1 is
+  returned.
+
+  Valid analog reference numbers are:
+
+
+  +\bo  AREF_GROUND     Reference to analog ground
+
+  +\bo  AREF_COMMON     Reference to analog common
+
+  +\bo  AREF_DIFF               Differential reference
+
+  +\bo  AREF_OTHER      Board-specific meaning
+
+  Valid data values used by these functions is an unsigned integer less
+  than or equal to maxdata, which is channel-dependent.  Conversion of
+  physical units to these data value can be performed by
+  ``comedi_from_phys()''.
+
+  Source: /lib/data.c
+
+
+
+  6\b6.\b.3\b3.\b.6\b6.\b.  c\bco\bom\bme\bed\bdi\bi_\b_d\bdi\bio\bo_\b_b\bbi\bit\btf\bfi\bie\bel\bld\bd(\b()\b);\b;
+
+  int comedi_dio_bitfield(comedi_t *it,unsigned int subd,unsigned int
+  write_mask,unsigned int *bits);
+
+
+  The function comedi_dio_bitfield() allows multiple channels to be read
+  simultaneously from a digital input or digital I/O device.  The
+  parameter write_mask and the value pointed to by bits are interpreted
+  as bit fields, with the least significant bit representing channel 0.
+  For each bit in write_mask that is set, the cooresponding bit in *bits
+  is written to the digital output channel.  Each digital input channel
+  is read, and the result placed in the approprate bits in *bits.
+
+
+  The current implementation reads and writes bits using separate system
+  calls, which is not ideal.  When the kernel driver supports
+  simultaneous reading/writing, this will be fixed in the library.
+
+
+  It should be noted that it is not possible to access channels greater
+  than 31 using this function.
+
+
+
+  Source: /lib/dio.c
+
+
+
+  6\b6.\b.3\b3.\b.7\b7.\b.  c\bco\bom\bme\bed\bdi\bi_\b_d\bdi\bio\bo_\b_c\bco\bon\bnf\bfi\big\bg(\b()\b)
+
+  int comedi_dio_config(comedi_t *it,unsigned int subd,unsigned int
+  chan,unsigned int dir);
+
+
+  The function comedi_dio_config configures individual channels in a
+  digital I/O subdevice to be either input or output, depending on the
+  value of parameter dir.  Depending on the capabilities of the hardware
+  device, multiple channels may be affected by a single call to
+  comedi_dio_config.
+
+
+  Valid directions are:
+
+  +\bo  COMEDI_INPUT
+
+  +\bo  COMEDI_OUTPUT
+
+  Source: /lib/dio.c
+
+
+
+  6\b6.\b.3\b3.\b.8\b8.\b.  c\bco\bom\bme\bed\bdi\bi_\b_d\bdi\bio\bo_\b_r\bre\bea\bad\bd(\b()\b)
+
+  int comedi_dio_read(comedi_t *it,unsigned int subd,unsigned int
+  chan,unsigned int *bit);
+
+
+  The function reads the status of channel chan belonging to the digital
+  input subdevice subd of device it. The result, 0 or 1, is stored in
+  bit. Returns -1 on failure.
+
+
+  This function is equivalent to comedi_data_read(it,subd,chan,0,0,bit).
+
+
+  Source: /lib/dio.c
+
+
+
+  6\b6.\b.3\b3.\b.9\b9.\b.  c\bco\bom\bme\bed\bdi\bi_\b_d\bdi\bio\bo_\b_w\bwr\bri\bit\bte\be(\b()\b)
+
+  int comedi_dio_write(comedi_t *it,unsigned int subd,unsigned int
+  chan,unsigned int bit);
+
+
+  The function writes the value of bit, 0 or 1, to channel chan,
+  belonging to the digital output device subd of device it. Returns -1
+  on failure.
+
+
+  Source: /lib/dio.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b10\b0.\b.  c\bco\bom\bme\bed\bdi\bi_\b_f\bfi\bil\ble\ben\bno\bo(\b()\b)
+
+
+
+  int comedi_fileno(comedi_t *it);
+
+
+  The function comedi_fileno returns the integer descriptor for the
+  handle it.  It is equivalent to the standard function fileno.  If it
+  is an invalid comedi_t pointer, the function returns -1 and sets the
+  appropriate libcomedi error value.
+
+  Source: /lib/comedi.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b11\b1.\b.  c\bco\bom\bme\bed\bdi\bi_\b_f\bfi\bin\bnd\bd_\b_r\bra\ban\bng\bge\be(\b()\b)
+
+
+  int comedi_find_range(comedi_t *it, unsigned int subdevice, unsigned
+  int chan, unsigned int unit, double min, double max);
+
+
+  The function comedi_find_range tries to locate the optimal (smallest)
+  range for the channel chan belonging to a subdevice of the comedi
+  device it, that includes both min and max in units.  If it finds a
+  matching range, it returns its index.  If no matching range is
+  available, it returns -1.
+
+
+  Valid units are:
+
+
+  +\bo  UNIT_volt
+
+  +\bo  UNIT_mA
+
+  +\bo  UNIT_none
+
+  Source: /lib/range.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b12\b2.\b.  c\bco\bom\bme\bed\bdi\bi_\b_e\ber\brr\brn\bno\bo(\b()\b)
+
+  int comedi_errno(void);
+
+
+  The function comedi_errno() returns an integer describing the most
+  recent comedilib error.  This integer may be used as the errnum
+  parameter for ``comedi_strerror()''.
+
+  When a libcomedi function fails, it usually returns -1 or NULL,
+  depending on the return type.  An internal library variable stores an
+  error number, which can be retrieved with comedi_errno().  This error
+  number can be converted to a human-readable form by the functions
+  ``comedi_perror()'' and ``comedi_strerror()''.
+
+  These functions are intended to mimic the behavior of the standard C
+  library functions perror(), strerror, and errno().  In particular,
+  libcomedi functions sometimes return an error that is generated by the
+  C library; the Comedi error message in this case is the same as the C
+  library.
+
+  Source: /lib/error.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b13\b3.\b.  c\bco\bom\bme\bed\bdi\bi_\b_f\bfi\bin\bnd\bd_\b_s\bsu\bub\bbd\bde\bev\bvi\bic\bce\be_\b_b\bby\by_\b_t\bty\byp\bpe\be(\b()\b)
+
+
+  int comedi_find_subdevice_by_type(comedi_t *it,int type,unsigned int
+  start_subdevice);
+
+
+  The function comedi_find_subdevice_by_type tries to locate a subdevice
+  belonging to comedi device it, having type type, starting with the
+  subdevice start_subdevice.  If it finds the requested subdevice, it
+  returns its index.  If it does not locate the requested subdevice, it
+  returns -1 and sets the comedi error number to "subdevice not found".
+  If there is an error, the function returns -1 and sets the appropriate
+  error.
+
+
+  For subdevice types, see the manual page for the function
+  ``comedi_get_subdevice_type()''.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b14\b4.\b.  c\bco\bom\bme\bed\bdi\bi_\b_f\bfr\bro\bom\bm_\b_p\bph\bhy\bys\bs(\b()\b)
+
+
+  lsampl_t comedi_from_phys(double data, comedi_range *rng, lsampl_t
+  maxdata);
+
+  Converts data given in physical units (data) into sample values
+  (lsampl_t, between 0 and maxdata).  The parameter rng represents the
+  conversion information to use, and the parameter maxdata represents
+  the maximum possible data value for the channel that the data will be
+  written to.
+
+
+  Source: /lib/range.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b15\b5.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_b\bbo\boa\bar\brd\bd_\b_n\bna\bam\bme\be(\b()\b)
+
+
+  char *comedi_get_board_name(comedi_t *it);
+
+  The function comedi_get_board_name returns a pointer to a string
+  containing the name of the device.  This pointer is valid until the
+  comedi descriptor it is closed.  This function returns NULL if there
+  is an error.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b16\b6.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_c\bcm\bmd\bd_\b_s\bsr\brc\bc_\b_m\bma\bas\bsk\bk(\b()\b)
+
+
+  int comedi_get_cmd_src_mask(comedi_t *dev, unsigned int subdevice,
+  comedi_cmd *cmd);
+
+  undocumented
+
+  Source: /lib/cmd.c
+
+  6\b6.\b.3\b3.\b.1\b17\b7.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_d\bdr\bri\biv\bve\ber\br_\b_n\bna\bam\bme\be(\b()\b)
+
+
+  char *comedi_get_driver_name(comedi_t *it);
+
+  The function comedi_get_driver_name returns a pointer to a string
+  containing the name of the driver being used by comedi for the comedi
+  device represented by it.  This pointer is valid until the comedi
+  descriptor it is closed.  This function returns NULL if there is an
+  error.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b18\b8.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_m\bma\bax\bxd\bda\bat\bta\ba(\b()\b)
+
+
+  lsampl_t comedi_get_maxdata(comedi_t *it,unsigned int
+  subdevice,unsigned int chan);
+
+
+  The function comedi_get_maxdata() returns the maximum valid data value
+  for channel chan of subdevice subdevice belonging to the comedi device
+  it This function returns 0 on error.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.1\b19\b9.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_n\bn_\b_c\bch\bha\ban\bnn\bne\bel\bls\bs(\b()\b)
+
+
+  int comedi_get_n_channels(comedi_t *it,unsigned int subdevice);
+
+  The function comedi_get_n_channels() returns the number of channels of
+  the subdevice belonging to the comedi device it and having index
+  subdevice.  This function returns -1 on error.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b20\b0.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_n\bn_\b_r\bra\ban\bng\bge\bes\bs(\b()\b)
+
+
+  int comedi_get_n_ranges(comedi_t *it,unsigned int subdevice, unsigned
+  int chan);
+
+  The function comedi_get_n_ranges() returns the number of ranges of the
+  channel chan belonging to the subdevice of the comedi device it.  This
+  function returns -1 on error.
+
+  Source: /lib/range.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b21\b1.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_n\bn_\b_s\bsu\bub\bbd\bde\bev\bvi\bic\bce\bes\bs(\b()\b)
+
+
+  int comedi_get_n_subdevices(comedi_t *it);
+
+  The function comedi_get_n_subdevices returns the number of subdevices
+  associated with the comedi descriptor it, or -1 if there is an error.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b22\b2.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_r\bra\ban\bng\bge\be(\b()\b)
+
+
+  comedi_range * comedi_get_range(comedi_t *it,unsigned int
+  subdevice,unsigned int chan,unsigned int range);
+
+  The function comedi_get_range returns a pointer to a comedi_range
+  structure that contains information that can be used to convert sample
+  values to or from physical units.  The pointer is valid until the
+  comedi device it is closed.  If there is an error, NULL is returned.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b23\b3.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_r\bra\ban\bng\bge\bet\bty\byp\bpe\be(\b()\b)  d\bde\bep\bpr\bre\bec\bca\bat\bte\bed\bd
+
+
+  int comedi_get_rangetype(comedi_t *it,unsigned int subdevice,unsigned
+  int chan);
+
+  The function comedi_get_rangetype() returns an integer that represents
+  the number of range specifications available for a particular channel
+  chan of the subdevice subdevice, as well as a conversion table to
+  convert sample values to/from physical units.
+
+  The macro RANGE_LENGTH(rangetype) can be used to determine the number
+  of range specifications for a given range type.
+
+
+  This function is deprecated and should not be used in new code.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b24\b4.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_s\bsu\bub\bbd\bde\bev\bvi\bic\bce\be_\b_t\bty\byp\bpe\be(\b()\b)
+
+
+  int comedi_get_subdevice_type(comedi_t *it,unsigned int subdevice);
+
+  The function comedi_get_subdevice_type() returns an integer describing
+  the type of subdevice that belongs to the comedi device it and has the
+  index subdevice.  The function returns -1 is there is an error.
+
+  Valid subdevice types are:
+
+
+  +\bo  COMEDI_SUBD_UNUSED Subdevice has no functionality, i.e., a place-
+     holder.
+
+  +\bo  COMEDI_SUBD_AI    Analog input
+
+  +\bo  COMEDI_SUBD_AO    Analog output
+
+  +\bo  COMEDI_SUBD_DI    Digital input
+
+
+  +\bo  COMEDI_SUBD_DO    Digital output
+
+  +\bo  COMEDI_SUBD_DIO Digital input/output.  Channels are configurable as
+     to whether they are inputs or outputs.
+
+  +\bo  COMEDI_SUBD_COUNTER       Counter
+
+  +\bo  COMEDI_SUBD_TIMER Timer
+
+  +\bo  COMEDI_SUBD_MEMORY Memory, e.g., EEPROM or dual-ported RAM
+
+  +\bo  COMEDI_SUBD_CALIB Calibration DACs
+
+  +\bo  COMEDI_SUBD_PROC Processor or DSP
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b25\b5.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_t\bti\bim\bme\ber\br(\b()\b) (\b(d\bde\bep\bpr\bre\bec\bca\bat\bte\bed\bd)\b)
+
+
+  int comedi_get_timer(comedi_t *it,unsigned int subdev, double
+  freq,unsigned int *trigvar, double *actual_freq);
+
+
+  The function comedi_get_timer converts the frequency freq to a number
+  suitable to send to the driver in a comedi_trig structure.  This
+  function remains for compatibility with very old versions of Comedi,
+  that converted sampling rates to timer values in the libary.  This
+  conversion is now done in the kernel, and every device has the timer
+  type nanosec_timer, indicating that timer values are simply a time
+  specified in nanoseconds.
+
+
+  This function is deprecated and should not be used in new
+  applications.
+
+
+  Source: /lib/timer.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b26\b6.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_v\bve\ber\brs\bsi\bio\bon\bn_\b_c\bco\bod\bde\be(\b()\b)
+
+
+  int comedi_get_version_code(comedi_t *it);
+
+
+  The function comedi_get_version_code() returns the version code of the
+  currently running comedi module.  The version code is of the form
+  0x01072b, which is the version code for version 1.7.43.
+
+
+  This function is of limited usefulness.  A typical mis-application of
+  this function is to use it to determine if a certain feature is
+  supported.  If the application needs to know of the existence of a
+  particular feature, an existence test function should be written and
+  put in the libcomedi source.
+
+  Source: /lib/get.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b27\b7.\b.  c\bco\bom\bme\bed\bdi\bi_\b_l\blo\bog\bgl\ble\bev\bve\bel\bl(\b()\b)
+
+
+  int comedi_loglevel(int loglevel);
+
+
+  This function affects the output of debugging and error messages from
+  libcomedi.  By increasing the loglevel, additional debugging
+  information will be printed.  This function returns the previous
+  loglevel.  Error messages and debugging are printed to the stream
+  stderr.  The loglevel can also be affected by the environment variable
+  COMEDI_LOGLEVEL.
+
+
+  In order to conserve resources, some debugging information is disabled
+  when libcomedi is compiled.
+
+
+  The meaning of the loglevels is as follows:
+
+
+  +\bo  COMEDILIB_LOGLEVEL=0
+
+     Comedilib prints nothing.
+
+  +\bo  COMEDILIB_LOGLEVEL=1  (default)
+
+     Comedilib only prints error messages when there is a self-
+     consistency error (i.e., internal bug).
+
+  +\bo  COMEDILIB_LOGLEVEL=2
+
+     Comedilib prints an error message when an invalid parameter is
+     passed to comedilib.
+
+  +\bo  COMEDILIB_LOGLEVEL=3
+
+     Comedilib prints an error message whenever an error is generated in
+     the comedilib library or is generated in the C library when called
+     by comedilib.
+
+  +\bo  COMEDILIB_LOGLEVEL=4
+
+     Comedilib prints a lot of debugging messages.
+
+  Bugs: Libcomedi doesn't currently have much debugging information.
+
+  Source: /lib/error.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b28\b8.\b.  c\bco\bom\bme\bed\bdi\bi_\b_o\bop\bpe\ben\bn(\b()\b)
+
+
+  comedi_t *comedi_open(char *filename);
+
+  Opens a comedi device specified by the filename filename.  Returns
+  NULL on error.  On sucess, it returns a handle that is given as a
+  parameter to other libcomedi functions.
+
+
+  You are not supposed to have access to the internals of the comedi_t
+  structure.
+
+  Bugs: Not strictly identical to fopen
+
+  Source: /lib/comedi.c
+
+
+
+  6\b6.\b.3\b3.\b.2\b29\b9.\b.  c\bco\bom\bme\bed\bdi\bi_\b_p\bpe\ber\brr\bro\bor\br(\b()\b)
+
+
+  void comedi_perror(const char *s);
+
+  When a comedilib function fails, it usually returns -1 or NULL,
+  depending on the return type.  An internal library variable stores an
+  error number, which can be retrieved with ``comedi_errno()''.  This
+  error number can be converted to a human-readable form by the
+  functions comedi_perror() and ``comedi_strerror()''.
+
+  These functions are intended to mimic the behavior of the standard C
+  library functions perror(), strerror, and errno().  In particular,
+  comedilib functions sometimes return an error that is generated inside
+  the C library; the comedi error message in this case is the same as
+  the C library.
+
+  The function comedi_perror() prints an error message to stderr.  The
+  error message consists of the argument string, a colon, a space, a
+  description of the error condition, and a new line.
+
+  Bugs: Does not support internationalization.
+
+  Source: /lib/error.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b30\b0.\b.  c\bco\bom\bme\bed\bdi\bi_\b_s\bst\btr\bre\ber\brr\bro\bor\br(\b()\b)
+
+
+  *comedi_strerror(int errnum);
+
+  When a comedilib function fails, it usually returns -1 or NULL,
+  depending on the return type.  An internal library variable stores an
+  error number, which can be retrieved with ``comedi_errno()''.  This
+  error number can be converted to a human-readable form by the
+  functions ``comedi_perror()'' and comedi_strerror().
+
+  These functions are intended to mimic the behavior of the standard C
+  library functions perror(), strerror, and errno().  In particular,
+  comedilib functions sometimes return an error that is generated inside
+  the C library; the comedi error message in this case is the same as
+  the C library.
+
+  The function comedi_strerror() returns a pointer to a character string
+  describing the comedilib error errnum.  The persistence of the
+  returned pointer is undefined, and should not be trusted after the
+  next libcomedi call.  An unrecognized error number will return a
+  pointer to the string "undefined error", or similar.
+
+  Bugs: Does not support internationalization.
+
+  Source: /lib/error.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b31\b1.\b.  c\bco\bom\bme\bed\bdi\bi_\b_s\bsv\bv_\b_i\bin\bni\bit\bt(\b()\b)
+
+
+  int comedi_sv_init(comedi_sv_t *sv,comedi_t *dev,unsigned int subd,
+  unsigned int chan);
+
+
+  comedi_sv_init initializes the slow varying comedi structure sv of the
+  device dev, the subdevice subd (analog input) and the channel chan.
+  The slow varying comedi structure sv of type ``comedi_sv_t'' specifies
+  the signal measurement.  The default number of averaged samples is
+  100.  Returns zero on success, -1 on error.
+
+  Bugs: comedi_sv_* was very poorly designed.
+
+  Source: /lib/sv.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b32\b2.\b.  c\bco\bom\bme\bed\bdi\bi_\b_s\bsv\bv_\b_u\bup\bpd\bda\bat\bte\be(\b()\b)
+
+
+  int comedi_sv_update(comedi_sv_t *sv);
+
+  The function comedi_sv_update updates the slow varying comedi
+  structure sv.  Returns zero on success, -1 on error.
+
+  Source: /lib/sv.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b33\b3.\b.  i\bin\bnt\bt c\bco\bom\bme\bed\bdi\bi_\b_s\bsv\bv_\b_m\bme\bea\bas\bsu\bur\bre\be(\b()\b)
+
+
+  int comedi_sv_measure(comedi_sv_t *it,double *data);
+
+  comedi_sv_measure measures the slow variing signal. The measurement is
+  specified by the slow varying comedi structure sv, the result is
+  stored in data.  On success returns the number of samples, -1 on
+  error.
+
+  Source: /lib/sv.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b34\b4.\b.  c\bco\bom\bme\bed\bdi\bi_\b_t\bto\bo_\b_p\bph\bhy\bys\bs(\b()\b)
+
+
+  double comedi_to_phys(lsampl_t data, comedi_range *rng, lsampl_t
+  maxdata);
+
+  Converts data given in sample values (lsampl_t, between 0 and maxdata)
+  into physical units (double).  The parameter rng represents the
+  conversion information to use, and the parameter maxdata represents
+  the maximum possible data value for the channel that the data was
+  read.
+
+  Source: /lib/range.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b35\b5.\b.  c\bco\bom\bme\bed\bdi\bi_\b_t\btr\bri\big\bgg\bge\ber\br(\b()\b) (\b(d\bde\bep\bpr\bre\bec\bca\bat\bte\bed\bd)\b)
+
+
+  int comedi_trigger(comedi_t *it,comedi_trig *trig);
+
+  The function comedi_trigger instructs comedi to perform the command
+  specified by the ``trigger structure'' trig.  Results depend on the
+  particular command being issued.  If there is an error, -1 is
+  returned.
+
+  Lifetime: removal at 1.0.
+
+  Source: /lib/comedi.c
+
+
+
+  6\b6.\b.3\b3.\b.3\b36\b6.\b.  c\bco\bom\bme\bed\bdi\bi_\b_g\bge\bet\bt_\b_s\bsu\bub\bbd\bde\bev\bvi\bic\bce\be_\b_f\bfl\bla\bag\bgs\bs(\b()\b)
+
+
+  int comedi_get_subdevice_flags(comedi_t *dev, unsigned int subdevice);
+
+
+  This function returns a bitfield describing the capabilities of the
+  specified subdevice.  If there is an error, -1 is returned.
+
+
+  The bits are:
+
+
+  +\bo  SDF_BUSY                subdevice is running a command
+
+  +\bo  SDF_BUSY_OWNER  subdevice is running a command started by the file
+     descriptor used by dev.
+
+  +\bo  SDF_LOCKED      subdevice is locked
+
+  +\bo  SDF_LOCKED_OWNER        subdevice is locked by the file descriptor
+     used by dev.
+
+  +\bo  SDF_MAXDATA     maximum data values are channel dependent
+
+  +\bo  SDF_FLAGS               channel flags are channel dependent
+
+  +\bo  SDF_RANGETYPE   range types are channel dependent
+
+  +\bo  SDF_MODE0               deprecated
+
+  +\bo  SDF_MODE1               deprecated
+
+  +\bo  SDF_MODE2               deprecated
+
+  +\bo  SDF_MODE3               deprecated
+
+  +\bo  SDF_MODE4               deprecated
+
+  +\bo  SDF_CMD         subdevice supports commands
+
+  +\bo  SDF_READABLE    subdevice can be read from
+
+  +\bo  SDF_WRITEABLE   subdevice can be written to
+
+  +\bo  SDF_RT          deprecated
+
+  +\bo  SDF_GROUND      subdevice is capable of ground analog reference
+
+  +\bo  SDF_COMMON      subdevice is capable of common analog reference
+
+  +\bo  SDF_DIFF                subdevice is capable of differential analog
+     reference
+
+  +\bo  SDF_OTHER               subdevice is capable of other analog
+     reference
+
+  +\bo  SDF_DITHER      subdevice recognizes dither flag
+
+  +\bo  SDF_DEGLITCH    subdevice recognizes deglitch flag
+
+  +\bo  SDF_MMAP                deprecated
+
+  +\bo  SDF_RUNNING     subdevice is acquiring data (i.e., command has not
+     completed)
+
+  +\bo  SDF_LSAMPL      subdevice uses samples of type lsampl_t (otherwise
+     sampl_t)
+
+  +\bo  SDF_PACKED      subdevice uses bitfield samples (otherwise it uses
+     one sample per channel)
+
+
+
+  The bit definitions are part of the Comedi kernel interface.
+
+
+
+  6\b6.\b.3\b3.\b.3\b37\b7.\b.  c\bco\bom\bme\bed\bdi\bi_\b_r\bra\ban\bng\bge\be_\b_i\bis\bs_\b_c\bch\bha\ban\bn_\b_s\bsp\bpe\bec\bci\bif\bfi\bic\bc(\b()\b)
+
+
+  int comedi_range_is_chan_specific(comedi_t *dev,unsigned int
+  subdevice);
+
+
+  If each channel of the specified subdevice has a different range
+  specification, this function returns 1.  Otherwise, this function
+  returns 0.  On error, this function returns -1.
+
+
+
+  6\b6.\b.3\b3.\b.3\b38\b8.\b.  U\bUn\bnd\bdo\boc\bcu\bum\bme\ben\bnt\bte\bed\bd f\bfu\bun\bnc\bct\bti\bio\bon\bns\bs
+
+
+
+  +\bo  comedi_maxdata_is_chan_specific()
+
+  +\bo  comedi_get_buffer_size()
+
+  +\bo  comedi_get_max_buffer_size()
+
+  +\bo  comedi_set_buffer_size()
+
+  +\bo  comedi_set_max_buffer_size()
+
+  +\bo  comedi_do_insnlist()
+
+  +\bo  comedi_do_insn()
+
+  +\bo  comedi_lock()
+
+  +\bo  comedi_unlock()
+
+  +\bo  comedi_get_cmd_src_mask()
+
+  +\bo  comedi_get_cmd_generic_timed()
+
+  +\bo  comedi_cancel()
+
+  +\bo  comedi_command()
+
+  +\bo  comedi_command_test()
+
+  +\bo  comedi_poll()
+
+  +\bo  comedi_get_buffer_contents()
+
+  +\bo  comedi_mark_buffer_read()
+
+  +\bo  comedi_get_buffer_offset()
+
+  +\bo  comedi_set_global_oor_behavior()
+
+
+