From: Frank Mori Hess Date: Wed, 9 Jul 2003 02:46:39 +0000 (+0000) Subject: undoing regression X-Git-Tag: r0_7_21~52 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d7fc976d8b226961dff315af3e14b2d75533a687;p=comedilib.git undoing regression --- diff --git a/doc/advanced.sgml b/doc/advanced.sgml deleted file mode 100644 index d5f6303..0000000 --- a/doc/advanced.sgml +++ /dev/null @@ -1,672 +0,0 @@ -

-Configuring comedi for your hardware -

- - -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: - - -I/O base -IRQ -1=differential, 0=single ended -ai 0=unipolar, 1=bipolar -ao0 0=unipolar, 1=bipolar -ao1 0=unipolar, 1=bipolar -dma1 -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. - - -

-Getting information from comedi -

- - -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. - - - - - - - - -Writing programs that use comedi and comedilib -

- -Your first comedi program -

- -This example requires a card that has analog or -digital input. Right to the source: - - -#include /* for printf() */ -#include - -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,&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. - - -

-Converting samples to voltages -

- -If you selected an analog input subdevice, you probably noticed -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 always 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 - -

- -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 -'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 - - -volts=comedi_to_phys(it,data,range,maxdata); - - -and the opposite - - -data=comedi_from_phys(it,volts,range,maxdata); - - - -

-Another section -

- - -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. - - - -Your second comedi program -

- - -Actually, this is the first comedi program again, just -that we've added what we've learned. - - - -#include /* for printf() */ -#include /* also included by comedilib.h */ -#include /* '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,&data); - - volts=comedi_to_phys(data,rangetype,range,maxdata); - - printf("%d %g\n",data,volts); - - return 0; -} - - - - - - - -

-Application-specific functions -

- -Digital Input/Output -

- -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 - - -Slowly-varying inputs -

- - -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: - -

- - -you are ultimately limited by "spurious free dynamic range" - - -you need to have _some_ noise on the input channel, -otherwise you will be averaging the same number N times. - - -the more noise you have, the greater your SFDR, but it -takes many more samples to compensate for the increased -noise - - -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. - - -

-Commands -

- - -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 structure is -used to control acquisition and query the capabilities of a device -(see also , -, and -). - -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 structure. The source types are: - - -TRIG_NONE: don't ever cause an event -TRIG_NOW: cause event to occur immediately -TRIG_FOLLOW: see notes below -TRIG_TIME: cause event to occur at a particular time -TRIG_TIMER: cause event to occur repeatedly at a specific rate -TRIG_COUNT: cause event when count reaches specific value -TRIG_EXT: external signal causes event -TRIG_INT: internal signal causes event -TRIG_OTHER: driver-specific meaning - - -Not all triggers are applicable to all events. Supported triggers -for specific events depend significantly on your particular -device. The -function is useful for determining what triggers a subdevice supports. - -For every trigger, there is a corresponding -argument (the -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 -structure is the index of the subdevice the command is intended for. The - -function can be useful in discovering the index of your desired subdevice. - -The -structure should point to an array whose number of elements is specificed by macro. - -The structure is -TRIG_BOGUS: do the motions?? -TRIG_DITHER: enable dithering?? -TRIG_DEGLITCH: enable deglitching?? -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. -TRIG_CONFIG: perform configuration, not triggering. This is a legacy of the -deprecated comedi_trig_struct, and has no function at present. -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. -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. - -TRIG_ROUND_NEAREST: round to nearest supported timing period, the default. -TRIG_ROUND_DOWN: round period down. -TRIG_ROUND_UP: round period up. -TRIG_ROUND_UP_NEXT: this one doesn't do anything, and I don't know what it was intended -to do?? - - -

- -The typical sequence for executing a command is to first send -the command through - -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 -. For input/output commands, data -is read from or written to the device file /dev/comedi[0..3] you are using. -