What are the addresses and meanings of all the card's registers?
</para>
<para>
-This information is to be found in the so-called “register level
-manual” of the card. Without it, coding a device driver is close
+This information is to be found in the so-called <quote>register level
+manual</quote> of the card. Without it, coding a device driver is close
to hopeless. It is also something that &comedi; (and hence also this
handbook) cannot give any support or information for: board
manufacturers all use their own design and nomenclature.
<function>comedi_subdevice</function>
<para>
The subdevice is the smallest &comedi; entity that can be used for
-“stand-alone” DAQ, so it is no surprise that it is
+<quote>stand-alone</quote> DAQ, so it is no surprise that it is
quite big:
<programlisting>
struct comedi_subdevice_struct{
</para>
<para>
To help device driver writers,
-&comedi; provides the “skeleton” of a new device driver,
+&comedi; provides the <quote>skeleton</quote> of a new device driver,
in the <filename>comedi/drivers/skel.c</filename> file. Before
starting to write a new driver, make sure you understand this file,
and compare it to what you find in the other already available
mydriver_attach();
mydriver_detach();
</programlisting>
-In the “attach” function, memory is allocated for the
+In the <quote>attach</quote> function, memory is allocated for the
necessary <link linkend="driverdatastructures">data structures</link>,
all properties of a device and its subdevices are defined, and filled
in in the generic &comedi; data structures. As part of this, pointers
<emphasis>asynchronous</emphasis> activity: the function call that
has set the acquisition in motion has returned before the acquisition
has finished (or even started). So, not only the acquired data must be
-sent back to the user's buffer “in the background”, but
+sent back to the user's buffer <quote>in the background</quote>, but
various types of asynchronous <emphasis>event handling</emphasis> can
be needed during the acquisition:
<itemizedlist>
<listitem>
<para>
The device driver writer can register a driver-supplied
-”callback” function, that is called at the end of each
+<quote>callback</quote> function, that is called at the end of each
hardware interrupt routine.
</para>
</listitem>
<para>
<anchor id="comedi-cb-eoa">
<parameter>COMEDI_CB_EOA</parameter>: execute the callback at the
-“End Of-Acquisition”.
+<quote>End Of-Acquisition</quote>.
</para>
</listitem>
<para>
<anchor id="comedi-cb-eos">
<parameter>COMEDI_CB_EOS</parameter>: execute the callback at the
-“End-Of-Scan”.
+<quote>End-Of-Scan</quote>.
</para>
</listitem>
<listitem>
<para>
-Some DAQ cards consist of different “layers” of hardware,
+Some DAQ cards consist of different <quote>layers</quote> of hardware,
which can each be given their own device driver. Examples are:
some of the National Instruments cards, that all share the same
<emphasis>Mite</emphasis> PCI driver chip; the ubiquitous parallel
<listitem>
<para>
Choose a senseful name for the source code file. Let's assume here
-that you call it “mydriver.c”
+that you call it <quote>mydriver.c</quote>
</para>
</listitem>
<listitem>
<para>
-Put your new driver into “comedi/drivers/mydriver.c”.
+Put your new driver into <quote>comedi/drivers/mydriver.c</quote>.
</para>
</listitem>
<listitem>
<para>
-Edit “comedi/Config.in” and add a new
-“dep_tristate” line (look at the other examples). Invent a
+Edit <quote>comedi/Config.in</quote> and add a new
+<quote>dep_tristate</quote> line (look at the other examples). Invent a
senseful name for the driver's variable. For example:
<programlisting>
dep_tristate 'MYDRIVER' CONFIG_COMEDI_MYDRIVER $CONFIG_COMEDI
<listitem>
<para>
-Add a line to “comedi/drivers/Makefile.in”, using your
+Add a line to <quote>comedi/drivers/Makefile.in</quote>, using your
freshly defined variable, i.e., CONFIG_COMEDI_MYDRIVER.
</para>
</listitem>
PATH=/sbin:/usr/sbin:/usr/local/sbin:$PATH
comedi_config /dev/comedi0 labpc-1200 0x260,3
</screen>
-This command says that the “file”
+This command says that the <quote>file</quote>
<filename>/dev/comedi0</filename> can be used to access the &comedi;
device that uses the <parameter>labpc-1200</parameter> board, and that
you give it two run-time parameters (<literal>0x260</literal> and
<para>
<emphasis role="strong">Comedi</emphasis> is a collection of drivers for a variety
of common data acquisition plug-in boards (which are called
-“devices” in &comedi; terminology). The drivers are
+<quote>devices</quote> in &comedi; terminology). The drivers are
implemented as the combination of (i) one single core Linux kernel module
-(called “<literal>comedi</literal>”) providing common
+(called <quote><literal>comedi</literal></quote>) providing common
functionality, and (ii) individual low-level driver modules for
each device.
</para>
(distributed with the <literal>comedi</literal> package) that provides
the same interface as <emphasis>comedilib</emphasis> in kernel space,
and suitable for <emphasis>real-time</emphasis> tasks. It is
-effectively a “kernel library” for using &comedi; from
+effectively a <quote>kernel library</quote> for using &comedi; from
real-time tasks.
</para>
</listitem>
<section id="whatisdevicedriver">
<title>
-What is a “device driver”?
+What is a <quote>device driver</quote>?
</title>
<para>
A device driver is a piece of software that interfaces a particular
<emphasis>modularity</emphasis> and <emphasis>complexity</emphasis>:
it's fairly easy to integrate a new card because most of the
infrastructure part of other, similar drivers can be reused, and
-learning the generic and hence somewhat “heavier” &comedi;
+learning the generic and hence somewhat <quote>heavier</quote> &comedi;
API doesn't scare away new contributors from integrating their drivers
into the &comedi; framework.
</para>
the device driver code should reflect this fact. For example, many
different interface cards use the same PCI driver chips, or use the
parallel port as an intermediate means to connect to the hardware
-device. Hence, “lower-level” device drivers for
+device. Hence, <quote>lower-level</quote> device drivers for
these PCI chips and parallel ports allow for an increased modularity
and re-useability of the software. Finding the generic
similarities and structure among different cards helps in developing
this device driver, however, runs in kernel space, and the user
application in user space. So, the operating system provides an
interface between both. In Linux or Unix, these interfaces are in the
-form of “files”
+form of <quote>files</quote>
in the <filename class=directory>/dev</filename> directory (2.2.x kernels or
earlier) or <filename class=directory>/devfs</filename> directory
(2.4.x kernels and later). Each device supported in the kernel has a
Linux (and some other UNIX operating systems) offer a file-like
interface to attached devices (and other OS-related information) via
the <filename class=directory>/proc</filename> directories. These
-“files” do not really exist, but it gives a familiar
+<quote>files</quote> do not really exist, but it gives a familiar
interface to users, with which they can inspect the current status of
each device.
</para>
responsible for directly accessing the bus addresses allocated to
the device whenever it needs
to read or write data. Some devices also allow DMA: the device and the
- memory “talk” to each other directly, without needing the processor.
+ memory <quote>talk</quote> to each other directly, without needing the processor.
DMA is a feature of the bus, not of the operating system (which, of
course, has
to support its processes to use the feature).
</listitem>
</itemizedlist>
-In addition to these “real” DAQ functions, &comedi; also
+In addition to these <quote>real</quote> DAQ functions, &comedi; also
offers basic timer access.
</para>
</section>
Each channel has several parameters, such as: the voltage range; the
reference voltage; the channel polarity (unipolar, bipolar); a
conversion factor between voltages and physical units; the binary
-values “0” and “1”; etc.
+values <quote>0</quote> and <quote>1</quote>; etc.
</para>
</listitem>
Some interface cards have extra components that don't fit in the
above-mentioned classification, such as an EEPROM to store
configuration and board parameters, or calibration inputs. These
-special components are also classified as “sub-devices” in
+special components are also classified as <quote>sub-devices</quote> in
&comedi;.
</para>
<para>
This Section introduces the terminology that this document uses when
-talking about “acquisitions.” <xref linkend="fig-acq-seq">
+talking about <quote>acquisitions.</quote> <xref linkend="fig-acq-seq">
depicts a typical acquisition <emphasis role="strong">sequence</emphasis>:
<itemizedlist>
<emphasis role="strong">end</emphasis>, and a finite
<emphasis role="strong">setup time</emphasis>. Possibly, there is also
a settling time
-(“<emphasis role="strong">scan delay</emphasis>”) at the
+(<quote><emphasis role="strong">scan delay</emphasis></quote>) at the
end of a scan.
</para>
<para>
moment in time called the
<emphasis role="strong">sample time</emphasis>
in <xref linkend="fig-acq-seq">
-(sometimes also called the “timestamp”),
+(sometimes also called the <quote>timestamp</quote>),
and caused by a
triggering event, called <emphasis role="strong">convert</emphasis>.
In addition, each hardware has limits on the minimum
one single AD/DA hardware, such that the conversions are done serially
in time (as shown on the <link linkend="fig-acq-seq">Figure</link>);
other cards have the hardware to do two or more acquisitions in
-parallel. The begin of each conversion is “triggered” by
+parallel. The begin of each conversion is <quote>triggered</quote> by
some internally or externally generated pulse, e.g., a timer.
</para>
</listitem>
<function>comedi_data_write()</function>,
<function>comedi_dio_read()</function>,
<function>comedi_dio_write()</function>.
-“Synchronous” means that the calling process
+<quote>Synchronous</quote> means that the calling process
blocks until the data acquisition has finished.
</para>
</listitem>
the data acquisition,
and makes sure that the acquired data is delivered
in a software buffer provided by the calling process. Asynchronous
-operation requires some form of “callback” functionality
+operation requires some form of <quote>callback</quote> functionality
to prevent buffer overflow: after the calling process has launched the
acquisition command, it goes off doing other things, but not after it
-has configured the “handler” that the interface card can
+has configured the <quote>handler</quote> that the interface card can
use when it needs to put data in the calling process's buffer.
Interrupt routines or DMA are typical techniques to allow such
asynchronous operation. Their handlers are configured at driver load
As already mentioned before, &comedi; contains more than just
procedural function calls, since it also offers
<emphasis role="strong">event-driven</emphasis>
-(“asynchronous”) functionality:
+(<quote>asynchronous</quote>) functionality:
the data acquisition can signal
its completion by means of an interrupt or a
<emphasis>callback</emphasis> function call.
<para>
Finally, &comedi; offers the previously mentioned
-“high-level” interaction, i.e., at the level of user space
+<quote>high-level</quote> interaction, i.e., at the level of user space
device drivers, through file operations on entries in the
<filename class=directory>/dev</filename> directory (for access to the
device's functionality), or interactively from the command line
-through the “files” in the
+through the <quote>files</quote> in the
<filename class=directory>/proc</filename> directory (which allow to
inspect the status of a &comedi; device).
</para>
<para>
This Section gives an overview of all &comedi; functions with which
application programmers can implement their data acquisition. (With
-“acquisition” we mean all possible kinds of interfacing
+<quote>acquisition</quote> we mean all possible kinds of interfacing
with the cards: input, output, configuration, streaming, etc.)
<xref linkend="comedireference"> explains the function calls in full
detail.
<listitem>
<para>
<link linkend="ref-type-lsampl-t">lsampl_t</link>: this
-“data structure” represents one single sample. On most
+<quote>data structure</quote> represents one single sample. On most
architectures, it's nothing more than a 32 bits value. Internally,
&comedi; does some conversion from raw sample data to
-“correct” integers. This is called “data
-munging”.
+<quote>correct</quote> integers. This is called <quote>data
+munging</quote>.
</para>
</listitem>
<listitem>
<para>
-INSN_GTOD: the instruction performs a “Get Time Of Day”
+INSN_GTOD: the instruction performs a <quote>Get Time Of Day</quote>
acquisition.
</para>
</listitem>
The
<link linkend="insn-data-structure-data">data</link>[0] field of the
INSN_INTTRIG instruction is reserved for future use, and should be set
-to “0”.
+to <quote>0</quote>.
</para>
</section>
specifies the sequence of channels and gains (and analog references)
that should be stepped through for each scan. The elements of the
<link linkend="command-data-struct-chanlist">chanlist</link> array should be
-initialized by “packing” the channel, range and reference
+initialized by <quote>packing</quote> the channel, range and reference
information together with the
<parameter class=function>
<link linkend="ref-macro-CR-PACK">CR_PACK()</link>
argument (the <parameter class=function>*_arg</parameter> members of
the <link linkend="ref-type-comedi-cmd">comedi_cmd</link> data
structure) whose meaning depends on the type of source trigger.
-For example, to specify an external digital line “3” as a
+For example, to specify an external digital line <quote>3</quote> as a
source (in general, <emphasis>any</emphasis> of the five event
sources), you would use
<parameter>src</parameter>=<link linkend="trig-ext">TRIG_EXT</link> and
</para>
<para>
Its argument is reserved and should be set to 0.
-(“Reserved”
+(<quote>Reserved</quote>
means that unspecified things could happen if it is set to something
else but 0.)
</para>
The
<link linkend="command-data-struct-flags">flags</link> field in the
<link linkend="ref-type-comedi-cmd">command data structure</link>
-is used to specify some “behaviour” of the acquisitions in
+is used to specify some <quote>behaviour</quote> of the acquisitions in
a command.
The meaning of the field is as follows:
<itemizedlist>
<para>
<anchor id="trig-wake-eos">
TRIG_WAKE_EOS:
-where “EOS” stands for “End of Scan”. Some
+where <quote>EOS</quote> stands for <quote>End of Scan</quote>. 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 hardware data buffer is
<para>
<anchor id="trig-dither">
TRIG_DITHER: enable dithering? Dithering is a software technique to
-smooth the influence of discretization “noise”.
+smooth the influence of discretization <quote>noise</quote>.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-deglitch">
-TRIG_DEGLITCH: enable deglitching? Another “noise”
+TRIG_DEGLITCH: enable deglitching? Another <quote>noise</quote>
smoothing technique.
</para>
</listitem>
<listitem>
<para>
-you are ultimately limited by “Spurious Free Dynamic
-Range”. This SFDR is one of the popular measures to quantify how
+you are ultimately limited by <quote>Spurious Free Dynamic
+Range</quote>. This SFDR is one of the popular measures to quantify how
much noise a signal carries. If you take a Fourier transform of your
-signal, you will see several “peaks” in the transform: one
+signal, you will see several <quote>peaks</quote> in the transform: one
or more of the fundamental harmonics of the measured signal, and lots
-of little “peaks” (called “spurs”) caused by
+of little <quote>peaks</quote> (called <quote>spurs</quote>) caused by
noise. The SFDR is then the difference between the amplitude of the
fundamental harmonic and of the largest spur (at frequencies below
half of the Nyquist frequency of the DAQ sampler!).
When one or several digital inputs are used to modify an output
value, either an accumulator or a single digital line or bit,
a bitfield structure is typically used in the &comedi; interface.
-The digital inputs have two properties, “sensitive” inputs
-and “modifier” inputs. Edge transitions on sensitive
+The digital inputs have two properties, <quote>sensitive</quote> inputs
+and <quote>modifier</quote> inputs. Edge transitions on sensitive
inputs cause changes in the output signal, whereas modifier inputs
change the effect of edge transitions on sensitive inputs. Note that
inputs can be both modifier inputs and sensitive inputs.
<term>AREF_COMMON <anchor id="aref-common"> </term>
<listitem>
<para>
- is for a “common” reference (the low inputs of all the
+ is for a <quote>common</quote> reference (the low inputs of all the
channels are tied together, but are isolated from ground).
</para>
</listitem>
<para>
The data type <parameter>subdevice_struct</parameter> is used to store
information about a subdevice. This structure is usually filled in
-automatically when the driver is loaded (“attached”), so
+automatically when the driver is loaded (<quote>attached</quote>), so
programmers need not access this data structure directly.
<programlisting>
typedef struct subdevice_struct <anchor id="ref-type-subdevice">subdevice;
<para>
The data type <parameter>comedi_devinfo</parameter> is used to store
information about a device. This structure is usually filled in
-automatically when the driver is loaded (“attached”), so
+automatically when the driver is loaded (<quote>attached</quote>), so
programmers need not access this data structure directly.
<programlisting>
typedef struct comedi_devinfo_struct comedi_devinfo;
</function> can only be successful if the
<filename>comedi0</filename> device file is configured to point to a
valid &comedi; driver. <xref linkend="cardconfiguration"> explains
-how this driver is linked to the “device file”.
+how this driver is linked to the <quote>device file</quote>.
<para>
The code above is basically the guts of
<filename>demo/inp.c</filename>, without error checking or fancy
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?”
+question is: <quote>How do I do this in a device-independent
+manner?</quote>
</para>
<para>
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
+parameter is called the <quote>range parameter,</quote> since it
+specifies the <quote>input range</quote> for analog input (or
+<quote>output range</quote> for analog output.) The range parameter
represents both the gain and the unipolar/bipolar aspects.
</para>
</para>
<para>
-“Could it get easier?” you say. Well, yes. Use
+<quote>Could it get easier?</quote> you say. Well, yes. Use
the function <function>comedi_to_phys()</function>
<link linkend="func-ref-comedi-to-phys">comedi_to_phys()</link>, which
converts data values to physical units. Call it using something like