From: David Schleef Date: Tue, 10 Jul 2001 22:25:26 +0000 (+0000) Subject: A text version, for all the crazies X-Git-Tag: r0_7_16~39 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=915c97e04202d898efd4cd0fa343367b2f01fa6d;p=comedilib.git A text version, for all the crazies --- diff --git a/doc/comedilib.txt b/doc/comedilib.txt new file mode 100644 index 0000000..d044ac7 --- /dev/null +++ b/doc/comedilib.txt @@ -0,0 +1,1716 @@ + Comedi Documentation + David Schleef ds@stm.lbl.gov, Frank Hess fmhess@uiuc.edu + + + 11.. IInnttrroodduuccttiioonn + + This is preliminary documentation for Comedi and Comedilib. + + + 22.. IInnssttaallllaattiioonn aanndd ccoonnffiigguurraattiioonn + + + This section covers compiling, installing, and configuring comedi and + comedlib. + + + + 22..11.. CCoommppiilliinngg aanndd IInnssttaalllliinngg + + + This section has not been written. + + + + 22..22.. IInnssmmoodd''ddiinngg tthhee kkeerrnneell mmoodduullee + + + This section has not been written. + + + + 22..33.. CCoonnffiigguurriinngg ccoommeeddii ffoorr yyoouurr hhaarrddwwaarree + + + + 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: + + + +o I/O base + + +o IRQ + + +o 1=differential, 0=single ended + + +o ai 0=unipolar, 1=bipolar + + +o ao0 0=unipolar, 1=bipolar + + +o ao1 0=unipolar, 1=bipolar + + +o dma1 + + +o 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. + + + + 22..44.. GGeettttiinngg iinnffoorrmmaattiioonn ffrroomm ccoommeeddii + + + + 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. + + + + 33.. IInnddiivviidduuaall ddrriivveerrss + + + This section contains information that is specific to each hardware + driver. The most current information about a driver is included in + the comedi source. + + + 33..11.. NNaattiioonnaall IInnssttrruummeennttss AATT--MMIIOO EE sseerriieess + + + + 33..22.. DDaattaa TTrraannssllaattiioonn + + + + 44.. WWrriittiinngg pprrooggrraammss tthhaatt uussee ccoommeeddii aanndd ccoommeeddiilliibb + + + + 44..11.. YYoouurr ffiirrsstt ccoommeeddii pprrooggrraamm + + + 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; + 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. + + + + 44..22.. CCoonnvveerrttiinngg ssaammpplleess ttoo vvoollttaaggeess + + + 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 aallwwaayyss 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); + + + + 44..33.. AAnnootthheerr sseeccttiioonn + + + + 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. + + + + 44..44.. YYoouurr sseeccoonndd ccoommeeddii pprrooggrraamm + + + + 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 /* 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; + } + + + + 55.. AApppplliiccaattiioonn--ssppeecciiffiicc ffuunnccttiioonnss + + + + 55..11.. DDiiggiittaall IInnppuutt//OOuuttppuutt + + + 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. + + + + 55..22.. SSlloowwllyy--vvaarryyiinngg iinnppuuttss + + + + 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: + + + + +o you are ultimately limited by "spurious free dynamic range" + + +o you need to have _some_ noise on the input channel, otherwise you + will be averaging the same number N times. + + +o the more noise you have, the greater your SFDR, but it takes many + more samples to compensate for the increased noise + + +o 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. + + + + 55..33.. CCoommmmaannddss + + + + 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: + + + +o TRIG_NONE: don't ever cause an event, sometimes used as a + stop_src. + + +o 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. + + +o TRIG_FOLLOW: see notes below, usually used as a scan_begin_src. + + +o TRIG_TIME: cause event to occur at a particular time + + +o TRIG_TIMER: cause event to occur repeatedly at a specific rate, + often used as a scan_begin_src or convert_src. + + +o TRIG_COUNT: cause event when count reaches specific value, + almost always used as the scan_end_src and often for stop_src. + + +o 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. + + +o 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: + + + +o trigger src = TRIG_NONE: argument has no meaning + + +o trigger src = TRIG_NOW: argument is the delay in nanoseconds before + triggering + + +o trigger src = TRIG_FOLLOW: argument has no meaning + + +o trigger src = TRIG_TIME: argument is the time at which to trigger + (in what units??), but no drivers support this yet. + + +o trigger src = TRIG_TIMER: argument is the period in nanoseconds + between triggers + + + +o 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. + + +o trigger src = TRIG_EXT: argument is the digital input channel to + trigger on. + + +o 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. + + + +o TRIG_BOGUS: do the motions?? + + +o TRIG_DITHER: enable dithering?? + + +o TRIG_DEGLITCH: enable deglitching?? + + +o 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. + + +o TRIG_CONFIG: perform configuration, not triggering. + + +o 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. + + +o 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. + + +o TRIG_ROUND_NEAREST: round to nearest supported timing period, the + default. + + +o TRIG_ROUND_DOWN: round period down. + + + +o TRIG_ROUND_UP: round period up. + + +o TRIG_ROUND_UP_NEXT: this one doesn't do anything, and I don't know + what it was intended to do?? + + + + 66.. LLiibbccoommeeddii RReeffeerreennccee + + + + 66..11.. CCoonnssttaannttss aanndd MMaaccrrooss + + + + 66..11..11.. CCRR__PPAACCKK((cchhaannnneell,, rraannggee,, aarreeff)) + + + undocumented + + + 66..11..22.. RRAANNGGEE__LLEENNGGTTHH(()) ((ddeepprreeccaatteedd)) + + + 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. + + + + 66..22.. DDaattaa TTyyppeess aanndd SSttrruuccttuurreess + + + 66..22..11.. ccoommeeddii__tt + + 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. + + + + 66..22..22.. ssaammppll__tt + + 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. + + 66..22..33.. llssaammppll__tt + + 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. + + + + 66..22..44.. ccoommeeddii__ttrriigg__ssttrruucctt ((ddeepprreeccaatteedd)) + + + 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. + + + + 66..22..55.. ccoommeeddii__ssvv__tt + + + + 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. + + + + 66..22..66.. ccoommeeddii__ccmmdd + + + undocumented + + + Related functions are described in section XXX. + + + This structure is defined as part of the Comedi kernel interface. + + + + 66..22..77.. ccoommeeddii__iinnssnn + + + undocumented + + + Related functions are described in section XXX. + + + This structure is defined as part of the Comedi kernel interface. + + + + 66..22..88.. ccoommeeddii__rraannggee + + + undocumented + + + + 66..33.. FFuunnccttiioonnss + + + + 66..33..11.. ccoommeeddii__cclloossee(()) + + + 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 + + + + 66..33..22.. ccoommeeddii__ccoommmmaanndd(()) + + + int comedi_command(comedi_t *it, comedi_cmd *cmd); + + undocumented + + Source: /lib/comedi.c + + + + 66..33..33.. ccoommeeddii__ccoommmmaanndd__tteesstt(()) + + + int comedi_command_test(comedi_t *it, comedi_cmd *cmd); + + undocumented + + Source: /lib/comedi.c + + + + 66..33..44.. ccoommeeddii__ddaattaa__rreeaadd(()) + + + 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: + + + +o AREF_GROUND Reference to analog ground + + +o AREF_COMMON Reference to analog common + + +o AREF_DIFF Differential reference + + +o 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 + + + + 66..33..55.. ccoommeeddii__ddaattaa__wwrriittee(()) + + + 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: + + + +o AREF_GROUND Reference to analog ground + + +o AREF_COMMON Reference to analog common + + +o AREF_DIFF Differential reference + + +o 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 + + + + 66..33..66.. ccoommeeddii__ddiioo__bbiittffiieelldd(());; + + 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 + + + + 66..33..77.. ccoommeeddii__ddiioo__ccoonnffiigg(()) + + 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: + + +o COMEDI_INPUT + + +o COMEDI_OUTPUT + + Source: /lib/dio.c + + + + 66..33..88.. ccoommeeddii__ddiioo__rreeaadd(()) + + 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 + + + + 66..33..99.. ccoommeeddii__ddiioo__wwrriittee(()) + + 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 + + + + 66..33..1100.. ccoommeeddii__ffiilleennoo(()) + + + + 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 + + + + 66..33..1111.. ccoommeeddii__ffiinndd__rraannggee(()) + + + 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: + + + +o UNIT_volt + + +o UNIT_mA + + +o UNIT_none + + Source: /lib/range.c + + + + 66..33..1122.. ccoommeeddii__eerrrrnnoo(()) + + 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 + + + + 66..33..1133.. ccoommeeddii__ffiinndd__ssuubbddeevviiccee__bbyy__ttyyppee(()) + + + 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 + + + + 66..33..1144.. ccoommeeddii__ffrroomm__pphhyyss(()) + + + 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 + + + + 66..33..1155.. ccoommeeddii__ggeett__bbooaarrdd__nnaammee(()) + + + 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 + + + + 66..33..1166.. ccoommeeddii__ggeett__ccmmdd__ssrrcc__mmaasskk(()) + + + int comedi_get_cmd_src_mask(comedi_t *dev, unsigned int subdevice, + comedi_cmd *cmd); + + undocumented + + Source: /lib/cmd.c + + 66..33..1177.. ccoommeeddii__ggeett__ddrriivveerr__nnaammee(()) + + + 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 + + + + 66..33..1188.. ccoommeeddii__ggeett__mmaaxxddaattaa(()) + + + 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 + + + + 66..33..1199.. ccoommeeddii__ggeett__nn__cchhaannnneellss(()) + + + 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 + + + + 66..33..2200.. ccoommeeddii__ggeett__nn__rraannggeess(()) + + + 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 + + + + 66..33..2211.. ccoommeeddii__ggeett__nn__ssuubbddeevviicceess(()) + + + 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 + + + + 66..33..2222.. ccoommeeddii__ggeett__rraannggee(()) + + + 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 + + + + 66..33..2233.. ccoommeeddii__ggeett__rraannggeettyyppee(()) ddeepprreeccaatteedd + + + 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 + + + + 66..33..2244.. ccoommeeddii__ggeett__ssuubbddeevviiccee__ttyyppee(()) + + + 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: + + + +o COMEDI_SUBD_UNUSED Subdevice has no functionality, i.e., a place- + holder. + + +o COMEDI_SUBD_AI Analog input + + +o COMEDI_SUBD_AO Analog output + + +o COMEDI_SUBD_DI Digital input + + + +o COMEDI_SUBD_DO Digital output + + +o COMEDI_SUBD_DIO Digital input/output. Channels are configurable as + to whether they are inputs or outputs. + + +o COMEDI_SUBD_COUNTER Counter + + +o COMEDI_SUBD_TIMER Timer + + +o COMEDI_SUBD_MEMORY Memory, e.g., EEPROM or dual-ported RAM + + +o COMEDI_SUBD_CALIB Calibration DACs + + +o COMEDI_SUBD_PROC Processor or DSP + + Source: /lib/get.c + + + + 66..33..2255.. ccoommeeddii__ggeett__ttiimmeerr(()) ((ddeepprreeccaatteedd)) + + + 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 + + + + 66..33..2266.. ccoommeeddii__ggeett__vveerrssiioonn__ccooddee(()) + + + 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 + + + + 66..33..2277.. ccoommeeddii__lloogglleevveell(()) + + + 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: + + + +o COMEDILIB_LOGLEVEL=0 + + Comedilib prints nothing. + + +o COMEDILIB_LOGLEVEL=1 (default) + + Comedilib only prints error messages when there is a self- + consistency error (i.e., internal bug). + + +o COMEDILIB_LOGLEVEL=2 + + Comedilib prints an error message when an invalid parameter is + passed to comedilib. + + +o 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. + + +o COMEDILIB_LOGLEVEL=4 + + Comedilib prints a lot of debugging messages. + + Bugs: Libcomedi doesn't currently have much debugging information. + + Source: /lib/error.c + + + + 66..33..2288.. ccoommeeddii__ooppeenn(()) + + + 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 + + + + 66..33..2299.. ccoommeeddii__ppeerrrroorr(()) + + + 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 + + + + 66..33..3300.. ccoommeeddii__ssttrreerrrroorr(()) + + + *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 + + + + 66..33..3311.. ccoommeeddii__ssvv__iinniitt(()) + + + 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 + + + + 66..33..3322.. ccoommeeddii__ssvv__uuppddaattee(()) + + + 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 + + + + 66..33..3333.. iinntt ccoommeeddii__ssvv__mmeeaassuurree(()) + + + 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 + + + + 66..33..3344.. ccoommeeddii__ttoo__pphhyyss(()) + + + 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 + + + + 66..33..3355.. ccoommeeddii__ttrriiggggeerr(()) ((ddeepprreeccaatteedd)) + + + 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 + + + + 66..33..3366.. ccoommeeddii__ggeett__ssuubbddeevviiccee__ffllaaggss(()) + + + 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: + + + +o SDF_BUSY subdevice is running a command + + +o SDF_BUSY_OWNER subdevice is running a command started by the file + descriptor used by dev. + + +o SDF_LOCKED subdevice is locked + + +o SDF_LOCKED_OWNER subdevice is locked by the file descriptor + used by dev. + + +o SDF_MAXDATA maximum data values are channel dependent + + +o SDF_FLAGS channel flags are channel dependent + + +o SDF_RANGETYPE range types are channel dependent + + +o SDF_MODE0 deprecated + + +o SDF_MODE1 deprecated + + +o SDF_MODE2 deprecated + + +o SDF_MODE3 deprecated + + +o SDF_MODE4 deprecated + + +o SDF_CMD subdevice supports commands + + +o SDF_READABLE subdevice can be read from + + +o SDF_WRITEABLE subdevice can be written to + + +o SDF_RT deprecated + + +o SDF_GROUND subdevice is capable of ground analog reference + + +o SDF_COMMON subdevice is capable of common analog reference + + +o SDF_DIFF subdevice is capable of differential analog + reference + + +o SDF_OTHER subdevice is capable of other analog + reference + + +o SDF_DITHER subdevice recognizes dither flag + + +o SDF_DEGLITCH subdevice recognizes deglitch flag + + +o SDF_MMAP deprecated + + +o SDF_RUNNING subdevice is acquiring data (i.e., command has not + completed) + + +o SDF_LSAMPL subdevice uses samples of type lsampl_t (otherwise + sampl_t) + + +o SDF_PACKED subdevice uses bitfield samples (otherwise it uses + one sample per channel) + + + + The bit definitions are part of the Comedi kernel interface. + + + + 66..33..3377.. ccoommeeddii__rraannggee__iiss__cchhaann__ssppeecciiffiicc(()) + + + 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. + + + + 66..33..3388.. UUnnddooccuummeenntteedd ffuunnccttiioonnss + + + + +o comedi_maxdata_is_chan_specific() + + +o comedi_get_buffer_size() + + +o comedi_get_max_buffer_size() + + +o comedi_set_buffer_size() + + +o comedi_set_max_buffer_size() + + +o comedi_do_insnlist() + + +o comedi_do_insn() + + +o comedi_lock() + + +o comedi_unlock() + + +o comedi_get_cmd_src_mask() + + +o comedi_get_cmd_generic_timed() + + +o comedi_cancel() + + +o comedi_command() + + +o comedi_command_test() + + +o comedi_poll() + + +o comedi_get_buffer_contents() + + +o comedi_mark_buffer_read() + + +o comedi_get_buffer_offset() + + +o comedi_set_global_oor_behavior() + + +