undoing regression
authorFrank Mori Hess <fmhess@speakeasy.net>
Wed, 9 Jul 2003 02:46:39 +0000 (02:46 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Wed, 9 Jul 2003 02:46:39 +0000 (02:46 +0000)
doc/advanced.sgml [deleted file]

diff --git a/doc/advanced.sgml b/doc/advanced.sgml
deleted file mode 100644 (file)
index d5f6303..0000000
+++ /dev/null
@@ -1,672 +0,0 @@
-<p>
-<sect1>Configuring comedi for your hardware
-<p>
-
-
-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 <tt>comedi_config</tt>
-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:
-
-
-<tscreen><verb>
-# 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)
-))
-</verb></tscreen>
-
-
-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
-
-<tscreen><verb>
-/usr/sbin/comedi_config /dev/comedi0 atmio-E 0x260,3
-</verb></tscreen>
-
-into <tt>/etc/rc.d/rc.local</tt>.  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:
-
-<itemize>
-<item>I/O base
-<item>IRQ
-<item>1=differential, 0=single ended
-<item>ai 0=unipolar, 1=bipolar
-<item>ao0 0=unipolar, 1=bipolar
-<item>ao1 0=unipolar, 1=bipolar
-<item>dma1
-<item>dma2
-</itemize>
-
-(ai=analog input, ao=analog output.)  From this, I decide that
-the appropriate options list is
-
-<tscreen><verb>
-0x200,4,,1,1,1
-</verb></tscreen>
-
-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.
-
-<tscreen><verb>
-/usr/sbin/comedi_config /dev/comedi1 dt2821-f-8di 0x200,4,,1,1,1
-</verb></tscreen>
-
-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):
-
-<tscreen><verb>
-comedi0: ni_E: 0x0200 can't find board
-</verb></tscreen>
-
-When it does work, I get:
-
-<tscreen><verb>
-comedi0: ni_E: 0x0260 at-mio-16e-10 ( irq = 3 )
-</verb></tscreen>
-
-Note that it also correctly identified my board.
-
-
-<p>
-<sect1>Getting information from comedi
-<p>
-
-
-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:
-
-<p>
-
-<tscreen><verb>
-cat /proc/comedi
-</verb></tscreen>
-
-Right now, on my computer, this command gives:
-
-<tscreen><verb>
-comedi version 0.6.4
-format string
- 0: atmio-E              at-mio-16e-10           7
- 1: dt282x               dt2821-f-8di            4
-</verb></tscreen>
-
-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 <tt>demo/</tt> directory, there is a command called
-<tt>info</tt>, 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 <tt>/dev/comedi0</tt>.)  ('demo/info /dev/comedi0')
-
-<tscreen><verb>
-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
-</verb>
-...
-</tscreen>
-
-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.
-
-
-
-
-
-
-
-
-<sect>Writing programs that use comedi and comedilib
-<p>
-
-<sect1>Your first comedi program
-<p>
-
-This example requires a card that has analog or
-digital input.  Right to the source:
-
-<tscreen><verb>
-#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;
-       lsampl_t data;
-
-       it=comedi_open("/dev/comedi0");
-       
-       comedi_data_read(it,subdev,chan,range,aref,&amp;data);
-       
-       printf("%d\n",data);
-       
-       return 0;
-}
-</verb></tscreen>
-
-
-Should be understandable: open the device, get the data,
-print it out.  This is basically the guts of <tt>demo/inp.c</tt>,
-without error checking or fancy options.
-Compile it using
-
-<tscreen><verb>
-cc tut1.c -lcomedi -o tut1
-</verb></tscreen>
-
-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.
-
-
-<p>
-<sect1>Converting samples to voltages
-<p>
-
-If you selected an analog input subdevice, you probably noticed
-that the output of <tt>tut1</tt> 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 <bf>always</bf> 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"
-for 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
-
-<p>
-<tscreen><verb>
-typedef struct{
-        double min;
-        double max;
-        unsigned int unit;
-}comedi_range;
-</verb></tscreen>
-
-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
-'unit' entry tells you if min and
-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
-
-<tscreen><verb>
-volts=comedi_to_phys(it,data,range,maxdata);
-</verb></tscreen>
-
-and the opposite
-
-<tscreen><verb>
-data=comedi_from_phys(it,volts,range,maxdata);
-</verb></tscreen>
-
-
-<p>
-<sect1>Another section
-<p>
-
-
-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():
-
-<p>
-<tscreen><verb>
-file=comedi_open("/dev/comedi0");
-</verb></tscreen>
-
-where file is of type <tt>(comedi_t *)</tt>.  This function
-calls <tt>open()</tt>, like we did explicitly in a previous
-section, but also fills the <tt>comedi_t</tt> 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:
-
-<tscreen><verb>
-maxdata=comedi_get_maxdata(file,subdevice,channel);
-</verb></tscreen>
-
-Wow.  How easy.  And the range type?
-
-<tscreen><verb>
-range_type=comedi_get_rangetype(file,subdevice,channel);
-</verb></tscreen>
-
-Cool.  Other information you need to know about a channel
-can be gotten in a similar way.
-
-
-
-<sect1>Your second comedi program
-<p>
-
-
-Actually, this is the first comedi program again, just
-that we've added what we've learned.
-
-
-<tscreen><verb>
-#include <stdio.h>      /* for printf() */
-#include <comedi.h>     /* also included by comedilib.h */
-#include <comedilib.h>  /* 'cuz we're using comedilib */
-
-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,&amp;data);
-
-       volts=comedi_to_phys(data,rangetype,range,maxdata);
-
-        printf("%d %g\n",data,volts);
-
-        return 0;
-}
-</verb></tscreen>
-
-
-
-
-
-
-<p>
-<sect>Application-specific functions
-<p>
-
-<sect1>Digital Input/Output
-<p>
-
-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
-
-  <tt/comedi_dio_read(device,subdevice,channel,unsigned int *bit);/
-  <tt/comedi_dio_write(device,subdevice,channel,unsigned int bit);/
-
-The direction of bidirectional lines can be configured using
-the function
-
-  <tt/comedi_dio_config(device,subdevice,channel,unsigned int dir);/
-
-The parameter <tt/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
-
-  <tt/comedi_dio_bitfield(device,subdevice,unsigned int write_mask,unsigned int *bits);/
-
-Each channel is assigned to a bit in the <tt/write_mask/ and <tt/bits/
-bitfield.  If a bit in <tt/write_mask/ is set, the corresponding bit
-in <tt/*bits/ will be written to the corresponding digital output line.
-Each digital line is then read and placed into <tt/*bits/.  The value
-of bits in <tt/*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.
-
-
-<p>
-<sect1>Slowly-varying inputs
-<p>
-
-
-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:
-
-<p>
-<itemize>
-<item>
-you are ultimately limited by "spurious free dynamic range"
-
-<item>
-you need to have _some_ noise on the input channel,
-otherwise you will be averaging the same number N times.
-
-<item>
-the more noise you have, the greater your SFDR, but it
-takes many more samples to compensate for the increased
-noise
-
-<item>
-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.
-
-</itemize>
-
-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.
-
-
-<p>
-<sect1>Commands
-<label id="command_section">
-<p>
-
-
-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 <ref id="comedi_cmd" name="comedi_cmd"> structure is
-used to control acquisition and query the capabilities of a device
-(see also <ref id="comedi_command" name="comedi_command()">,
-<ref id="comedi_command_test" name="comedi_command_test()">, and
-<ref id="comedi_get_cmd_src_mask" name="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 <tt/*_src/ members of the
-<ref id="comedi_cmd" name="comedi_cmd"> structure.  The source types are:
-
-<itemize>
-<item>TRIG_NONE:       don't ever cause an event
-<item>TRIG_NOW:        cause event to occur immediately
-<item>TRIG_FOLLOW:     see notes below
-<item>TRIG_TIME:       cause event to occur at a particular time
-<item>TRIG_TIMER:      cause event to occur repeatedly at a specific rate
-<item>TRIG_COUNT:      cause event when count reaches specific value
-<item>TRIG_EXT:        external signal causes event
-<item>TRIG_INT:        internal signal causes event
-<item>TRIG_OTHER:      driver-specific meaning
-</itemize>
-
-Not all triggers are applicable to all events.  Supported triggers
-for specific events depend significantly on your particular
-device.  The <ref id="comedi_get_cmd_src_mask" name="comedi_get_cmd_src_mask()">
-function is useful for determining what triggers a subdevice supports.
-
-For every trigger, there is a corresponding
-argument (the <tt/*_arg/ members of the <ref id="comedi_cmd" name="comedi_cmd">
-structure) whose meaning depends on the type of trigger.  The meanings
-of the arguments are as follows:
-
-TRIG_NONE is typically used only as a <tt/stop_src/.  The argument for TRIG_NONE
-is reserved and should be set to 0.
-
-TRIG_NOW is most often used as a <tt/start_src/.  The argument for TRIG_NOW is
-the number of nanoseconds between when the command is issued and when
-the event should occur.  In the case of using TRIG now as a <tt/start_src/,
-it indicates a delay between issuing the command and the start of
-acquisition.  Most drivers only support a delay of 0.
-
-TRIG_FOLLOW is a special type of trigger for events that trigger on
-the completion of some other, logically connected event.  The argument
-is reserved and should be set to 0.  When used
-as a <tt/scan_begin_src/, it indicates that a trigger should occur as a
-logical continuation of convert events.  This is done in order to
-properly describe boards that do not have separate timers for
-convert and scan_begin events.  When used as a <tt/start_src/ for analog
-output subdevices, it indicates that conversion of output samples
-should begin when samples are written to the buffer.
-
-TRIG_TIME is reserved for future use.
-
-TRIG_TIMER is most often used as a <tt/convert_src/, a <tt/scan_begin_src/, or
-both.  It indicates that triggers should occur at a specific rate.
-The argument specifies the interval between triggers in nanoseconds.
-
-TRIG_COUNT is used for <tt/scan_end_src/ and <tt/stop_src/.  It indicates that
-a trigger should occur when the specified number of corresponding
-lower-level triggers (convert and scan_begin, respectively) occur.
-The argument is the count of lower-level triggers.
-
-TRIG_EXT can be useful as any of the trigger sources.  It indicates
-that an external digital line should be used to trigger the event.
-The exact meaning of digital line is device-dependent.  Some devices
-have one dedicated line, others may allow generic digital input
-lines to be used.  The argument indicates the particular external
-line to use as the trigger.
-
-TRIG_INT is typically used as a <tt/start_src/.  This trigger occurs when
-the application performs an INSN_INTTRIG instruction.  Using TRIG_INT
-is a method by which the application can accurately record the time of
-the start of acquisition, since the parsing and setup time of a
-particular command may be significant.  The argument associated with
-TRIG_INT is reserved and should be set to 0.
-
-TRIG_OTHER can be useful as any of the trigger sources.  The exact
-meaning of TRIG_OTHER is driver-specific, and implements a feature
-that otherwise does not fit into the command interface.  Configuration
-of TRIG_OTHER features are done by INSN_CONFIG insns.  The argument
-is reserved and should be set to 0.
-
-Ths <tt/subdev/ member of the <ref id="comedi_cmd" name="comedi_cmd">
-structure is the index of the subdevice the command is intended for.  The
-<ref id="comedi_find_subdevice_by_type" name="comedi_find_subdevice_by_type()">
-function can be useful in discovering the index of your desired subdevice.
-
-The <tt/chanlist/ member of the <ref id="comedi_cmd" name="comedi_cmd">
-structure should point to an array whose number of elements is specificed by <tt/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 <ref id="CR_PACK" name="CR_PACK()"> macro.
-
-The <tt/data/ and <tt/data_len/ members can be safely ignored when issueing commands
-from a user-space program.  They only have meaning when a command is sent from a kernel
-module using the kcomedilib interface, in which case they specify the buffer where
-the driver should write/read its data to/from.
-
-The final member of the <ref id="comedi_cmd" name="comedi_cmd"> structure is <tt/flags/.
-The following flags are valid, and can be bitwise-or'd together.
-
-<itemize>
-<item>TRIG_BOGUS:      do the motions??
-<item>TRIG_DITHER:     enable dithering??
-<item>TRIG_DEGLITCH:   enable deglitching??
-<item>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.
-<item>TRIG_CONFIG:     perform configuration, not triggering.  This is a legacy of the
-deprecated comedi_trig_struct, and has no function at present.
-<item>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 high frequencies.
-<item>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.
-</itemize>
-There are also a few flags that indicate how timing arguments should be rounded
-if the hardware cannot achieve the exact timing requested.
-<itemize>
-<item>TRIG_ROUND_NEAREST: round to nearest supported timing period, the default.
-<item>TRIG_ROUND_DOWN: round period down.
-<item>TRIG_ROUND_UP: round period up.
-<item>TRIG_ROUND_UP_NEXT: this one doesn't do anything, and I don't know what it was intended
-to do??
-</itemize>
-
-<p>
-
-The typical sequence for executing a command is to first send
-the command through
-<ref id="comedi_command_test" name="comedi_command_test()">
-once or twice.  The test will check that the command is valid for the particular
-device, and often makes some adjustments to the command arguments, which
-can then be read back by the user to see the actual values used.  The
-command is executed with
-<ref id="comedi_command" name="comedi_command()">.  For input/output commands, data
-is read from or written to the device file /dev/comedi[0..3] you are using.
-