2008-01-24 01:32:41 +00:00
|
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
2012-05-01 12:51:08 +01:00
|
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
|
2008-01-24 01:32:41 +00:00
|
|
|
<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
|
|
|
|
%comedilib_entities;
|
|
|
|
]>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<section id="acquisitionfunctions">
|
2002-01-21 15:17:12 +00:00
|
|
|
<title>
|
2003-07-07 22:34:18 +00:00
|
|
|
Acquisition and configuration functions
|
2002-01-21 15:17:12 +00:00
|
|
|
</title>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
This Section gives an overview of all &comedi; functions with which
|
2003-07-07 22:34:18 +00:00
|
|
|
application programmers can implement their data acquisition. (With
|
2003-07-11 22:53:40 +00:00
|
|
|
<quote>acquisition</quote> we mean all possible kinds of interfacing
|
2003-07-07 22:34:18 +00:00
|
|
|
with the cards: input, output, configuration, streaming, etc.)
|
2008-01-24 01:32:41 +00:00
|
|
|
<xref linkend="comedireference"/> explains the function calls in full
|
2003-07-07 22:34:18 +00:00
|
|
|
detail.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<section id="singleacquisition">
|
|
|
|
<title>
|
|
|
|
Functions for single acquisition
|
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The simplest form of using &comedi; is to get one single sample to or
|
|
|
|
from an interface card. This sections explains how to do such simple
|
|
|
|
<link linkend="dio">digital</link> and
|
|
|
|
<link linkend="singleanalog">analog</link> acquisitions.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<section id="dio">
|
|
|
|
<title>
|
|
|
|
Single digital acquisition
|
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Many boards supported by &comedi; have digital input and output
|
|
|
|
channels; i.e., channels that can only produce a <literal>0</literal>
|
|
|
|
or a <literal>1</literal>.
|
|
|
|
Some boards allow the <emphasis>direction</emphasis> (input or output)
|
|
|
|
of each channel to be specified independently in software.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
&comedi; groups digital channels into a
|
|
|
|
<emphasis>subdevice</emphasis>, 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.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Individual bits on a digital I/O device can be read and written using
|
2012-05-03 19:56:59 +01:00
|
|
|
the functions <function><link linkend="func-ref-comedi-dio-read">comedi_dio_read</link></function>
|
|
|
|
and <function><link linkend="func-ref-comedi-dio-write">comedi_dio_write</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_dio_read</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int *<parameter>bit</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_dio_write</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>bit</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
The <parameter class="function">device</parameter> parameter is a
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="ref-type-comedi-t">pointer</link>
|
|
|
|
to a successfully opened &comedi; device.
|
2008-01-24 01:32:41 +00:00
|
|
|
The <parameter class="function">subdevice</parameter> and
|
|
|
|
<parameter class="function">channel</parameter> parameters are positive
|
2003-07-07 22:34:18 +00:00
|
|
|
integers that indicate which subdevice and channel is used in the
|
2008-01-24 01:32:41 +00:00
|
|
|
acquisition. The integer <parameter class="function">bit</parameter>
|
2003-07-07 22:34:18 +00:00
|
|
|
contains the value of the acquired bit.
|
2003-12-21 18:07:42 +00:00
|
|
|
</para>
|
2003-07-07 22:34:18 +00:00
|
|
|
<para>
|
2012-05-02 15:47:59 +01:00
|
|
|
The direction of bidirectional lines can be configured using the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-dio-config">comedi_dio_config</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_dio_config</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>dir</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
The parameter <parameter class="function">dir</parameter> should be
|
2012-05-01 15:42:07 +01:00
|
|
|
either <constant>COMEDI_INPUT</constant> or
|
|
|
|
<constant>COMEDI_OUTPUT</constant>.
|
2003-07-07 22:34:18 +00:00
|
|
|
Many digital I/O subdevices group channels into blocks for
|
|
|
|
configuring direction. Changing one channel in a block changes
|
|
|
|
the entire block.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Multiple channels can be read and written simultaneously using the
|
2012-05-03 19:56:59 +01:00
|
|
|
function <function><link linkend="func-ref-comedi-dio-bitfield2">comedi_dio_bitfield2</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_dio_bitfield2</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>write_mask</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int *<parameter>bits</parameter></paramdef>
|
2012-05-02 12:54:46 +01:00
|
|
|
<paramdef>unsigned int <parameter>base_channel</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-02 12:54:46 +01:00
|
|
|
Each channel from <parameter class="function">base_channel</parameter>
|
|
|
|
to <parameter class="function">base_channel</parameter> +
|
|
|
|
<literal>31</literal> is assigned to a bit in the
|
2008-01-24 01:32:41 +00:00
|
|
|
<parameter class="function">write_mask</parameter> and
|
|
|
|
<parameter class="function">bits</parameter>
|
2012-05-02 12:54:46 +01:00
|
|
|
bitfield with bit 0 assigned to channel
|
|
|
|
<parameter class="function">base_channel</parameter>, bit 1 assigned to channel
|
|
|
|
<parameter class="function">base_channel</parameter> +
|
|
|
|
<literal>1</literal>, etc. If a bit in
|
2008-01-24 01:32:41 +00:00
|
|
|
<parameter class="function">write_mask</parameter> is set, the
|
|
|
|
corresponding bit in <parameter class="function">*bits</parameter> will
|
2012-05-02 12:54:46 +01:00
|
|
|
be written to the digital output line corresponding to the channel given by
|
|
|
|
<parameter class="function">base_channel</parameter> plus the bit number.
|
2006-10-24 15:07:41 +00:00
|
|
|
Each digital line is then read and placed into
|
2008-01-24 01:32:41 +00:00
|
|
|
<parameter class="function">*bits</parameter>. The value
|
|
|
|
of bits in <parameter class="function">*bits</parameter> corresponding
|
2003-07-07 22:34:18 +00:00
|
|
|
to digital output lines is undefined and device-specific. Channel
|
2012-05-02 12:54:46 +01:00
|
|
|
<parameter class="function">base_channel</parameter> +
|
|
|
|
<literal>0</literal> is the least significant bit in the bitfield. No
|
|
|
|
more than 32 channels at once can be accessed using this method.
|
|
|
|
<emphasis role="strong">Warning!</emphasis> Older versions of &comedi;
|
|
|
|
may ignore <parameter class="function">base_channel</parameter> and treat
|
|
|
|
it as <literal>0</literal> unless the subdevice has more than 32 channels.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The digital acquisition functions seem to be very simple, but, behind
|
|
|
|
the implementation screens of the &comedi; kernel module, they are
|
|
|
|
executed as special cases of the general
|
|
|
|
<link linkend="instructions">instruction</link> command.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="singleanalog">
|
|
|
|
<title>
|
|
|
|
Single analog acquisition
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
Analog &comedi; channels can produce data values that are
|
|
|
|
<emphasis>samples</emphasis> from continuous analog signals.
|
|
|
|
These samples are integers with a significant content in
|
2012-05-02 15:47:59 +01:00
|
|
|
the range of, typically, 8, 10, 12, or 16 bits.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-02 15:47:59 +01:00
|
|
|
Single samples can be read from an analog channel using the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-data-read">comedi_data_read</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_data_read</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>range</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>aref</parameter></paramdef>
|
2012-05-02 15:47:59 +01:00
|
|
|
<paramdef>lsampl_t *<parameter>data</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
This reads one such data value from a &comedi; channel, and puts it in
|
2012-05-09 18:41:51 +01:00
|
|
|
the user-specified <parameter class="function">data</parameter> buffer.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The <parameter class="function">range</parameter> parameter is the zero-based
|
|
|
|
index of one of the gain ranges supported by the channel. This is a number
|
|
|
|
from 0 to N-1 where N is the number of ranges supported by the channel.
|
|
|
|
Use the function
|
|
|
|
<function><link linkend="func-ref-comedi-get-n-ranges">comedi_get_n_ranges</link></function>
|
|
|
|
to get the number of ranges supported by the channel, the function
|
|
|
|
<function><link linkend="func-ref-comedi-find-range">comedi_find_range</link></function>
|
|
|
|
to search for a suitable range, or the function
|
|
|
|
<function><link linkend="func-ref-comedi-get-range">comedi_get_range</link></function>
|
|
|
|
to get the details of a supported range.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The <parameter class="function">aref</parameter> parameter specifies an
|
|
|
|
analog reference to use:
|
|
|
|
<constant><link linkend="aref-ground">AREF_GROUND</link></constant>,
|
|
|
|
<constant><link linkend="aref-common">AREF_COMMON</link></constant>,
|
|
|
|
<constant><link linkend="aref-diff">AREF_DIFF</link></constant>, or
|
|
|
|
<constant><link linkend="aref-other">AREF_OTHER</link></constant>.
|
|
|
|
Use the function
|
|
|
|
<function><link linkend="func-ref-comedi-get-subdevice-flags">comedi_get_subdevice_flags</link></function>
|
|
|
|
to see which analog references are supported by the subdevice.
|
2012-05-02 15:47:59 +01:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
In the opposite direction, single samples can be written to an analog output
|
|
|
|
channel using the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-data-write">comedi_data_write</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_data_write</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>range</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>aref</parameter></paramdef>
|
2012-05-02 15:47:59 +01:00
|
|
|
<paramdef>lsampl_t <parameter>data</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
2012-05-02 15:47:59 +01:00
|
|
|
</para>
|
2012-05-01 15:42:07 +01:00
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
<para>
|
|
|
|
Raw data values read or written by the above functions
|
2003-07-07 22:34:18 +00:00
|
|
|
are unsigned integers less than, or equal to, the maximum sample value
|
|
|
|
of the channel, which can be determined using the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-get-maxdata">comedi_get_maxdata</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>lsampl_t <function>comedi_get_maxdata</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
Conversion between raw data values and uncalibrated physical units can
|
|
|
|
be performed by the functions
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-to-phys">comedi_to_phys</link></function>
|
|
|
|
and <function><link linkend="func-ref-comedi-from-phys">comedi_from_phys</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>double <function>comedi_to_phys</function></funcdef>
|
|
|
|
<paramdef>lsampl_t <parameter>data</parameter></paramdef>
|
|
|
|
<paramdef>comedi_range *<parameter>range</parameter></paramdef>
|
|
|
|
<paramdef>lsampl_t <parameter>maxdata</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcsynopsis><funcprototype>
|
|
|
|
<funcdef>lsampl_t <function>comedi_from_phys</function></funcdef>
|
|
|
|
<paramdef>double <parameter>data</parameter></paramdef>
|
|
|
|
<paramdef>comedi_range *<parameter>range</parameter></paramdef>
|
|
|
|
<paramdef>lsampl_t <parameter>maxdata</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-09 18:41:51 +01:00
|
|
|
There are some data structures in these commands that are not fully
|
2003-07-07 22:34:18 +00:00
|
|
|
self-explanatory:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-t">comedi_t</link></type>: this data structure
|
2003-07-07 22:34:18 +00:00
|
|
|
contains all information that a user program has to know about an
|
|
|
|
<emphasis>open</emphasis> &comedi; device. The programmer doesn't have
|
|
|
|
to fill in this data structure manually: it gets filled in by opening
|
|
|
|
the device.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-lsampl-t">lsampl_t</link></type>: this
|
2003-07-11 22:53:40 +00:00
|
|
|
<quote>data structure</quote> represents one single sample. On most
|
2003-07-07 22:34:18 +00:00
|
|
|
architectures, it's nothing more than a 32 bits value. Internally,
|
|
|
|
&comedi; does some conversion from raw sample data to
|
2003-07-11 22:53:40 +00:00
|
|
|
<quote>correct</quote> integers. This is called <quote>data
|
|
|
|
munging</quote>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
2012-05-09 18:41:51 +01:00
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
<type><link linkend="ref-type-comedi-range">comedi_range</link></type>:
|
|
|
|
this holds the minimum and maximum physical values for a gain range supported
|
|
|
|
by a channel of a subdevice, and specifies the units. This can be used in
|
|
|
|
combination with the channel's <quote>maxdata</quote> value to convert between
|
|
|
|
unsigned integer sample values (of type
|
|
|
|
<type><link linkend="ref-type-lsampl-t">lsampl_t</link></type> or
|
|
|
|
<type><link linkend="ref-type-sampl-t">sampl_t</link></type>) and physical
|
|
|
|
units in a nominal (uncalibrated) way using the
|
|
|
|
<function><link linkend="func-ref-comedi-to-phys">comedi_to_phys</link></function>
|
|
|
|
and
|
|
|
|
<function><link linkend="func-ref-comedi-from-phys">comedi_from_phys</link></function>
|
|
|
|
functions. Use the
|
|
|
|
<function><link linkend="func-ref-comedi-get-maxdata">comedi_get_maxdata</link></function>
|
|
|
|
function to get the <quote>maxdata</quote> value for the channel.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Most functions specify the range to be used for a channel by a zero-based
|
|
|
|
index into the list of ranges supported by the channel. Depending on the
|
|
|
|
device and subdevice, different channels on the subdevice may or may not
|
|
|
|
share the same list of ranges, that is, ranges may or may not be
|
|
|
|
channel-specific. (The <constant>SDF_RANGETYPE</constant> subdevice flag
|
|
|
|
indicates whether ranges are channel-specific.)
|
|
|
|
</para>
|
2003-07-07 22:34:18 +00:00
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Each single acquisition by, for example,
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-data-read">comedi_data_read</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
requires quite some overhead, because all the arguments of the
|
|
|
|
function call are checked. If multiple acquisitions must be done on
|
|
|
|
the same channel, this overhead can be avoided by using a function
|
2012-05-02 15:47:59 +01:00
|
|
|
that can read more than one sample,
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-data-read-n">comedi_data_read_n</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_data_read_n</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>range</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>aref</parameter></paramdef>
|
2012-05-02 15:47:59 +01:00
|
|
|
<paramdef>lsampl_t *<parameter>data</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>n</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
The number of samples, <parameter class="function">n</parameter>, is
|
2003-07-07 22:34:18 +00:00
|
|
|
limited by the &comedi; implementation (to a maximum of 100 samples),
|
|
|
|
because the call is blocking.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-02 15:47:59 +01:00
|
|
|
The start of the a single data acquisition can also be delayed by a specified
|
|
|
|
number of nano-seconds using the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-data-read-delayed">comedi_data_read_delayed</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_data_read_delayed</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>range</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>aref</parameter></paramdef>
|
2012-05-02 15:47:59 +01:00
|
|
|
<paramdef>lsampl_t *<parameter>data</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>nano_sec</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
2012-05-02 15:47:59 +01:00
|
|
|
</para>
|
2012-05-01 15:42:07 +01:00
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
All these read and write acquisition functions are implemented on top
|
|
|
|
of the generic <link linkend="instructions">instruction</link>
|
|
|
|
command.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="instructions">
|
|
|
|
<title>
|
2006-10-24 15:07:41 +00:00
|
|
|
Instructions for multiple acquisitions
|
2003-07-07 22:34:18 +00:00
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
The <emphasis>instruction</emphasis> is one of the most generic,
|
|
|
|
overloaden and flexible functions in the &comedi; API. It is used to
|
|
|
|
execute a multiple of identical acquisitions on the same channel, but
|
|
|
|
also to perform a
|
|
|
|
<link linkend="instructionsconfiguration">configuration</link> of a
|
|
|
|
channel.
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="anchor.instruction.list"/>
|
2003-07-07 22:34:18 +00:00
|
|
|
An <emphasis>instruction list</emphasis> is a list of instructions,
|
|
|
|
possibly on different channels. Both instructions and instructions
|
|
|
|
lists are executed <emphasis>synchronously</emphasis>, i.e., while
|
|
|
|
<emphasis role="strong">blocking</emphasis> the calling process.
|
|
|
|
This is one of the limitations of instructions; the other one is that
|
|
|
|
they cannot code an acquisition involving timers or external events.
|
|
|
|
These limits are eliminated by the
|
|
|
|
<link linkend="commandsstreaming">command</link> acquisition
|
|
|
|
primitive.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="comediinsnstructure">
|
|
|
|
<title>
|
|
|
|
The instruction data structure
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
All the information needed to execute an instruction is stored in the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-insn">comedi_insn</link></type>
|
2003-07-07 22:34:18 +00:00
|
|
|
data structure:
|
|
|
|
<programlisting>
|
2012-05-02 15:47:59 +01:00
|
|
|
typedef struct <anchor id="insn-data-structure"/>comedi_insn_struct {
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="insn-data-structure-insn"/>unsigned int insn; // integer encoding the type of acquisition
|
2003-07-07 22:34:18 +00:00
|
|
|
// (or configuration)
|
2006-10-25 19:57:49 +00:00
|
|
|
unsigned int n; // number of elements in data array
|
2008-01-24 01:32:41 +00:00
|
|
|
<link linkend="ref-type-lsampl-t">lsampl_t</link> <anchor id="insn-data-structure-data"/>*data; // pointer to data buffer
|
2003-07-07 22:34:18 +00:00
|
|
|
unsigned int subdev; // subdevice
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="insn-data-structure-chanspec"/><link linkend="ref-macro-CR-PACK">chanspec</link>; // encoded channel specification
|
2003-07-07 22:34:18 +00:00
|
|
|
unsigned int unused[3];
|
|
|
|
} comedi_insn;
|
|
|
|
</programlisting>
|
|
|
|
Because of the large flexibility of the instruction function, many
|
|
|
|
types of instruction do not need to fill in all fields, or attach
|
|
|
|
different meanings to the same field. But the current implementation
|
2006-10-24 15:07:41 +00:00
|
|
|
of &comedi; requires the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-data">data</link></structfield>
|
|
|
|
field to be at least one byte long.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> member of the
|
2006-10-24 15:07:41 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
2003-07-07 22:34:18 +00:00
|
|
|
determines the type of acquisition executed in the corresponding
|
|
|
|
instruction:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_READ</constant>: the instruction executes a read on an
|
|
|
|
analog channel.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_WRITE</constant>: the instruction executes a write on an
|
|
|
|
analog channel.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2006-10-24 15:07:41 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_BITS</constant>: indicates that the instruction must
|
2003-07-07 22:34:18 +00:00
|
|
|
read or write values on multiple digital I/O channels.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_GTOD</constant>: the instruction performs a
|
|
|
|
<quote>Get Time Of Day</quote> acquisition.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_WAIT</constant>: the instruction blocks for a specified
|
|
|
|
number of nanoseconds.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="instructionexecution">
|
|
|
|
<title>
|
|
|
|
Instruction execution
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
Once an instruction data structure has been filled in, the
|
2012-05-01 15:42:07 +01:00
|
|
|
corresponding instruction is executed with the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-do-insn">comedi_do_insn</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_do_insn</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
|
|
|
<paramdef>comedi_insn *<parameter>instruction</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
Many &comedi; instructions are shortcuts that relieve the programmer
|
|
|
|
from explicitly filling in the data structure and calling the
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-do-insn">comedi_do_insn</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
function.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-02 15:47:59 +01:00
|
|
|
A list of instructions can be executed in one function call using the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-do-insnlist">comedi_do_insnlist</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_do_insnlist</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
|
|
|
<paramdef>comedi_insnlist *<parameter>list</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
The parameter <parameter class="function">list</parameter> is a pointer to a
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="insnlist-data-structure">comedi_insnlist</link></type>
|
2012-05-02 15:47:59 +01:00
|
|
|
data structure holding a pointer to an array of <type>comedi_insn</type>
|
|
|
|
and the number of instructions in the list:
|
|
|
|
<programlisting>
|
|
|
|
typedef struct <anchor id="insnlist-data-structure"/>comedi_insnlist_struct {
|
|
|
|
unsigned int n_insns;
|
|
|
|
comedi_insn *insns;
|
|
|
|
} comedi_insnlist;
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The number of instructions in the list is limited in the
|
2003-07-07 22:34:18 +00:00
|
|
|
implementation, because instructions are executed
|
|
|
|
<emphasis>synchronously</emphasis>, i.e., the call blocks until the
|
|
|
|
whole instruction (list) has finished.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
2006-10-24 15:07:41 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="instructionsconfiguration">
|
|
|
|
<title>
|
|
|
|
Instructions for configuration
|
|
|
|
</title>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<xref linkend="instructions"/> explains how instructions are used to do
|
2003-07-07 22:34:18 +00:00
|
|
|
<emphasis>acquisition</emphasis> on channels. This section explains
|
2006-10-25 19:57:49 +00:00
|
|
|
how they are used to <emphasis>configure</emphasis> a subdevice.
|
2003-07-07 22:34:18 +00:00
|
|
|
There are various sorts of configurations, and the
|
|
|
|
specific information for each different configuration possibility is
|
|
|
|
to be specified via the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-data">data</link></structfield>
|
|
|
|
buffer of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>.
|
|
|
|
(So, the pointer to a
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-lsampl-t">lsampl_t</link></type>
|
2003-07-07 22:34:18 +00:00
|
|
|
is misused as a pointer to an array with board-specific information.)
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
Using <constant>INSN_CONFIG</constant> as the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-insn">insn</link></structfield>
|
|
|
|
member in an
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
indicates that the instruction will
|
|
|
|
<emphasis>not perform acquisition</emphasis> on a
|
|
|
|
channel, but will <emphasis>configure</emphasis> that channel.
|
2006-10-25 19:57:49 +00:00
|
|
|
The
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="ref-macro-CR-PACK">chanspec</link></structfield>
|
|
|
|
member in the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="insn-data-structure-chanspec">comedi_insn</link></type>
|
2006-10-25 19:57:49 +00:00
|
|
|
data structure, contains the channel to be configured.
|
|
|
|
The zeroth element of the data array
|
|
|
|
is always an id that specifies
|
|
|
|
what type of configuration instruction is being performed. The
|
|
|
|
meaning of rest of the elements in the data array
|
|
|
|
depend on the configuration instruction id.
|
|
|
|
Some of the
|
|
|
|
possible ids are summarised in the table below, along with the
|
|
|
|
meanings of the data array elements for
|
|
|
|
each type of configuration instruction.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
2006-10-25 19:57:49 +00:00
|
|
|
<informaltable>
|
|
|
|
<tgroup cols='4' align='left'>
|
2012-04-25 18:34:54 +01:00
|
|
|
<colspec colwidth='4*' />
|
|
|
|
<colspec colwidth='4*' />
|
|
|
|
<colspec colwidth='1*' />
|
|
|
|
<colspec colwidth='4*' />
|
2006-10-25 19:57:49 +00:00
|
|
|
<thead>
|
|
|
|
<row>
|
|
|
|
<entry>data[0]</entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>n (number of elements in data array)</entry>
|
|
|
|
<entry>Meanings of data[1], ..., data[n-1]</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>INSN_CONFIG_DIO_INPUT</constant></entry>
|
2006-10-25 19:57:49 +00:00
|
|
|
<entry>
|
2012-05-02 15:47:59 +01:00
|
|
|
Configure a DIO line as input. It is easier to use
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-dio-config">comedi_dio_config</link></function>
|
2012-05-02 15:47:59 +01:00
|
|
|
than to use this configuration instruction directly.
|
2006-10-25 19:57:49 +00:00
|
|
|
</entry>
|
|
|
|
<entry>1</entry>
|
|
|
|
<entry>
|
|
|
|
n/a
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>INSN_CONFIG_DIO_OUTPUT</constant></entry>
|
2006-10-25 19:57:49 +00:00
|
|
|
<entry>
|
2012-05-02 15:47:59 +01:00
|
|
|
Configure a DIO line as output. It is easier to use
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-dio-config">comedi_dio_config</link></function>
|
2012-05-02 15:47:59 +01:00
|
|
|
than to use this configuration instruction directly.
|
2006-10-25 19:57:49 +00:00
|
|
|
</entry>
|
|
|
|
<entry>1</entry>
|
|
|
|
<entry>
|
|
|
|
n/a
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>INSN_CONFIG_ALT_SOURCE</constant></entry>
|
2006-10-25 19:57:49 +00:00
|
|
|
<entry>
|
2012-05-02 15:47:59 +01:00
|
|
|
Select an alternate input source. This instruction is used by calibration
|
|
|
|
programs to configure analog input channels
|
2006-10-25 19:57:49 +00:00
|
|
|
which can be redirected to read internal calibration
|
2012-05-02 15:47:59 +01:00
|
|
|
references. You need to set the <constant>CR_ALT_SOURCE</constant> flag in the chanspec
|
2006-10-25 19:57:49 +00:00
|
|
|
when reading to actually read from the configured alternate input source.
|
2012-05-03 19:56:59 +01:00
|
|
|
If you are using <function>comedi_data_read</function>, then the channel parameter can be
|
2012-05-02 15:47:59 +01:00
|
|
|
bitwise or'd with the <constant>CR_ALT_SOURCE</constant> flag.
|
2006-10-25 19:57:49 +00:00
|
|
|
</entry>
|
|
|
|
<entry>2</entry>
|
|
|
|
<entry>
|
|
|
|
data[1]: alternate input source.
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>INSN_CONFIG_BLOCK_SIZE</constant></entry>
|
2006-10-25 19:57:49 +00:00
|
|
|
<entry>
|
|
|
|
Specify block size for asynchonous command data.
|
|
|
|
When performing streaming input, many boards accumulate
|
|
|
|
samples in internal fifos and transfer them to the host
|
|
|
|
computer in chunks. Some drivers let you suggest a size in bytes for how big a
|
|
|
|
the chunks should be. This lets you tune how often the host computer is
|
|
|
|
interrupted with a new chunk of data.
|
|
|
|
</entry>
|
|
|
|
<entry>2</entry>
|
|
|
|
<entry>
|
|
|
|
data[1]: The desired block size in bytes. The actual configured block size is
|
|
|
|
writen back to data[1] after the instruction completes. This instruction
|
|
|
|
acts purely as a query if the block size is set to zero.
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>INSN_CONFIG_DIO_QUERY</constant></entry>
|
2006-10-25 19:57:49 +00:00
|
|
|
<entry>
|
2012-05-02 15:47:59 +01:00
|
|
|
Queries the configuration of a DIO line to see if it is an input or output.
|
|
|
|
It is probably easier to use the comedilib function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-dio-get-config">comedi_dio_get_config</link></function>
|
2006-10-25 19:57:49 +00:00
|
|
|
than to use this instruction directly.
|
|
|
|
</entry>
|
|
|
|
<entry>2</entry>
|
|
|
|
<entry>
|
2012-05-01 15:42:07 +01:00
|
|
|
data[1]: The instruction sets this element to either
|
|
|
|
<constant>COMEDI_INPUT</constant> or <constant>COMEDI_OUTPUT</constant>.
|
2006-10-25 19:57:49 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</informaltable>
|
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<para>
|
2012-05-02 15:47:59 +01:00
|
|
|
See the comedilib demo program <filename>demo/choose_clock.c</filename> for an example
|
2006-10-25 19:57:49 +00:00
|
|
|
of using a configuration instruction.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="inttrigconfiguration">
|
|
|
|
<title>
|
|
|
|
Instruction for internal triggering
|
|
|
|
</title>
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
This special instruction has
|
2012-05-01 15:42:07 +01:00
|
|
|
<anchor id="insn-inttrig"/><constant>INSN_INTTRIG</constant> as the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-insn">insn</link></structfield>
|
|
|
|
member in its
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>.
|
|
|
|
Its execution causes an
|
|
|
|
<link linkend="trig-int-start-src">internal triggering event</link>. This
|
|
|
|
event can, for example, cause the device driver to start a conversion,
|
|
|
|
or to stop an ongoing acquisition. The exact meaning of the triggering
|
|
|
|
depends on the card and its particular driver.
|
|
|
|
</para>
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
The
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-data">data</link></structfield>[0] element of the
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_INTTRIG</constant> instruction is reserved for future use,
|
|
|
|
and should be set to <literal>0</literal>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="commandsstreaming">
|
|
|
|
<title>
|
|
|
|
Commands for streaming acquisition
|
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The most powerful &comedi; acquisition primitive is the
|
|
|
|
<emphasis>command</emphasis>. It's powerful because, with one single
|
|
|
|
command, the programmer launches:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
a possibly infinite <emphasis>sequence of acquisitions</emphasis>,
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
accompanied with various <emphasis>callback</emphasis> functionalities
|
2006-10-24 15:07:41 +00:00
|
|
|
(DMA, interrupts, driver-specific callback functions),
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
for <emphasis>any number of channels</emphasis>,
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
with an <emphasis>arbitrary order</emphasis> of channels in each scan
|
2006-10-24 15:07:41 +00:00
|
|
|
(possibly even with repeated channels per scan),
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
and with various scan <emphasis>triggering sources</emphasis>,
|
|
|
|
external (i.e., hardware pulses) as well as internal (i.e., pulses
|
2006-10-24 15:07:41 +00:00
|
|
|
generated on the DAQ card itself, or generated by a
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="inttrigconfiguration">software trigger instruction</link>).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
This command functionality exists in the &comedi; API, because various
|
|
|
|
data acquisition devices have the capability to perform this kind of
|
|
|
|
complex acquisition, driven by either on-board or
|
|
|
|
off-board timers and triggers.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
A command specifies a particular data
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="fig-acq-seq">acquisition sequence</link>, which
|
|
|
|
consists of a number of <emphasis>scans</emphasis>, and each scan is
|
|
|
|
comprised of a number of <emphasis>conversions</emphasis>, which
|
|
|
|
usually corresponds to a single A/D or D/A conversion. So, for
|
|
|
|
example, a scan could consist of sampling channels 1, 2 and 3 of a
|
|
|
|
particular device, and this scan should be repeated 1000 times, at
|
|
|
|
intervals of 1 millisecond apart.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The command function is complementary to the
|
|
|
|
<link linkend="instructionsconfiguration">configuration instruction</link>
|
2006-10-24 15:07:41 +00:00
|
|
|
function: each channel in the command's
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-chanlist">chanlist</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
should first be configured by an appropriate instruction.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="executingcommand">
|
|
|
|
<title>
|
|
|
|
Executing a command
|
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
2012-05-02 15:47:59 +01:00
|
|
|
A command is executed by the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-command">comedi_command</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_command</function></funcdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
|
|
|
<paramdef>comedi_cmd *<parameter>command</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
The following sections explain the meaning of the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type> data structure.
|
2003-07-07 22:34:18 +00:00
|
|
|
Filling in this structure can be quite complicated, and
|
|
|
|
requires good knowledge about the exact functionalities of the DAQ
|
|
|
|
card. So, before launching a command, the application programmer is
|
|
|
|
adviced to check whether this complex command data structure can be
|
|
|
|
successfully parsed. So, the typical sequence for executing a command is
|
|
|
|
to first send the command through
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-command-test">comedi_command_test</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
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.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
A &comedi; program can find out on-line what the command capabilities
|
|
|
|
of a specific device are, by means of the
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-get-cmd-src-mask">comedi_get_cmd_src_mask</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
function.
|
|
|
|
</para>
|
2006-10-24 15:07:41 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="comedicmdstructure">
|
|
|
|
<title>
|
|
|
|
The command data structure
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
The command executes according to the information about the requested
|
|
|
|
acquisition, which is stored in the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="command-data-struct"/>data structure:
|
2003-07-07 22:34:18 +00:00
|
|
|
<programlisting>
|
|
|
|
typedef struct comedi_cmd_struct comedi_cmd;
|
|
|
|
|
2012-05-01 12:51:08 +01:00
|
|
|
struct comedi_cmd_struct {
|
2003-07-07 22:34:18 +00:00
|
|
|
unsigned int subdev; // which subdevice to sample
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-flags"/>flags; // encode some configuration possibilities
|
2003-07-07 22:34:18 +00:00
|
|
|
// of the command execution; e.g.,
|
|
|
|
// whether a callback routine is to be
|
|
|
|
// called at the end of the command
|
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-start-src"/>start_src; // event to make the acquisition start
|
|
|
|
unsigned int <anchor id="command-data-struct-start-arg"/>start_arg; // parameters that influence this start
|
2003-07-07 22:34:18 +00:00
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-scan-begin-src"/>scan_begin_src; // event to make a particular scan start
|
|
|
|
unsigned int <anchor id="command-data-struct-scan-begin-arg"/>scan_begin_arg; // parameters that influence this start`
|
2003-07-07 22:34:18 +00:00
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-convert-src"/>convert_src; // event to make a particular conversion start
|
|
|
|
unsigned int <anchor id="command-data-struct-convert-arg"/>convert_arg; // parameters that influence this start
|
2003-07-07 22:34:18 +00:00
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-scan-end-src"/>scan_end_src; // event to make a particular scan terminate
|
|
|
|
unsigned int <anchor id="command-data-struct-scan-end-arg"/>scan_end_arg; // parameters that influence this termination
|
2003-07-07 22:34:18 +00:00
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-stop-src"/>stop_src; // what make the acquisition terminate
|
|
|
|
unsigned int <anchor id="command-data-struct-stop-arg"/>stop_arg; // parameters that influence this termination
|
2003-07-07 22:34:18 +00:00
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
unsigned int <anchor id="command-data-struct-chanlist"/>*chanlist; // pointer to list of channels to be sampled
|
|
|
|
unsigned int <anchor id="command-data-struct-chanlist-len"/>chanlist_len; // number of channels to be sampled
|
2003-07-07 22:34:18 +00:00
|
|
|
|
2008-01-24 01:32:41 +00:00
|
|
|
sampl_t *<anchor id="command-data-struct-data"/>data; // address of buffer
|
|
|
|
unsigned int <anchor id="command-data-struct-data-len"/>data_len; // number of samples to acquire
|
2003-07-07 22:34:18 +00:00
|
|
|
};
|
|
|
|
</programlisting>
|
|
|
|
The start and end of the whole command acquisition sequence, and the
|
|
|
|
start and end of each scan and of each conversion, is triggered by a
|
|
|
|
so-called <emphasis>event</emphasis>. More on these in
|
2008-01-24 01:32:41 +00:00
|
|
|
<xref linkend="comedicmdsources"/>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
The <parameter class="function">subdev</parameter> member of the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type> structure is
|
2003-07-07 22:34:18 +00:00
|
|
|
the index of the subdevice the command is intended for. The
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-find-subdevice-by-type">comedi_find_subdevice_by_type</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
function can be useful in discovering the index of your desired subdevice.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="command-data-struct-chanlist">chanlist</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
member of the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type> data
|
2003-07-07 22:34:18 +00:00
|
|
|
structure should point to an array whose number of elements is
|
2012-05-03 19:56:59 +01:00
|
|
|
specified by
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-chanlist-len">chanlist_len</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
(this will generally be the same as the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-end-arg">scan_end_arg</link></structfield>).
|
2003-07-07 22:34:18 +00:00
|
|
|
The
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-chanlist">chanlist</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
specifies the sequence of channels and gains (and analog references)
|
|
|
|
that should be stepped through for each scan. The elements of the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-chanlist">chanlist</link></structfield> array should be
|
2003-07-11 22:53:40 +00:00
|
|
|
initialized by <quote>packing</quote> the channel, range and reference
|
2003-07-07 22:34:18 +00:00
|
|
|
information together with the
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="ref-macro-CR-PACK">CR_PACK</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
macro.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="command-data-struct-data">data</link></structfield> and
|
|
|
|
<structfield><link linkend="command-data-struct-data-len">data_len</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
members can be safely ignored when issueing commands from a user-space
|
|
|
|
program. They only have meaning when a command is sent from a
|
|
|
|
<emphasis role="strong">kernel</emphasis> module using the
|
2012-05-01 15:42:07 +01:00
|
|
|
<systemitem>kcomedilib</systemitem> interface, in which case they specify
|
2003-07-07 22:34:18 +00:00
|
|
|
the buffer where the driver should write/read its data to/from.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The final member of the
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="command-data-struct">comedi_cmd</link></type> structure is the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-flags">flags</link></structfield> field,
|
2003-07-07 22:34:18 +00:00
|
|
|
i.e., bits in a word that can be bitwise-or'd together. The meaning of
|
2012-05-08 13:58:27 +01:00
|
|
|
these bits are explained in
|
|
|
|
<xref linkend="comedicmdflags"/>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="comedicmdsources">
|
|
|
|
<title>
|
|
|
|
The command trigger events
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="source.trigger.anchor"/>
|
2003-07-07 22:34:18 +00:00
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
A command is a very versatile acquisition instruction, in the sense
|
|
|
|
that it offers lots of possibilities to let different hardware and
|
|
|
|
software sources determine when acquisitions are started, performed,
|
|
|
|
and stopped. More specifically, the command
|
|
|
|
<link linkend="command-data-struct">data structure</link>
|
2006-10-24 15:07:41 +00:00
|
|
|
has <emphasis>five</emphasis> types of events: start the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="acquisitionterminology">acquisition</link>,
|
2006-10-24 15:07:41 +00:00
|
|
|
start a <link linkend="scan">scan</link>, start a
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="conversion">conversion</link>, stop a scan, and stop
|
|
|
|
the acquisition. Each event can be given its own
|
|
|
|
<emphasis><link linkend="source.trigger.anchor">source</link></emphasis>
|
2012-05-03 19:56:59 +01:00
|
|
|
(the <parameter class="function">…_src</parameter> members in the
|
|
|
|
<type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type> data
|
2003-07-07 22:34:18 +00:00
|
|
|
structure). And each event source can have a corresponding
|
2012-05-03 19:56:59 +01:00
|
|
|
argument (the <parameter class="function">…_arg</parameter> members of
|
|
|
|
the <type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type> data
|
2006-10-24 15:07:41 +00:00
|
|
|
structure) whose meaning depends on the type of source trigger.
|
2003-07-11 22:53:40 +00:00
|
|
|
For example, to specify an external digital line <quote>3</quote> as a
|
2003-07-07 22:34:18 +00:00
|
|
|
source (in general, <emphasis>any</emphasis> of the five event
|
|
|
|
sources), you would use
|
2012-05-03 19:56:59 +01:00
|
|
|
<parameter>src</parameter>=<constant><link linkend="trig-ext">TRIG_EXT</link></constant>
|
2012-05-01 15:42:07 +01:00
|
|
|
and <parameter>arg</parameter>=<literal>3</literal>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The following paragraphs discuss in somewhat more detail the trigger
|
2012-05-03 19:56:59 +01:00
|
|
|
event sources(<parameter class="function">…_src</parameter>), and the
|
|
|
|
corresponding arguments (<parameter class="function">…_arg</parameter>).
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The start of an acquisition is controlled by the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-start-src">start_src</link></structfield> events.
|
2003-07-07 22:34:18 +00:00
|
|
|
The available options are:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-now-start-src"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_NOW</constant>: the <quote>start</quote> event occurs
|
|
|
|
<structfield><link linkend="command-data-struct-start-arg">start_arg</link></structfield>
|
2012-05-02 15:47:59 +01:00
|
|
|
nanoseconds after the command is set up. Currently, only
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-start-arg">start_arg</link></structfield>=<literal>0</literal> is
|
2003-07-07 22:34:18 +00:00
|
|
|
supported.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-follow-start-src"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_FOLLOW</constant>: (For an output device.) The <quote>start</quote>
|
2003-07-07 22:34:18 +00:00
|
|
|
event occurs when data is written to the buffer.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-ext-start-src"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_EXT</constant>: the <quote>start</quote> event occurs when an
|
2012-05-01 15:42:07 +01:00
|
|
|
external trigger signal occurs; e.g., a rising edge of a digital line.
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-start-arg">start_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
chooses the particular digital line.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-int-start-src"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_INT</constant>: the <quote>start</quote> event occurs on a &comedi;
|
2012-05-01 15:42:07 +01:00
|
|
|
internal signal, which is typically caused by an
|
2012-05-03 19:56:59 +01:00
|
|
|
<constant><link linkend="insn-inttrig">INSN_INTTRIG</link></constant>
|
|
|
|
instruction.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
The start of the beginning of each
|
|
|
|
<link linkend="scan">scan</link> is controlled by the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-src">scan_begin_src</link></structfield> events.
|
2003-07-07 22:34:18 +00:00
|
|
|
The available options are:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-timer-start-scan"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_TIMER</constant>: <quote>scan begin</quote>
|
|
|
|
events occur periodically. The time between <quote>scan begin</quote>
|
2003-07-07 22:34:18 +00:00
|
|
|
events is
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-arg">scan_begin_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
nanoseconds.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-follow-start-scan"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_FOLLOW</constant>: The <quote>scan begin</quote>
|
|
|
|
event occurs immediately after a <quote>scan end</quote>
|
2003-07-07 22:34:18 +00:00
|
|
|
event occurs.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-ext-start-scan"/>
|
2012-05-08 13:58:27 +01:00
|
|
|
<constant>TRIG_EXT</constant>: the <quote>scan begin</quote>
|
2003-07-07 22:34:18 +00:00
|
|
|
event occurs when an external trigger signal
|
2006-10-24 15:07:41 +00:00
|
|
|
occurs; e.g., a rising edge of a digital line.
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-arg">scan_begin_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
chooses the particular digital line.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
2006-10-24 15:07:41 +00:00
|
|
|
The
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-arg">scan_begin_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
used here may not be supported exactly by the device, but it
|
2006-10-24 15:07:41 +00:00
|
|
|
will be adjusted to the nearest supported value by
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-command-test">comedi_command_test</link></function>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
The timing between each sample in a
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="scan">scan</link> is controlled by the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-convert-src">convert_src</link></structfield>
|
|
|
|
events.
|
|
|
|
The available options are:
|
2003-07-07 22:34:18 +00:00
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="convert-trig-timer"/>
|
|
|
|
<anchor id="trig-timer"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_TIMER</constant>: the conversion events occur periodically.
|
2012-05-08 13:58:27 +01:00
|
|
|
The time between <quote>convert</quote> events is
|
|
|
|
<structfield><link linkend="command-data-struct-convert-arg">convert_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
nanoseconds.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="convert-trig-ext"/>
|
|
|
|
<anchor id="trig-ext"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_EXT</constant>: the conversion events occur when an
|
|
|
|
external trigger signal occurs, e.g., a rising edge of a digital line.
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-convert-arg">convert_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
chooses the particular digital line.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="convert-trig-now"/>
|
|
|
|
<anchor id="trig-now"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_NOW</constant>: All conversion events in a
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="scan">scan</link> occur simultaneously.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
The <emphasis>end</emphasis> of each scan is almost always specified
|
2012-05-08 13:58:27 +01:00
|
|
|
by setting the
|
|
|
|
<structfield><link linkend="command-data-struct-scan-end-src">scan_end_src</link></structfield>
|
|
|
|
event to
|
2012-05-03 19:56:59 +01:00
|
|
|
<constant><link linkend="trig-count">TRIG_COUNT</link></constant>,
|
2012-05-01 15:42:07 +01:00
|
|
|
with the argument being the same as the number of channels in the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-chanlist">chanlist</link></structfield>. You
|
2003-07-07 22:34:18 +00:00
|
|
|
could probably find a device that allows something else, but it would
|
2006-10-24 15:07:41 +00:00
|
|
|
be strange.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The end of an
|
|
|
|
<link linkend="acquisitionterminology">acquisition</link> is
|
|
|
|
controlled by
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-stop-src">stop_src</link></structfield> event.
|
|
|
|
The available options are:
|
2003-07-07 22:34:18 +00:00
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="acquisition-end-trig-count"/>
|
|
|
|
<anchor id="trig-count"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_COUNT</constant>: stop the acquisition after
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-stop-arg">stop_arg</link></structfield>
|
2003-07-07 22:34:18 +00:00
|
|
|
scans.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="acquisition-end-trig-none"/>
|
|
|
|
<anchor id="trig-none"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_NONE</constant>: perform continuous acquisition,
|
|
|
|
until stopped using
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-cancel">comedi_cancel</link></function>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
2016-03-08 22:47:52 -07:00
|
|
|
<structfield>stop_arg</structfield> is used to denote how many samples should be
|
|
|
|
used in the continuous acquisition. If <structfield>stop_arg</structfield> is
|
|
|
|
set to <literal>0</literal>, the entire output buffer may contribute to the
|
|
|
|
output. If <structfield>stop_arg</structfield> != <literal>0</literal>, only
|
|
|
|
the memory for <structfield>stop_arg</structfield> samples will be used. Many
|
|
|
|
drivers do not yet support
|
|
|
|
<structfield>stop_arg</structfield>!=<literal>0</literal> and should enforce
|
|
|
|
<structfield>stop_arg</structfield>=<literal>0</literal> via
|
|
|
|
comedi_command_test.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
There are a couple of less usual or not yet implemented events:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-time"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_TIME</constant>:
|
2003-07-07 22:34:18 +00:00
|
|
|
cause an event to occur at a particular time.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
(This event source is reserved for future use.)
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trigother-event"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_OTHER</constant>: driver specific event trigger.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
This event can be useful as any of the trigger sources. Its exact
|
|
|
|
meaning is driver specific, because it implements a feature that
|
|
|
|
otherwise does not fit into the generic &comedi; command interface.
|
2012-05-01 15:42:07 +01:00
|
|
|
Configuration of <constant>TRIG_OTHER</constant> features are done by
|
2012-05-03 19:56:59 +01:00
|
|
|
<constant><link linkend="instructionsconfiguration">INSN_CONFIG</link></constant>
|
2003-07-07 22:34:18 +00:00
|
|
|
instructions.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
The argument is reserved and should be set to <literal>0</literal>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
Not all event sources are applicable to all events. Supported
|
|
|
|
trigger sources for specific events depend significantly on your
|
|
|
|
particular device, and even more on the current state of its device
|
2006-10-24 15:07:41 +00:00
|
|
|
driver. The
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-get-cmd-src-mask">comedi_get_cmd_src_mask</link></function>
|
2003-07-07 22:34:18 +00:00
|
|
|
function is useful for determining what trigger sources a subdevice
|
|
|
|
supports.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="comedicmdflags">
|
|
|
|
<title>
|
|
|
|
The command flags
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="source.flags.anchor"/>
|
2003-07-07 22:34:18 +00:00
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-flags">flags</link></structfield>
|
|
|
|
field in the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="ref-type-comedi-cmd">command data structure</link>
|
2003-07-11 22:53:40 +00:00
|
|
|
is used to specify some <quote>behaviour</quote> of the acquisitions in
|
2003-07-07 22:34:18 +00:00
|
|
|
a command.
|
|
|
|
The meaning of the field is as follows:
|
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-rt"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_RT</constant>: ask the driver to use a
|
2003-07-07 22:34:18 +00:00
|
|
|
<emphasis role="strong">hard real-time</emphasis> 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 data buffer. You must have a
|
|
|
|
real-time kernel (<ulink url="http://www.rtai.org">RTAI</ulink> or
|
2004-12-02 07:59:00 +00:00
|
|
|
<ulink url="http://www.rtlinux-gpl.org/">RTLinux/GPL</ulink>)
|
2003-07-07 22:34:18 +00:00
|
|
|
and must compile &comedi; with real-time support, or this flag will do
|
|
|
|
nothing.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-wake-eos"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_WAKE_EOS</constant>:
|
2003-07-11 22:53:40 +00:00
|
|
|
where <quote>EOS</quote> stands for <quote>End of Scan</quote>. Some
|
2003-07-07 22:34:18 +00:00
|
|
|
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
|
|
|
|
half full). This flag may degrade a driver's performance at high
|
|
|
|
frequencies, because the end of a scan is, in general, a much more
|
|
|
|
frequent event than the filling up of the data buffer.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-round-nearest"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_ROUND_NEAREST</constant>:
|
2003-07-07 22:34:18 +00:00
|
|
|
round to nearest supported timing period, the default.
|
|
|
|
This flag (as well as the following three), indicates how timing
|
|
|
|
arguments should be rounded if the hardware cannot achieve the exact
|
|
|
|
timing requested.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-round-down"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_ROUND_DOWN</constant>: round period down.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-round-up"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_ROUND_UP</constant>: round period up.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-round-up-next"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_ROUND_UP_NEXT</constant>:
|
2003-07-07 22:34:18 +00:00
|
|
|
this one doesn't do anything, and I don't know what it was intended
|
|
|
|
to do…?
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-dither"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_DITHER</constant>: enable dithering? Dithering is
|
|
|
|
a software technique to smooth the influence of discretization
|
|
|
|
<quote>noise</quote>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-deglitch"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_DEGLITCH</constant>: enable deglitching?
|
|
|
|
Another <quote>noise</quote> smoothing technique.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-write"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_WRITE</constant>:
|
2003-07-07 22:34:18 +00:00
|
|
|
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.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-bogus"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_BOGUS</constant>: do the motions?
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2008-01-24 01:32:41 +00:00
|
|
|
<anchor id="trig-other"/>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>TRIG_CONFIG</constant>: perform configuration, not triggering.
|
|
|
|
This is a legacy of the deprecated
|
2012-05-03 19:56:59 +01:00
|
|
|
<type><link linkend="ref-type-comedi-trig">comedi_trig_struct</link></type>
|
2003-07-07 22:34:18 +00:00
|
|
|
data structure, and has no function at present.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
2003-07-08 23:51:29 +00:00
|
|
|
<section>
|
|
|
|
<title>
|
|
|
|
Anti-aliasing
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
If you wish to aquire accurate waveforms, it is vital that you use an
|
|
|
|
anti-alias filter. An anti-alias filter is a low-pass filter used to
|
|
|
|
remove all frequencies higher than the Nyquist frequency (half your sampling rate)
|
|
|
|
from your analog input signal
|
|
|
|
before you convert it to digital. If you fail to filter your input signal,
|
|
|
|
any high frequency components in the original analog signal will create
|
|
|
|
artifacts in your recorded digital waveform that cannot be corrected.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
For example, suppose you are sampling an analog input channel at a rate of
|
|
|
|
1000 Hz. If you were to apply a 900 Hz sine wave to the input, you
|
|
|
|
would find that your
|
|
|
|
sampling rate is not high enough to faithfully record the 900 Hz input,
|
|
|
|
since it is above your Nyquist frequency of 500 Hz. Instead, what you
|
|
|
|
will see in your recorded digital waveform is a 100 Hz sine wave! If you
|
|
|
|
don't use an anti-alias filter, it is impossible to tell whether the 100
|
|
|
|
Hz sine wave you see in your digital signal was really produced by a
|
|
|
|
100 Hz input signal, or a 900 Hz signal aliased to 100 Hz, or a 1100 Hz
|
|
|
|
signal, etc.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
In practice, the cutoff frequency for the anti-alias filter is usually
|
|
|
|
set 10% to 20% below the Nyquist frequency due to fact that real filters
|
|
|
|
do not have infinitely sharp cutoffs.
|
|
|
|
</para>
|
|
|
|
</section>
|
2003-07-07 22:34:18 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="slowlyvarying">
|
2002-01-21 15:17:12 +00:00
|
|
|
<title>
|
2003-07-07 22:34:18 +00:00
|
|
|
Slowly-varying inputs
|
2002-01-21 15:17:12 +00:00
|
|
|
</title>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2012-05-04 18:45:33 +01:00
|
|
|
<para>
|
|
|
|
<emphasis role="strong">Note: The functions described here use an old
|
|
|
|
feature that is no longer implemented by the &comedi;
|
|
|
|
kernel layer. THEY WILL NOT WORK!</emphasis>
|
|
|
|
</para>
|
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Sometimes, your input channels change slowly enough that
|
|
|
|
you are able to average many successive input values to get a
|
|
|
|
more accurate measurement of the actual value. In general,
|
|
|
|
the more samples you average, the better your estimate
|
2012-05-09 17:40:34 +01:00
|
|
|
gets, roughly by a factor of
|
|
|
|
<function>sqrt<parameter>number_of_samples</parameter></function>.
|
2003-07-07 22:34:18 +00:00
|
|
|
Obviously, there are limitations to this:
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<itemizedlist>
|
|
|
|
|
|
|
|
<listitem>
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-11 22:53:40 +00:00
|
|
|
you are ultimately limited by <quote>Spurious Free Dynamic
|
|
|
|
Range</quote>. This SFDR is one of the popular measures to quantify how
|
2003-07-07 22:34:18 +00:00
|
|
|
much noise a signal carries. If you take a Fourier transform of your
|
2003-07-11 22:53:40 +00:00
|
|
|
signal, you will see several <quote>peaks</quote> in the transform: one
|
2003-07-07 22:34:18 +00:00
|
|
|
or more of the fundamental harmonics of the measured signal, and lots
|
2003-07-11 22:53:40 +00:00
|
|
|
of little <quote>peaks</quote> (called <quote>spurs</quote>) caused by
|
2003-07-07 22:34:18 +00:00
|
|
|
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!).
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2003-07-07 22:34:18 +00:00
|
|
|
</listitem>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<listitem>
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
you need to have <emphasis>some</emphasis> noise on the input channel,
|
|
|
|
otherwise you will be averaging the same number <literal>N</literal>
|
|
|
|
times. (Of course, this only holds if the noise is large enough to
|
|
|
|
cause at least a one-bit discretization.)
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2003-07-07 22:34:18 +00:00
|
|
|
</listitem>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
the more noise you have, the greater your SFDR, but it
|
|
|
|
takes many more samples to compensate for the increased
|
|
|
|
noise.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<listitem>
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
if you feel the need to average samples for, for example, two seconds,
|
|
|
|
your signal will need to be <emphasis>very</emphasis> slowly-varying,
|
|
|
|
i.e., not varying more than your target uncertainty for the entire two
|
|
|
|
seconds.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2003-07-07 22:34:18 +00:00
|
|
|
</listitem>
|
|
|
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
As you might have guessed, the &comedi; library has functions
|
|
|
|
to help you in your quest to accurately measure slowly varying
|
|
|
|
inputs:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_sv_init</function></funcdef>
|
|
|
|
<paramdef>comedi_sv_t *<parameter>sv</parameter></paramdef>
|
|
|
|
<paramdef>comedi_t *<parameter>device</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
|
|
|
|
<paramdef>unsigned int <parameter>channel</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-03 19:56:59 +01:00
|
|
|
The above function <function><link linkend="func-ref-comedi-sv-init">comedi_sv_init</link></function> initializes the
|
|
|
|
<type><link linkend="ref-type-comedi-sv-t">comedi_sv_t</link></type> data structure, used
|
2003-07-07 22:34:18 +00:00
|
|
|
to do the averaging acquisition:
|
|
|
|
<programlisting>
|
2012-05-02 15:47:59 +01:00
|
|
|
typedef struct comedi_sv_struct {
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="ref-type-comedi-t">comedi_t</link> *dev;
|
|
|
|
unsigned int subdevice;
|
|
|
|
unsigned int chan;
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
/* range policy */
|
|
|
|
int range;
|
|
|
|
int aref;
|
|
|
|
|
|
|
|
/* number of measurements to average (for analog inputs) */
|
|
|
|
int n;
|
|
|
|
|
|
|
|
lsampl_t maxdata;
|
2012-05-02 15:47:59 +01:00
|
|
|
} comedi_sv_t;
|
2003-07-07 22:34:18 +00:00
|
|
|
</programlisting>
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
The actual acquisition is done with the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function><link linkend="func-ref-comedi-sv-measure">comedi_sv_measure</link></function>:
|
2012-05-01 15:42:07 +01:00
|
|
|
|
|
|
|
<funcsynopsis><funcprototype>
|
2012-05-02 15:47:59 +01:00
|
|
|
<funcdef>int <function>comedi_sv_measure</function></funcdef>
|
|
|
|
<paramdef>comedi_sv_t *<parameter>sv</parameter></paramdef>
|
2012-05-01 15:42:07 +01:00
|
|
|
<paramdef>double *<parameter>data</parameter></paramdef>
|
|
|
|
</funcprototype></funcsynopsis>
|
|
|
|
|
2012-05-02 15:47:59 +01:00
|
|
|
The number of samples over which the function
|
2012-05-03 19:56:59 +01:00
|
|
|
<function>comedi_sv_measure</function> averages is limited by the
|
2006-10-24 15:07:41 +00:00
|
|
|
implementation (currently the limit is 100 samples).
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
One typical use for this function is the measurement of thermocouple
|
|
|
|
voltages.
|
|
|
|
And 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 a part-per-thousand.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section id="experimentalfunctionality">
|
|
|
|
<title>
|
|
|
|
Experimental functionality
|
|
|
|
</title>
|
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
The following subsections document functionality that has not yet
|
|
|
|
matured. Most of this functionality has even not been implemented yet
|
|
|
|
in any single device driver. This information is included here, in
|
|
|
|
order to stimulate discussion about their API, and to encourage
|
|
|
|
pioneering implementations.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<section id="digitalinputcombining">
|
|
|
|
<title>
|
|
|
|
Digital input combining machines
|
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
(<emphasis role="strong">Status: experimental (i.e., no driver implements
|
|
|
|
this yet)</emphasis>)
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
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.
|
2003-07-11 22:53:40 +00:00
|
|
|
The digital inputs have two properties, <quote>sensitive</quote> inputs
|
|
|
|
and <quote>modifier</quote> inputs. Edge transitions on sensitive
|
2003-07-07 22:34:18 +00:00
|
|
|
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.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
For simplification purposes, it is assumed that multiple digital
|
|
|
|
inputs do not change simultaneously.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The combined state of the modifier inputs determine a modifier
|
|
|
|
state. For each combination of modifier state and sensitive
|
|
|
|
input, there is a set of bits that determine the effect on the
|
|
|
|
output value due to positive or negative transitions of the
|
|
|
|
sensitive input. For each transition direction, there are two
|
|
|
|
bits defined as follows:
|
|
|
|
|
2012-05-01 11:48:46 +01:00
|
|
|
<variablelist spacing="compact">
|
|
|
|
<varlistentry>
|
|
|
|
<term>00</term>
|
|
|
|
<listitem>transition is ignored.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>01</term>
|
|
|
|
<listitem>accumulator is incremented, or output is set.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>10</term>
|
|
|
|
<listitem>accumulator is decremented, or output is cleared.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>11</term>
|
|
|
|
<listitem>reserved.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
2003-07-07 22:34:18 +00:00
|
|
|
|
|
|
|
For example, a simple digital follower is specified by the bit
|
|
|
|
pattern 01 10, because it sets the output on positive transitions
|
|
|
|
of the input, and clears the output on negative transitions. A
|
|
|
|
digital inverter is similarily 10 01. These systems have only
|
|
|
|
one sensitive input.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
As another example, a simple up counter, which increments on
|
|
|
|
positive transitions of one input, is specified by 01 00. This
|
|
|
|
system has only one sensitive input.
|
|
|
|
</para>
|
2002-01-21 15:17:12 +00:00
|
|
|
|
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
When multiple digital inputs are used, the inputs are divided
|
|
|
|
into two types, inputs which cause changes in the accumulator, and
|
|
|
|
those that only modify the meaning of transitions on other inputs.
|
|
|
|
Modifier inputs do not require bitfields, but there needs to be
|
|
|
|
a bitfield of length 4*(2^(N-1)) for each edge sensitive input,
|
|
|
|
where N is the total number of inputs. Since N is usually 2 or
|
|
|
|
3, with only one edge sensitive input, the scaling issues are
|
|
|
|
not significant.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
</section>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
|
|
|
|
<section id="analogconversion">
|
2002-01-21 15:17:12 +00:00
|
|
|
<title>
|
2003-07-07 22:34:18 +00:00
|
|
|
Analog filtering configuration
|
2002-01-21 15:17:12 +00:00
|
|
|
</title>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
<emphasis role="strong">(Status: design (i.e., no driver implements
|
|
|
|
this yet).)</emphasis>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield>
|
|
|
|
field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is ignored.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Some devices have the capability to add white noise (dithering) to
|
|
|
|
analog input measurement. This additional noise can then be averaged
|
|
|
|
out, to get a more accurate measurement of the input signal. It
|
|
|
|
should not be assumed that channels can be separately configured.
|
|
|
|
A simple design can use 1 bit to turn this feature on/off.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Some devices have the capability of changing the glitch characteristics
|
|
|
|
of analog output subsytems. The default (off) case should be where
|
|
|
|
the average settling time is lowest. A simple design can use 1 bit
|
|
|
|
to turn this feature on/off.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Some devices have a configurable analog filters as part of the analog
|
|
|
|
input stage. A simple design can use 1 bit to enable/disable the
|
|
|
|
filter. Default is disabled, i.e., the filter being bypassed, or if
|
|
|
|
the choice is between two filters, the filter with the largest
|
|
|
|
bandwidth.
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section id="waveformgeneration">
|
|
|
|
<title>
|
|
|
|
Analog Output Waveform Generation
|
|
|
|
</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
<emphasis role="strong">(Status: design (i.e., no driver implements
|
|
|
|
this yet).)</emphasis>
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is ignored.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Some devices have the ability to cyclicly loop through samples kept in
|
|
|
|
an on-board analog output FIFO. This config should allow the user to
|
|
|
|
enable/disable this mode.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This config should allow the user to configure the number of samples
|
|
|
|
to loop through. It may be necessary to configure the channels used.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section id="extendedtriggering">
|
|
|
|
<title>
|
|
|
|
Extended Triggering
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
<emphasis role="strong">(Status: alpha.)</emphasis>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is ignored.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This section covers common information for all extended
|
|
|
|
triggering configuration, and doesn't describe a particular
|
|
|
|
type of extended trigger.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Extended triggering is used to configure triggering engines that
|
|
|
|
do not fit into commands. In a typical programming sequence, the
|
|
|
|
application will use
|
|
|
|
<link linkend="instructionsconfiguration">configuration instructions</link>
|
|
|
|
to configure an extended trigger, and a
|
|
|
|
<link linkend="commandsstreaming">command</link>,
|
2006-10-24 15:07:41 +00:00
|
|
|
specifying
|
2012-05-03 19:56:59 +01:00
|
|
|
<constant><link linkend="trig-other">TRIG_OTHER</link></constant>
|
2012-05-01 15:42:07 +01:00
|
|
|
as one of the trigger sources.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Extended trigger configuration should be designed in such a way
|
|
|
|
that the user can probe for valid parameters, similar to how
|
|
|
|
command testing works. An extended trigger configuration instruction
|
|
|
|
should not configure the hardware directly, rather, the configuration
|
|
|
|
should be saved until the subsequent command is issued. This
|
|
|
|
allows more flexibility for future interface changes.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
It has not been decided whether the configuration stage should return a
|
|
|
|
token that is then used as the trigger argument in the command.
|
|
|
|
Using tokens is one method to satisfy the problem that extended
|
|
|
|
trigger configurations may have subtle compatiblity issues with
|
|
|
|
other trigger sources/arguments that can only be determined at
|
|
|
|
command test time. Passing all stages of a command test should
|
|
|
|
only be allowed with a properly configured extended trigger.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
Extended triggers must use
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-data">data</link></structfield>[1] as flags. The
|
2003-07-07 22:34:18 +00:00
|
|
|
upper 16 bits are reserved and used only for flags that are common to
|
|
|
|
all extended triggers. The lower 16 bits may be defined by the
|
|
|
|
particular type of extended trigger.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
Various types of extended triggers must use
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="insn-data-structure-data">data</link></structfield>[1] to know which
|
2003-07-07 22:34:18 +00:00
|
|
|
event the extended trigger will be assigned to in the command
|
|
|
|
structure. The possible values are an OR'd mask of the following:
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>COMEDI_EV_START</constant>
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>COMEDI_EV_SCAN_BEGIN</constant>
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>COMEDI_EV_CONVERT</constant>
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>COMEDI_EV_SCAN_END</constant>
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>COMEDI_EV_STOP</constant>
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section id="analogtriggering">
|
|
|
|
<title>
|
|
|
|
Analog Triggering
|
|
|
|
</title>
|
|
|
|
<para>
|
|
|
|
<emphasis role="strong">
|
2012-05-03 19:56:59 +01:00
|
|
|
(Status: alpha. The <filename>ni_mio_common.c</filename> driver
|
2003-07-07 22:34:18 +00:00
|
|
|
implements this feature.)
|
|
|
|
</emphasis>
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is ignored.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-data">data</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is used as follows:
|
2012-05-01 11:48:46 +01:00
|
|
|
<variablelist spacing="compact">
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[1]</term>
|
|
|
|
<listitem>trigger and combining machine configuration.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[2]</term>
|
|
|
|
<listitem>analog triggering signal chanspec.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[3]</term>
|
|
|
|
<listitem>primary analog level.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[4]</term>
|
|
|
|
<listitem>secondary analog level.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
2003-12-21 18:07:42 +00:00
|
|
|
</para>
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Analog triggering is described by a digital combining machine that
|
|
|
|
has two sensitive digital inputs. The sensitive digital inputs are
|
|
|
|
generated by configurable analog comparators. The analog comparators
|
|
|
|
generate a digital 1 when the analog triggering signal is greater
|
|
|
|
than the comparator level. The digital inputs are not modifier
|
|
|
|
inputs. Note, however, there is an effective modifier due to the
|
|
|
|
restriction that the primary analog comparator level must be less
|
|
|
|
than the secondary analog comparator level.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
If only one analog comparator signal is used, the combining machine
|
|
|
|
for the secondary input should be set to ignored, and the secondary
|
2012-05-01 15:42:07 +01:00
|
|
|
analog level should be set to <literal>0</literal>.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The interpretation of the chanspec and voltage levels is device
|
|
|
|
dependent, but should correspond to similar values of the analog
|
|
|
|
input subdevice, if possible.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Notes: Reading range information is not addressed. This makes it
|
|
|
|
difficult to convert comparator voltages to data values.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Possible extensions: A parameter that specifies the necessary time
|
|
|
|
that the set condition has to be true before the trigger is generated.
|
|
|
|
A parameter that specifies the necessary time that the reset condition
|
|
|
|
has to be true before the state machine is reset.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
</section>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<section id="bitfieldmatching">
|
2002-01-21 15:17:12 +00:00
|
|
|
<title>
|
2003-07-07 22:34:18 +00:00
|
|
|
Bitfield Pattern Matching Extended Trigger
|
2002-01-21 15:17:12 +00:00
|
|
|
</title>
|
2003-07-07 22:34:18 +00:00
|
|
|
<para>
|
|
|
|
<emphasis role="strong">
|
|
|
|
(Status: design. No driver implements this feature yet.)
|
|
|
|
</emphasis>
|
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is ignored.
|
|
|
|
</para>
|
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-data">data</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is used as follows:
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2012-05-01 11:48:46 +01:00
|
|
|
<variablelist spacing="compact">
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[1]</term>
|
|
|
|
<listitem>trigger flags.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[2]</term>
|
|
|
|
<listitem>mask.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[3]</term>
|
|
|
|
<listitem>pattern.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
The pattern matching trigger issues a trigger when all of a specifed
|
2003-07-07 22:34:18 +00:00
|
|
|
set of input lines match a specified pattern. If the device allows,
|
|
|
|
the input lines should correspond to the input lines of a digital input
|
|
|
|
subdevice, however, this will necessarily be device dependent. Each
|
|
|
|
possible digital line that can be matched is assigned a bit in the
|
|
|
|
mask and pattern. A bit set in the mask indicates that the
|
|
|
|
input line must match the corresponding bit in the pattern.
|
|
|
|
A bit cleared in the mask indicates that the input line is ignored.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Notes: This only allows 32 bits in the pattern/mask, which may be
|
|
|
|
too few. Devices may support selecting different sets of lines from
|
|
|
|
which to match a pattern.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Discovery: The number of bits can be discovered by setting the mask
|
2012-05-01 15:42:07 +01:00
|
|
|
to all 1's. The driver must modify this value and return
|
|
|
|
<constant>-EAGAIN</constant>.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section id="countertimer">
|
|
|
|
<title>
|
|
|
|
Counter configuration
|
|
|
|
</title>
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
<emphasis role="strong">
|
|
|
|
(Status: design. No driver implements this feature yet.)
|
|
|
|
</emphasis>
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is used to specify which counter to use. (I.e., the
|
|
|
|
counter is a &comedi; channel.)
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-data">data</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is used as follows:
|
|
|
|
</para>
|
2012-05-01 11:48:46 +01:00
|
|
|
<variablelist spacing="compact">
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[1]</term>
|
|
|
|
<listitem>trigger configuration.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[2]</term>
|
|
|
|
<listitem>primary input chanspec.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[3]</term>
|
|
|
|
<listitem>primary combining machine configuration.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[4]</term>
|
|
|
|
<listitem>secondary input chanspec.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[5]</term>
|
|
|
|
<listitem>secondary combining machine configuration.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[6]</term>
|
|
|
|
<listitem>latch configuration.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
2003-07-07 22:34:18 +00:00
|
|
|
|
|
|
|
<para>
|
|
|
|
Note that this configuration is only useful if the counting has to be
|
|
|
|
done in <emphasis>software</emphasis>. Many cards offer configurable
|
|
|
|
counters in hardware; e.g., general purpose timer cards can be
|
|
|
|
configured to act as pulse generators, frequency counters, timers,
|
|
|
|
encoders, etc.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Counters can be operated either in synchronous mode (using
|
2012-05-03 19:56:59 +01:00
|
|
|
<constant><link linkend="insn-read">INSN_READ</link></constant>)
|
2006-10-24 15:07:41 +00:00
|
|
|
or asynchronous mode (using
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="commandsstreaming">commands</link>), similar to analog
|
2006-10-24 15:07:41 +00:00
|
|
|
input subdevices.
|
2003-07-07 22:34:18 +00:00
|
|
|
The input signal for both modes is the accumulator.
|
|
|
|
Commands on counter subdevices are almost always specified using
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-src">scan_begin_src</link></structfield>
|
2012-05-03 19:56:59 +01:00
|
|
|
= <constant><link linkend="trigother-event">TRIG_OTHER</link></constant>,
|
2012-05-01 15:42:07 +01:00
|
|
|
with the counter configuration also serving as the extended configuration for
|
2012-05-08 13:58:27 +01:00
|
|
|
the <quote>scan begin</quote> source.
|
2003-07-07 22:34:18 +00:00
|
|
|
</para>
|
2002-01-21 15:17:12 +00:00
|
|
|
|
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Counters are made up of an accumulator and a combining machine that
|
|
|
|
determines when the accumulator should be incremented or decremented
|
|
|
|
based on the values of the input signals. The combining machine
|
|
|
|
optionally determines when the accumulator should be latched and
|
|
|
|
put into a buffer. This feature is used in asynchronous mode.
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-01-21 11:15:31 +00:00
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Note: How to access multiple pieces of data acquired at each event?
|
2002-01-21 15:17:12 +00:00
|
|
|
</para>
|
2002-07-22 20:45:24 +00:00
|
|
|
|
|
|
|
</section>
|
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
<section id="auxcounter">
|
2002-07-22 20:45:24 +00:00
|
|
|
<title>
|
2003-07-07 22:34:18 +00:00
|
|
|
One source plus auxiliary counter configuration
|
2002-07-22 20:45:24 +00:00
|
|
|
</title>
|
2003-07-07 22:34:18 +00:00
|
|
|
<para>
|
|
|
|
<emphasis role="strong">
|
|
|
|
(Status: design. No driver implements this feature yet.)
|
|
|
|
</emphasis>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-insn">insn</link></structfield> field of the
|
2003-07-07 22:34:18 +00:00
|
|
|
<link linkend="insn-data-structure">instruction data structure</link>
|
|
|
|
has not been assigned yet.
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-chanspec">chanspec</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is used to …
|
|
|
|
</para>
|
2002-07-22 20:45:24 +00:00
|
|
|
|
|
|
|
<para>
|
2012-05-08 13:58:27 +01:00
|
|
|
The <structfield><link linkend="insn-data-structure-data">data</link></structfield> field
|
2003-07-07 22:34:18 +00:00
|
|
|
of the <link linkend="insn-data-structure">instruction data
|
|
|
|
structure</link> is used as follows:
|
2002-07-22 20:45:24 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2012-05-01 11:48:46 +01:00
|
|
|
<variablelist spacing="compact">
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[1]</term>
|
|
|
|
<listitem>
|
|
|
|
is flags, including the flags for the command triggering
|
2003-07-07 22:34:18 +00:00
|
|
|
configuration. If a command is not subsequently issued on the
|
|
|
|
subdevice, the command triggering portion of the flags are ignored.
|
2012-05-01 11:48:46 +01:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[2]</term>
|
|
|
|
<listitem>
|
|
|
|
determines the mode of operation. The mode of operation
|
2003-07-07 22:34:18 +00:00
|
|
|
is actually a bitfield that encodes what to do for various
|
|
|
|
transitions of the source signals.
|
2012-05-01 11:48:46 +01:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>data[3]</term>
|
|
|
|
<term>data[4]</term>
|
|
|
|
<listitem>
|
|
|
|
determine the primary source for the counter, similar to the
|
2012-05-08 13:58:27 +01:00
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-src">…_src</link></structfield> and the
|
|
|
|
<structfield><link linkend="command-data-struct-scan-begin-arg">…_arg</link></structfield> fields
|
2003-07-07 22:34:18 +00:00
|
|
|
used in the
|
|
|
|
<link linkend="command-data-struct">command data structure</link>.
|
2012-05-01 11:48:46 +01:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
2002-07-22 20:45:24 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2003-07-07 22:34:18 +00:00
|
|
|
Notes: How to specify which events cause a latch and push, and what
|
|
|
|
should get latched?
|
2002-07-22 20:45:24 +00:00
|
|
|
</para>
|
|
|
|
|
2006-05-02 01:21:46 +00:00
|
|
|
</section>
|
|
|
|
|
2015-05-27 18:42:01 +02:00
|
|
|
<section id="GPCT">
|
|
|
|
<title>
|
2015-05-28 13:35:58 +01:00
|
|
|
National Instruments General Purpose Counters/Timers (GPCT)
|
2015-05-27 18:42:01 +02:00
|
|
|
</title>
|
|
|
|
|
|
|
|
Counters/timers and pulse generators are fairly different in terms of
|
|
|
|
functionality, but they correspond to similar devices seen either as input
|
|
|
|
or output. When generalising, these devices are both referred to as
|
|
|
|
"counters". The NI boards provide a couple of such counters, under the name of
|
|
|
|
GPCT.
|
|
|
|
A counter is made of the following basic elements:
|
|
|
|
<variablelist spacing="compact">
|
|
|
|
<varlistentry>
|
|
|
|
<term>Input source</term>
|
|
|
|
<listitem>the signal measured or the clock of the pulse generation.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>Gate</term>
|
|
|
|
<listitem>controls when the counting (or sampling) occurs.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>Register</term>
|
|
|
|
<listitem>holds the current count.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>Out</term>
|
|
|
|
<listitem>for the output counters (pulse generators), the output signal.</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
There are many different ways to count, time or generate pulses. All the modes
|
|
|
|
rely on the counter and some particular configuration. For example, in a typical
|
|
|
|
buffered counting mode, the source is the (digital) signal that is measured, the
|
|
|
|
counter is increased at every rising edge of the signal, the gate is the
|
|
|
|
(digital) signal indicating when to save the counter to memory. It is preferable
|
|
|
|
you get first familiarized with these various modes by reading your NI board
|
|
|
|
documentation before reading the following description on the mapping to the
|
|
|
|
comedi interface.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Each counter of the board is represented in comedi as a subdevice of type
|
|
|
|
<constant>COMEDI_SUBD_COUNTER</constant>. Each subdevice has a device file
|
|
|
|
associated (eg, <filename>/dev/comedi0_subd11</filename>) in order to read or
|
|
|
|
write buffered data from or to the counter.
|
|
|
|
Note that the comedi subdevice has three "channels". In most case, only channel
|
|
|
|
0 is to be used. Reading or writing on channel 0 corresponds to reading/writing
|
|
|
|
the counter value. The GPCT also has two registers named A and B, they can be
|
|
|
|
accessed respectively via channels 1 and 2.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
To configure the behaviour of the counter with comedi, the
|
|
|
|
function <function>comedi_set_counter_mode</function> is used.
|
|
|
|
The possible mode values are to be found in the <type>ni_gpct_mode_bits</type>
|
|
|
|
enum constants. For instance, by default the counter is cumulative, even in
|
|
|
|
buffered counting. To reinitialise it after each sampling (ie, after an edge on
|
|
|
|
the gate signal), one can add the <constant>NI_GPCT_LOADING_ON_GATE_BIT</constant>
|
|
|
|
to the mode. In that case, the counter will be reset to the value of the A
|
|
|
|
register after each sampling.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
To configure the signal to be used as the "source", one uses the <function>
|
|
|
|
comedi_set_clock_source</function> with one constant from the
|
|
|
|
<type>ni_gpct_clock_source_bits</type> enum. When the period of the signal is
|
|
|
|
fixed and known, it should be specified as the last parameter of the method, otherwise
|
|
|
|
<literal>0</literal> should be passed. Note that in comedi this is called "clock"
|
|
|
|
because in timer and pulse generator, this signal is used as the clock.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
To configure the signal to be used as the "gate", one uses the <function>
|
|
|
|
comedi_set_gate_source</function> with one constant from the <type>
|
|
|
|
ni_gpct_gate_select</type> enum. When the gate signal is not be used,
|
|
|
|
<constant>NI_GPCT_DISABLED_GATE_SELECT</constant> should be specified. Some
|
|
|
|
NI boards have two gates, but the behaviour associated with the second gate is
|
|
|
|
usually unknown so it is recommended to disable it. Note that this is called
|
|
|
|
"gate" because in some modes, this signal is used to block/unblock the counter.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The function <function>comedi_reset</function> will stop and reset a counter.
|
|
|
|
After being configured, to start a counter, it should be "armed", which can be
|
|
|
|
done either with the <function>comedi_arm</function> function (for simple counting
|
|
|
|
mode), or with the <structfield>start_src</structfield> member of the command
|
|
|
|
(for buffered counting).
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
One side thing to mention is the signal routing of the NI card, which is done
|
|
|
|
via the PFIs (Programmable Function Inputs).
|
|
|
|
NI's naming is confusing because they use the same name for the
|
|
|
|
terminal (ie, physical input/output pins) and for the signal
|
|
|
|
(ie, the logical information that controls/indicates a specific event).
|
|
|
|
|
|
|
|
The routing allows to configure which signal goes to a PFI terminal.
|
|
|
|
This is done via <function>comedi_set_routing</function>, with subdevice being
|
|
|
|
the special DIO comedi subdevice (eg, 7 on M-series), the PFI terminal
|
|
|
|
number as channel, the signal that should be routed to it encoded as source with
|
|
|
|
one of the constants from the <type>ni_pfi_routing</type> enum.
|
|
|
|
The direction of the pin must also be correctly configured (ie, whether it is
|
|
|
|
used as input or output). This is done via <function>comedi_dio_config</function>
|
|
|
|
with the same subdevice and channel, and either <constant>COMEDI_INPUT</constant>
|
|
|
|
or <constant>COMEDI_OUTPUT</constant>.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
2006-05-02 01:21:46 +00:00
|
|
|
<section id="RTSI">
|
|
|
|
<title>
|
2015-05-28 13:35:58 +01:00
|
|
|
National Instruments RTSI trigger bus
|
2006-05-02 01:21:46 +00:00
|
|
|
</title>
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
A number of NI boards support the RTSI (Real Time System Integration) bus.
|
|
|
|
It's primary use is to synchronize multiple DAQ cards.
|
|
|
|
On PXI boards, the RTSI lines correspond to the PXI trigger lines 0 to 7. PCI
|
|
|
|
boards use cables to connect to their RTSI ports.
|
|
|
|
The RTSI bus consists of 8 digital signal lines numbered 0 to 7 that are bi-directional.
|
|
|
|
Each of these signal lines
|
|
|
|
can be configured as an input or output, and the signal appearing on the output
|
|
|
|
of each line can be configured to one of several internal board timing signals
|
|
|
|
(although on older boards RTSI line 7 can only be used for the clock signal).
|
2012-05-02 15:47:59 +01:00
|
|
|
The <systemitem>ni_pcimio</systemitem>, <systemitem>ni_atmio</systemitem>, and
|
|
|
|
<systemitem>ni_mio_cs</systemitem> drivers expose the RTSI bus
|
2006-10-24 15:07:41 +00:00
|
|
|
as a digital I/O subdevice (subdevice number 10).
|
|
|
|
</para>
|
|
|
|
<para>
|
2012-05-03 19:56:59 +01:00
|
|
|
The functions <function>comedi_dio_config</function> and
|
|
|
|
<function>comedi_dio_get_config</function> can be used on
|
2006-10-24 15:07:41 +00:00
|
|
|
the RTSI subdevice to
|
|
|
|
set/query the direction (input or output) of each of the RTSI lines individually.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The subdevice also supports the
|
2012-05-01 15:42:07 +01:00
|
|
|
<constant>INSN_CONFIG_SET_CLOCK_SRC</constant> and
|
|
|
|
<constant>INSN_CONFIG_GET_CLOCK_SRC</constant> configuration
|
2006-10-24 15:07:41 +00:00
|
|
|
instructions, which can be
|
|
|
|
used to configure/query what source the board uses to synchronize its
|
2012-05-02 15:47:59 +01:00
|
|
|
master clock to. The various possibilities are defined in the <filename>comedi.h</filename>
|
2006-10-24 15:07:41 +00:00
|
|
|
header file:
|
2006-05-02 01:21:46 +00:00
|
|
|
</para>
|
|
|
|
<informaltable>
|
|
|
|
<tgroup cols='2' align='left'>
|
|
|
|
<thead>
|
|
|
|
<row>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>Clock Source</entry>
|
2006-05-02 01:21:46 +00:00
|
|
|
<entry>Description</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_MIO_INTERNAL_CLOCK</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
Use the board's internal oscillator.
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_MIO_RTSI_CLOCK</constant></entry>
|
2006-05-02 01:21:46 +00:00
|
|
|
<entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
Use the RTSI line 7 as the master clock. This source is
|
|
|
|
only supported on pre-m-series boards. The newer m-series boards
|
2012-05-03 19:56:59 +01:00
|
|
|
use <function>NI_MIO_PLL_RTSI_CLOCK</function> instead.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK</constant></entry>
|
2006-05-02 01:21:46 +00:00
|
|
|
<entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
Only available for newer m-series PXI boards. Synchronizes the board's
|
|
|
|
phased-locked loop (which runs at 80MHz) to the PXI star trigger
|
|
|
|
line.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_MIO_PLL_PXI10_CLOCK</constant></entry>
|
2006-05-02 01:21:46 +00:00
|
|
|
<entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
Only available for newer m-series PXI boards.
|
|
|
|
Synchronizes the board's
|
|
|
|
phased-locked loop (which runs at 80MHz) to the 10 MHz PXI backplane
|
|
|
|
clock.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry>
|
|
|
|
<function>NI_MIO_PLL_RTSI_CLOCK<parameter>n</parameter></function>
|
|
|
|
</entry>
|
2006-05-02 01:21:46 +00:00
|
|
|
<entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
Only available for newer m-series boards.
|
|
|
|
The function returns a clock source which will cause the board's
|
|
|
|
phased-locked loop (which runs at 80MHz) to syncronize to the RTSI
|
|
|
|
line specified in the function argument.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</informaltable>
|
2006-10-24 15:07:41 +00:00
|
|
|
|
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
For all clock sources except <constant>NI_MIO_INTERNAL_CLOCK</constant>
|
|
|
|
and <constant>NI_MIO_PLL_PXI10_CLOCK</constant>,
|
2006-10-24 15:07:41 +00:00
|
|
|
you should pass the period of the clock your are feeding to the board when
|
2012-05-01 15:42:07 +01:00
|
|
|
using <constant>INSN_CONFIG_SET_CLOCK_SRC</constant>.
|
2006-10-24 15:07:41 +00:00
|
|
|
</para>
|
2006-05-02 01:21:46 +00:00
|
|
|
<para>
|
2012-05-01 15:42:07 +01:00
|
|
|
Finally, the configuration instructions
|
|
|
|
<constant>INSN_CONFIG_SET_ROUTING</constant> and
|
|
|
|
<constant>INSN_CONFIG_GET_ROUTING</constant>
|
|
|
|
can be used to select/query which internal signal
|
2012-05-02 15:47:59 +01:00
|
|
|
will appear on a given RTSI output line. The header file <filename>comedi.h</filename> defines
|
2006-10-24 15:07:41 +00:00
|
|
|
the following signal sources which can be routed to an RTSI line:
|
2006-05-02 01:21:46 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<informaltable>
|
|
|
|
<tgroup cols='2' align='left'>
|
|
|
|
<thead>
|
|
|
|
<row>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>Signal Source</entry>
|
|
|
|
<entry>Description</entry>
|
2006-05-02 01:21:46 +00:00
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_ADR_START1</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
ADR_START1, an analog input start signal. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_ADR_START2</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
ADR_START2, an analog input stop signal. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_SCLKG</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
SCLKG, a sample clock signal. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_DACUPDN</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
DACUPDN, a dac update signal. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_DA_START1</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
DA_START1, an analog output start signal. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_G_SRC0</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
G_SRC0, the source signal to general purpose counter 0. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_G_GATE0</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
G_GATE0, the gate signal to general purpose counter 0. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_RGOUT0</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
RGOUT0, the output signal of general purpose counter 0. See the NI's
|
|
|
|
DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry>
|
|
|
|
<function>NI_RTSI_OUTPUT_RTSI_BRD<parameter>n</parameter></function>
|
|
|
|
</entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
RTSI_BRD0 though RTSI_BRD3 are four internal signals which can
|
|
|
|
have various other signals routed to them in turn. Currently, comedi
|
|
|
|
provides no way to configure the signals routed to the RTSI_BRD lines.
|
|
|
|
See the NI's DAQ-STC Technical Reference Manual for more information.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
</row>
|
|
|
|
<row>
|
2012-05-01 15:42:07 +01:00
|
|
|
<entry><constant>NI_RTSI_OUTPUT_RTSI_OSC</constant></entry>
|
2006-10-24 15:07:41 +00:00
|
|
|
<entry>
|
|
|
|
The RTSI clock signal. On pre-m-series boards, this signal is always
|
|
|
|
routed to RTSI line 7, and cannot be routed to lines 0 through 6. On
|
|
|
|
m-series boards, any RTSI line can be configured to output the clock
|
|
|
|
signal.
|
2006-05-02 01:21:46 +00:00
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</informaltable>
|
|
|
|
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
The RTSI bus pins may be used as trigger inputs for many of the
|
2012-05-01 15:42:07 +01:00
|
|
|
&comedi; trigger functions. To use the RTSI bus pins, set the source to be
|
|
|
|
<constant>TRIG_EXT</constant> and the source argument using the return values
|
2012-05-03 19:56:59 +01:00
|
|
|
from the <function>NI_EXT_RTSI<parameter>n</parameter></function> function (or similarly the
|
|
|
|
<function>NI_EXT_PFI<parameter>n</parameter></function> function if you want
|
2012-05-01 15:42:07 +01:00
|
|
|
to trigger from a PFI line). The <constant>CR_EDGE</constant> and
|
|
|
|
<constant>CR_INVERT</constant> flags may
|
2006-10-24 15:07:41 +00:00
|
|
|
also be set on the trigger source argument to specify edge and
|
|
|
|
falling edge/low level triggering.
|
|
|
|
|
2006-05-02 01:21:46 +00:00
|
|
|
</para>
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
An example to set up a device as a master is given below.
|
2006-05-02 01:21:46 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<programlisting><![CDATA[
|
2012-05-01 12:51:08 +01:00
|
|
|
void comediEnableMaster(comedi_t *dev){
|
|
|
|
comedi_insn configCmd;
|
|
|
|
lsampl_t configData[2];
|
|
|
|
int ret;
|
|
|
|
unsigned int d = 0;
|
|
|
|
static const unsigned rtsi_subdev = 10;
|
|
|
|
static const unsigned rtsi_clock_line = 7;
|
|
|
|
|
|
|
|
/* Route RTSI clock to line 7 (not needed on pre-m-series boards since their
|
|
|
|
clock is always on line 7). */
|
|
|
|
memset(&configCmd, 0, sizeof(configCmd));
|
|
|
|
memset(&configData, 0, sizeof(configData));
|
|
|
|
configCmd.insn = INSN_CONFIG;
|
|
|
|
configCmd.subdev = rtsi_subdev;
|
|
|
|
configCmd.chanspec = rtsi_clock_line;
|
|
|
|
configCmd.n = 2;
|
|
|
|
configCmd.data = configData;
|
|
|
|
configCmd.data[0] = INSN_CONFIG_SET_ROUTING;
|
|
|
|
configCmd.data[1] = NI_RTSI_OUTPUT_RTSI_OSC;
|
|
|
|
ret = comedi_do_insn(dev, &configCmd);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_do_insn: INSN_CONFIG");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
// Set clock RTSI line as output
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, rtsi_clock_line, INSN_CONFIG_DIO_OUTPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set routing of the 3 main AI RTSI signals and their direction to output.
|
|
|
|
We're reusing the already initialized configCmd instruction here since
|
|
|
|
it's mostly the same. */
|
|
|
|
configCmd.chanspec = 0;
|
|
|
|
configCmd.data[1] = NI_RTSI_OUTPUT_ADR_START1;
|
|
|
|
ret = comedi_do_insn(dev, &configCmd);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_do_insn: INSN_CONFIG");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, 0, INSN_CONFIG_DIO_OUTPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
configCmd.chanspec = 1;
|
|
|
|
configCmd.data[1] = NI_RTSI_OUTPUT_ADR_START2;
|
|
|
|
ret = comedi_do_insn(dev, &configCmd);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_do_insn: INSN_CONFIG");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, 1, INSN_CONFIG_DIO_OUTPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
configCmd.chanspec = 2;
|
|
|
|
configCmd.data[1] = NI_RTSI_OUTPUT_SCLKG;
|
|
|
|
ret = comedi_do_insn(dev, &configCmd);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_do_insn: INSN_CONFIG");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, 2, INSN_CONFIG_DIO_OUTPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
2006-05-02 01:21:46 +00:00
|
|
|
}
|
|
|
|
]]></programlisting>
|
|
|
|
|
|
|
|
<para>
|
2006-10-24 15:07:41 +00:00
|
|
|
An example to slave a m-series device from this master follows. A pre-m-series
|
2012-05-01 15:42:07 +01:00
|
|
|
device would need to use <constant>NI_MIO_RTSI_CLOCK</constant> for
|
|
|
|
the clock source instead. In
|
2006-10-24 15:07:41 +00:00
|
|
|
your code, you may also wish to configure the master device to use the
|
|
|
|
external clock source instead of using its internal clock directly (for
|
|
|
|
best syncronization).
|
2006-05-02 01:21:46 +00:00
|
|
|
</para>
|
|
|
|
<programlisting><![CDATA[
|
2012-05-01 12:51:08 +01:00
|
|
|
void comediEnableSlave(comedi_t *dev){
|
|
|
|
comedi_insn configCmd;
|
|
|
|
lsampl_t configData[3];
|
|
|
|
int ret;
|
|
|
|
unsigned int d = 0;;
|
|
|
|
static const unsigned rtsi_subdev = 10;
|
|
|
|
static const unsigned rtsi_clock_line = 7;
|
|
|
|
|
|
|
|
memset(&configCmd, 0, sizeof(configCmd));
|
|
|
|
memset(&configData, 0, sizeof(configData));
|
|
|
|
configCmd.insn = INSN_CONFIG;
|
|
|
|
configCmd.subdev = rtsi_subdev;
|
|
|
|
configCmd.chanspec = 0;
|
|
|
|
configCmd.n = 3;
|
|
|
|
configCmd.data = configData;
|
|
|
|
configCmd.data[0] = INSN_CONFIG_SET_CLOCK_SRC;
|
|
|
|
configCmd.data[1] = NI_MIO_PLL_RTSI_CLOCK(rtsi_clock_line);
|
|
|
|
configCmd.data[2] = 100; /* need to give it correct external clock period */
|
|
|
|
ret = comedi_do_insn(dev, &configCmd);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_do_insn: INSN_CONFIG");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* configure RTSI clock line as input */
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, rtsi_clock_line, INSN_CONFIG_DIO_INPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* Configure RTSI lines we are using for AI signals as inputs. */
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, 0, INSN_CONFIG_DIO_INPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, 1, INSN_CONFIG_DIO_INPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ret = comedi_dio_config(dev, rtsi_subdev, 2, INSN_CONFIG_DIO_INPUT);
|
|
|
|
if(ret < 0){
|
|
|
|
comedi_perror("comedi_dio_config");
|
|
|
|
exit(1);
|
|
|
|
}
|
2006-05-02 01:21:46 +00:00
|
|
|
}
|
|
|
|
|
2012-05-01 12:51:08 +01:00
|
|
|
int comediSlaveStart(comedi_t *dev){
|
|
|
|
comedi_cmd cmd;
|
|
|
|
unsigned int nChannels = 8;
|
|
|
|
double sampleRate = 50000;
|
|
|
|
unsigned int chanList[8];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
// Setup chan list
|
|
|
|
for(i = 0; i < nChannels; i++){
|
|
|
|
chanList[i] = CR_PACK(i, 0, AREF_GROUND);
|
|
|
|
}
|
|
|
|
// Set up command
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
|
|
|
ret = comedi_get_cmd_generic_timed(dev, subdevice, &cmd,
|
|
|
|
(int)(1e9/(nChannels * sampleRate)));
|
|
|
|
if(ret<0){
|
|
|
|
printf("comedi_get_cmd_generic_timed failed\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
cmd.chanlist = chanList;
|
|
|
|
cmd.chanlist_len = nChannels;
|
|
|
|
cmd.scan_end_arg = nChannels;
|
|
|
|
cmd.start_src = TRIG_EXT;
|
|
|
|
cmd.start_arg = CR_EDGE | NI_EXT_RTSI(0);
|
|
|
|
cmd.convert_src = TRIG_EXT;
|
|
|
|
cmd.convert_arg = CR_INVERT | CR_EDGE | NI_EXT_RTSI(2);
|
|
|
|
cmd.stop_src = TRIG_NONE;
|
|
|
|
|
|
|
|
ret = comedi_command(dev0, &cmd0);
|
|
|
|
if(ret<0){
|
|
|
|
printf("comedi_command failed\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
2006-05-02 01:21:46 +00:00
|
|
|
}
|
|
|
|
]]></programlisting>
|
|
|
|
|
|
|
|
|
2002-01-21 15:17:12 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
2003-07-07 22:34:18 +00:00
|
|
|
</section>
|
2002-01-21 11:15:31 +00:00
|
|
|
|