<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
- "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
%comedilib_entities;
]>
<para>
Individual bits on a digital I/O device can be read and written using
the functions
-<programlisting>
- int <link linkend="func-ref-comedi-dio-read">comedi_dio_read</link>(device,subdevice,channel,unsigned int *bit);
- int <link linkend="func-ref-comedi-dio-write">comedi_dio_write</link>(device,subdevice,channel,unsigned int bit);
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-dio-read"><function>comedi_dio_read</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<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>
+<funcdef>int <link linkend="func-ref-comedi-dio-write"><function>comedi_dio_write</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
+<paramdef>unsigned int <parameter>channel</parameter></paramdef>
+<paramdef>unsigned int <parameter>bit</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
The <parameter class="function">device</parameter> parameter is a
<link linkend="ref-type-comedi-t">pointer</link>
to a successfully opened &comedi; device.
<para>
The direction of bidirectional lines can be configured using
the function
-<programlisting>
- <link linkend="func-ref-comedi-dio-config">comedi_dio_config</link>(device,subdevice,channel,unsigned int dir);
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-dio-config"><function>comedi_dio_config</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
+<paramdef>unsigned int <parameter>channel</parameter></paramdef>
+<paramdef>unsigned int <parameter>dir</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
The parameter <parameter class="function">dir</parameter> should be
-either <literal>COMEDI_INPUT</literal> or
-<literal>COMEDI_OUTPUT</literal>.
+either <constant>COMEDI_INPUT</constant> or
+<constant>COMEDI_OUTPUT</constant>.
Many digital I/O subdevices group channels into blocks for
configuring direction. Changing one channel in a block changes
the entire block.
<para>
Multiple channels can be read and written simultaneously using the
function
-<programlisting>
- <link linkend="func-ref-comedi-dio-bitfield">comedi_dio_bitfield</link>(device,subdevice,unsigned int write_mask,unsigned int *bits);
-</programlisting>
-Each channel is assigned to a bit in the
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-dio-bitfield2"><function>comedi_dio_bitfield2</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
+<paramdef>unsigned int <parameter>write_mask</parameter></paramdef>
+<paramdef>unsigned int *<parameter>bits</parameter></paramdef>
+<paramdef>unsigned int <parameter>base_channel</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
+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
<parameter class="function">write_mask</parameter> and
<parameter class="function">bits</parameter>
-bitfield. If a bit in
+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
<parameter class="function">write_mask</parameter> is set, the
corresponding bit in <parameter class="function">*bits</parameter> will
-be written to the corresponding digital output line.
+be written to the digital output line corresponding to the channel given by
+<parameter class="function">base_channel</parameter> plus the bit number.
Each digital line is then read and placed into
<parameter class="function">*bits</parameter>. The value
of bits in <parameter class="function">*bits</parameter> corresponding
to digital output lines is undefined and device-specific. Channel
-<literal>0</literal> is the least significant bit in the bitfield;
-channel <literal>31</literal> is the most significant bit. Channels
-higher than <literal>31</literal> cannot be accessed using this method.
+<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.
</para>
<para>
<literal>12</literal>, or <literal>16</literal> bits.
</para>
<para>
-The
-<programlisting>
- int <link linkend="func-ref-comedi-data-read">comedi_data_read</link>(<link linkend="ref-type-comedi-t">comedi_t</link> * device, unsigned int subdevice, unsigned int channel,
- unsigned int range, unsigned int aref, <link linkend="ref-type-lsampl-t">lsampl_t</link> * data);
-</programlisting>
-function reads one such data value from a &comedi; channel, and puts it in
-the user-specified <parameter>data</parameter> buffer. The
-<programlisting>
- int <link linkend="func-ref-comedi-data-write">comedi_data_write</link>(<link linkend="ref-type-comedi-t">comedi_t</link> * device, unsigned int subdevice, unsigned int channel,
- unsigned int range, unsigned int aref, <link linkend="ref-type-lsampl-t">lsampl_t</link> data);
-</programlisting>
+The function
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-data-read"><function>comedi_data_read</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<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>
+<paramdef><link linkend="ref-type-lsampl-t">lsampl_t</link> *<parameter>data</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
+reads one such data value from a &comedi; channel, and puts it in
+the user-specified <parameter>data</parameter> buffer. The function
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-data-write"><function>comedi_data_write</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<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>
+<paramdef><link linkend="ref-type-lsampl-t">lsampl_t</link> <parameter>data</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
works in the opposite direction. Data values returned by this function
are unsigned integers less than, or equal to, the maximum sample value
of the channel, which can be determined using the function
-<programlisting>
- <link linkend="ref-type-lsampl-t">lsampl_t</link> <link linkend="func-ref-comedi-get-maxdata">comedi_get_maxdata</link>(<link linkend="ref-type-comedi-t">comedi_t</link> * device, unsigned int subdevice, unsigned int channel);
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef><link linkend="ref-type-lsampl-t">lsampl_t</link> <link linkend="func-ref-comedi-get-maxdata"><function>comedi_get_maxdata</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
+<paramdef>unsigned int <parameter>channel</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
Conversion of data values to physical units can be performed by the
function
-<programlisting>
- double <link linkend="func-ref-comedi-to-phys">comedi_to_phys</link>(<link linkend="ref-type-lsampl-t">lsampl_t</link> data, comedi_range * range, <link linkend="ref-type-lsampl-t">lsampl_t</link> maxdata);
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef>double <link linkend="func-ref-comedi-to-phys"><function>comedi_to_phys</function></link></funcdef>
+<paramdef><link linkend="ref-type-lsampl-t">lsampl_t</link> <parameter>data</parameter></paramdef>
+<paramdef><link linkend="ref-type-comedi-range">comedi_range</link> *<parameter>range</parameter></paramdef>
+<paramdef><link linkend="ref-type-lsampl-t">lsampl_t</link> <parameter>maxdata</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
There are two data structures in these commands that are not fully
self-explanatory:
<itemizedlist>
function call are checked. If multiple acquisitions must be done on
the same channel, this overhead can be avoided by using a function
that can read more than one sample:
-<programlisting>
- int <link linkend="func-ref-comedi-dio-read">comedi_data_read_n</link>(<link linkend="ref-type-comedi-t">comedi_t</link> *it, unsigned int subdev, unsigned int chan, unsigned int range,
- unsigned int aref, <link linkend="ref-type-lsampl-t">lsampl_t</link> *data, unsigned int n)
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-data-read-n"><function>comedi_data_read_n</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<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>
+<paramdef><link linkend="ref-type-lsampl-t">lsampl_t</link> *<parameter>data</parameter></paramdef>
+<paramdef>unsigned int <parameter>n</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
The number of samples, <parameter class="function">n</parameter>, is
limited by the &comedi; implementation (to a maximum of 100 samples),
because the call is blocking.
<para>
The start of the data acquisition can also be delayed by a specified
number of nano-seconds:
-<programlisting>
-int <link linkend="func-ref-comedi-data-read-delayed">comedi_data_read_delayed</link>(<link linkend="ref-type-comedi-t">comedi_t</link> *it, unsigned int subdev, unsigned int chan, unsigned int range,
- unsigned int aref, <link linkend="ref-type-lsampl-t">lsampl_t</link> *data, unsigned int nano_sec)
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-data-read-delayed"><function>comedi_data_read_delayed</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<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>
+<paramdef><link linkend="ref-type-lsampl-t">lsampl_t</link> *<parameter>data</parameter></paramdef>
+<paramdef>unsigned int <parameter>nano_sec</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
All these read and write acquisition functions are implemented on top
of the generic <link linkend="instructions">instruction</link>
command.
<link linkend="ref-type-comedi-insn">comedi_insn</link>
data structure:
<programlisting>
-struct <anchor id="insn-data-structure"/>comedi_insn_struct{
+struct <anchor id="insn-data-structure"/>comedi_insn_struct {
<anchor id="insn-data-structure-insn"/>unsigned int insn; // integer encoding the type of acquisition
// (or configuration)
unsigned int n; // number of elements in data array
<listitem>
<para>
-INSN_READ: the instruction executes a read on an analog channel.
+<constant>INSN_READ</constant>: the instruction executes a read on an
+analog channel.
</para>
</listitem>
<listitem>
<para>
-INSN_WRITE: the instruction executes a write on an analog channel.
+<constant>INSN_WRITE</constant>: the instruction executes a write on an
+analog channel.
</para>
</listitem>
<listitem>
<para>
-INSN_BITS: indicates that the instruction must
+<constant>INSN_BITS</constant>: indicates that the instruction must
read or write values on multiple digital I/O channels.
</para>
</listitem>
<listitem>
<para>
-INSN_GTOD: the instruction performs a <quote>Get Time Of Day</quote>
-acquisition.
+<constant>INSN_GTOD</constant>: the instruction performs a
+<quote>Get Time Of Day</quote> acquisition.
</para>
</listitem>
<listitem>
<para>
-INSN_WAIT: the instruction blocks for a specified number of
-nanoseconds.
+<constant>INSN_WAIT</constant>: the instruction blocks for a specified
+number of nanoseconds.
</para>
</listitem>
</title>
<para>
Once an instruction data structure has been filled in, the
-corresponding instruction is executed as follows:
-<programlisting>
- int <link linkend="func-ref-comedi-do-insn">comedi_do_insn</link>(<link linkend="ref-type-comedi-t">comedi_t</link> *it, <link linkend="ref-type-comedi-insn">comedi_insn</link> * instruction);
-</programlisting>
+corresponding instruction is executed with the function
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-do-insn"><function>comedi_do_insn</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef><link linkend="ref-type-comedi-insn">comedi_insn</link> *<parameter>instruction</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
Many &comedi; instructions are shortcuts that relieve the programmer
from explicitly filling in the data structure and calling the
<link linkend="func-ref-comedi-do-insn">comedi_do_insn</link>
function.
</para>
<para>
-The
-<programlisting>
- int <link linkend="func-ref-comedi-do-insnlist">comedi_do_insnlist</link><link linkend="ref-type-comedi-t">comedi_t</link> *it, <link linkend="ref-type-comedi-insnlist">comedi_insnlist</link> * list)
-</programlisting>
-instruction allows to perform a list of instructions in one function
+The function
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-do-insnlist"><function>comedi_do_insnlist</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef><link linkend="ref-type-comedi-insnlist">comedi_insnlist</link> *<parameter>list</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
+allows to perform a list of instructions in one function
call. The number of instructions in the list is limited in the
implementation, because instructions are executed
<emphasis>synchronously</emphasis>, i.e., the call blocks until the
</para>
<para>
-Using INSN_CONFIG as the
+Using <constant>INSN_CONFIG</constant> as the
<link linkend="insn-data-structure-insn">insn</link> flag in an
<link linkend="insn-data-structure">instruction data structure</link>
indicates that the instruction will
</thead>
<tbody>
<row>
-<entry>INSN_CONFIG_DIO_INPUT</entry>
+<entry><constant>INSN_CONFIG_DIO_INPUT</constant></entry>
<entry>
Configure a dio line as input. It is easier to use comedi_dio_config() than
to use this configuration instruction directly.
</entry>
</row>
<row>
-<entry>INSN_CONFIG_DIO_OUTPUT</entry>
+<entry><constant>INSN_CONFIG_DIO_OUTPUT</constant></entry>
<entry>
Configure a dio line as output. It is easier to use comedi_dio_config() than
to use this configuration instruction directly.
</entry>
</row>
<row>
-<entry>INSN_CONFIG_ALT_SOURCE</entry>
+<entry><constant>INSN_CONFIG_ALT_SOURCE</constant></entry>
<entry>
Select an alternate input source. This instruction is
used by comedi_calibrate to configure analog input channels
</entry>
</row>
<row>
-<entry>INSN_CONFIG_BLOCK_SIZE</entry>
+<entry><constant>INSN_CONFIG_BLOCK_SIZE</constant></entry>
<entry>
Specify block size for asynchonous command data.
When performing streaming input, many boards accumulate
</entry>
</row>
<row>
-<entry>INSN_CONFIG_DIO_QUERY</entry>
+<entry><constant>INSN_CONFIG_DIO_QUERY</constant></entry>
<entry>
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 comedi_dio_get_config()
</entry>
<entry>2</entry>
<entry>
-data[1]: The instruction sets this element to either COMEDI_INPUT or COMEDI_OUTPUT.
+data[1]: The instruction sets this element to either
+<constant>COMEDI_INPUT</constant> or <constant>COMEDI_OUTPUT</constant>.
</entry>
</row>
</tbody>
</title>
<para>
This special instruction has
-<anchor id="insn-inttrig"/>INSN_INTTRIG as the
+<anchor id="insn-inttrig"/><constant>INSN_INTTRIG</constant> as the
<link linkend="insn-data-structure-insn">insn</link> flag in its
<link linkend="insn-data-structure">instruction data structure</link>.
Its execution causes an
<para>
The
<link linkend="insn-data-structure-data">data</link>[0] field of the
-INSN_INTTRIG instruction is reserved for future use, and should be set
-to <quote>0</quote>.
+<constant>INSN_INTTRIG</constant> instruction is reserved for future use,
+and should be set to <literal>0</literal>.
</para>
</section>
</title>
<para>
-A commands is executed by the following &comedi; function:
-<programlisting>
- int <link linkend="func-ref-comedi-command">comedi_command</link>(<link linkend="ref-type-comedi-t">comedi_t</link> * device, <link linkend="ref-type-comedi-cmd">comedi_cmd</link> * command);
-</programlisting>
+A command is executed by the following &comedi; function:
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-command"><function>comedi_command</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef><link linkend="ref-type-comedi-cmd">comedi_cmd</link> *<parameter>command</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
The following sections explain the meaning of the
<link linkend="ref-type-comedi-cmd">comedi_cmd</link> data structure.
Filling in this structure can be quite complicated, and
<programlisting>
typedef struct comedi_cmd_struct comedi_cmd;
-struct comedi_cmd_struct{
+struct comedi_cmd_struct {
unsigned int subdev; // which subdevice to sample
unsigned int <anchor id="command-data-struct-flags"/>flags; // encode some configuration possibilities
// of the command execution; e.g.,
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
-<function>kcomedilib</function> interface, in which case they specify
+<systemitem>kcomedilib</systemitem> interface, in which case they specify
the buffer where the driver should write/read its data to/from.
</para>
For example, to specify an external digital line <quote>3</quote> as a
source (in general, <emphasis>any</emphasis> of the five event
sources), you would use
-<parameter>src</parameter>=<link linkend="trig-ext">TRIG_EXT</link> and
-<parameter>arg</parameter>=3.
+<parameter>src</parameter>=<link linkend="trig-ext"><constant>TRIG_EXT</constant></link>
+and <parameter>arg</parameter>=<literal>3</literal>.
</para>
<para>
The following paragraphs discuss in somewhat more detail the trigger
<listitem>
<para>
<anchor id="trig-now-start-src"/>
-TRIG_NOW: the
+<constant>TRIG_NOW</constant>: the
<link linkend="command-data-struct-start-src">start_src</link>
event occurs
<link linkend="command-data-struct-start-arg">start_arg</link>
<listitem>
<para>
<anchor id="trig-follow-start-src"/>
-TRIG_FOLLOW: (For an output device.) The
+<constant>TRIG_FOLLOW</constant>: (For an output device.) The
<link linkend="command-data-struct-start-src">start_src</link>
event occurs when data is written to the buffer.
</para>
<listitem>
<para>
<anchor id="trig-ext-start-src"/>
-TRIG_EXT: the start event occurs when an external trigger signal
-occurs; e.g., a rising edge of a digital line.
+<constant>TRIG_EXT</constant>: the start event occurs when an
+external trigger signal occurs; e.g., a rising edge of a digital line.
<link linkend="command-data-struct-start-arg">start_arg</link>
chooses the particular digital line.
</para>
<listitem>
<para>
<anchor id="trig-int-start-src"/>
-TRIG_INT: the start event occurs on a &comedi; internal signal, which
-is typically caused by an
-<link linkend="insn-inttrig">INSN_INTTRIG instruction</link>.
+<constant>TRIG_INT</constant>: the start event occurs on a &comedi;
+internal signal, which is typically caused by an
+<link linkend="insn-inttrig"><constant>INSN_INTTRIG</constant>
+instruction</link>.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-timer-start-scan"/>
-TRIG_TIMER:
+<constant>TRIG_TIMER</constant>:
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
events occur periodically. The time between
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
<listitem>
<para>
<anchor id="trig-follow-start-scan"/>
-TRIG_FOLLOW: The
+<constant>TRIG_FOLLOW</constant>: The
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
event occurs immediately after a
<link linkend="command-data-struct-scan-end-src">scan_end</link>
<listitem>
<para>
<anchor id="trig-ext-start-scan"/>
-TRIG_EXT: the
+<constant>TRIG_EXT</constant>: the
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
event occurs when an external trigger signal
occurs; e.g., a rising edge of a digital line.
<para>
<anchor id="convert-trig-timer"/>
<anchor id="trig-timer"/>
-TRIG_TIMER: the conversion events occur periodically. The time
-between convert events is
+<constant>TRIG_TIMER</constant>: the conversion events occur periodically.
+The time between convert events is
<link linkend="command-data-struct-convert-arg">convert_arg</link>
nanoseconds.
</para>
<para>
<anchor id="convert-trig-ext"/>
<anchor id="trig-ext"/>
-TRIG_EXT: the conversion events occur when an external trigger signal
-occurs, e.g., a rising edge of a digital line.
+<constant>TRIG_EXT</constant>: the conversion events occur when an
+external trigger signal occurs, e.g., a rising edge of a digital line.
<link linkend="command-data-struct-convert-arg">convert_arg</link>
chooses the particular digital line.
</para>
<para>
<anchor id="convert-trig-now"/>
<anchor id="trig-now"/>
-TRIG_NOW: All conversion events in a
+<constant>TRIG_NOW</constant>: All conversion events in a
<link linkend="scan">scan</link> occur simultaneously.
</para>
</listitem>
</itemizedlist>
The <emphasis>end</emphasis> of each scan is almost always specified
using
-<link linkend="trig-count">TRIG_COUNT</link>, with the argument being
-the same as the number of channels in the
+<link linkend="trig-count"><constant>TRIG_COUNT</constant></link>,
+with the argument being the same as the number of channels in the
<link linkend="command-data-struct-chanlist">chanlist</link>. You
could probably find a device that allows something else, but it would
be strange.
<para>
<anchor id="acquisition-end-trig-count"/>
<anchor id="trig-count"/>
-TRIG_COUNT: stop the acquisition after
+<constant>TRIG_COUNT</constant>: stop the acquisition after
<link linkend="command-data-struct-stop-arg">stop_arg</link>
scans.
</para>
<para>
<anchor id="acquisition-end-trig-none"/>
<anchor id="trig-none"/>
-TRIG_NONE: perform continuous acquisition, until stopped using
+<constant>TRIG_NONE</constant>: perform continuous acquisition,
+until stopped using
<link linkend="func-ref-comedi-cancel">comedi_cancel()</link>.
</para>
<para>
-Its argument is reserved and should be set to 0.
+Its argument is reserved and should be set to <literal>0</literal>.
(<quote>Reserved</quote>
means that unspecified things could happen if it is set to something
-else but 0.)
+else but <literal>0</literal>.)
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-time"/>
-TRIG_TIME:
+<constant>TRIG_TIME</constant>:
cause an event to occur at a particular time.
</para>
<para>
<listitem>
<para>
<anchor id="trigother-event"/>
-TRIG_OTHER: driver specific event trigger.
+<constant>TRIG_OTHER</constant>: driver specific event trigger.
</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.
-Configuration of TRIG_OTHER features are done by
-<link linkend="instructionsconfiguration">INSN_CONFIG</link>
+Configuration of <constant>TRIG_OTHER</constant> features are done by
+<link linkend="instructionsconfiguration"><constant>INSN_CONFIG</constant></link>
instructions.
</para>
<para>
-The argument is reserved and should be set to 0.
+The argument is reserved and should be set to <literal>0</literal>.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-rt"/>
-TRIG_RT: ask the driver to use a
+<constant>TRIG_RT</constant>: ask the driver to use a
<emphasis role="strong">hard real-time</emphasis> interrupt handler.
This will reduce latency in handling interrupts from your data
aquisition
<listitem>
<para>
<anchor id="trig-wake-eos"/>
-TRIG_WAKE_EOS:
+<constant>TRIG_WAKE_EOS</constant>:
where <quote>EOS</quote> stands for <quote>End of Scan</quote>. Some
drivers will change their behaviour when this flag is set, trying to
transfer data at the end of every scan (instead of, for example,
<listitem>
<para>
<anchor id="trig-round-nearest"/>
-TRIG_ROUND_NEAREST:
+<constant>TRIG_ROUND_NEAREST</constant>:
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
<listitem>
<para>
<anchor id="trig-round-down"/>
-TRIG_ROUND_DOWN: round period down.
+<constant>TRIG_ROUND_DOWN</constant>: round period down.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-round-up"/>
-TRIG_ROUND_UP: round period up.
+<constant>TRIG_ROUND_UP</constant>: round period up.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-round-up-next"/>
-TRIG_ROUND_UP_NEXT:
+<constant>TRIG_ROUND_UP_NEXT</constant>:
this one doesn't do anything, and I don't know what it was intended
to do…?
</para>
<listitem>
<para>
<anchor id="trig-dither"/>
-TRIG_DITHER: enable dithering? Dithering is a software technique to
-smooth the influence of discretization <quote>noise</quote>.
+<constant>TRIG_DITHER</constant>: enable dithering? Dithering is
+a software technique to smooth the influence of discretization
+<quote>noise</quote>.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-deglitch"/>
-TRIG_DEGLITCH: enable deglitching? Another <quote>noise</quote>
-smoothing technique.
+<constant>TRIG_DEGLITCH</constant>: enable deglitching?
+Another <quote>noise</quote> smoothing technique.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-write"/>
-TRIG_WRITE:
+<constant>TRIG_WRITE</constant>:
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.
<listitem>
<para>
<anchor id="trig-bogus"/>
-TRIG_BOGUS: do the motions?
+<constant>TRIG_BOGUS</constant>: do the motions?
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-other"/>
-TRIG_CONFIG: perform configuration, not triggering. This is a legacy
-of the deprecated
+<constant>TRIG_CONFIG</constant>: perform configuration, not triggering.
+This is a legacy of the deprecated
<link linkend="ref-type-comedi-cmd">comedi_trig_struct</link>
data structure, and has no function at present.
</para>
As you might have guessed, the &comedi; library has functions
to help you in your quest to accurately measure slowly varying
inputs:
-<programlisting>
- int <link linkend="func-ref-comedi-sv-init">comedi_sv_init</link>(<link linkend="ref-type-comedi-sv-t">comedi_sv_t</link> * sv, <link linkend="ref-type-comedi-t">comedi_t</link> * device, unsigned int subdevice, unsigned int channel);
-</programlisting>
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-sv-init"><function>comedi_sv_init</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-sv-t">comedi_sv_t</link> *<parameter>sv</parameter></paramdef>
+<paramdef><link linkend="ref-type-comedi-t">comedi_t</link> *<parameter>device</parameter></paramdef>
+<paramdef>unsigned int <parameter>subdevice</parameter></paramdef>
+<paramdef>unsigned int <parameter>channel</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
This function initializes the
<link linkend="ref-type-comedi-sv-t">comedi_sv_t</link> data structure, used
to do the averaging acquisition:
<programlisting>
-struct comedi_sv_struct{
+struct comedi_sv_struct {
<link linkend="ref-type-comedi-t">comedi_t</link> *dev;
unsigned int subdevice;
unsigned int chan;
lsampl_t maxdata;
};
</programlisting>
-The actual acquisition is done with:
-<programlisting>
- int <link linkend="func-ref-comedi-sv-measure">comedi_sv_measure</link>(<link linkend="ref-type-comedi-sv-t">comedi_sv_t</link> * sv, double * data);
-</programlisting>
+
+The actual acquisition is done with the function
+
+<funcsynopsis><funcprototype>
+<funcdef>int <link linkend="func-ref-comedi-sv-measure"><function>comedi_sv_measure</function></link></funcdef>
+<paramdef><link linkend="ref-type-comedi-sv-t">comedi_sv_t</link> *<parameter>sv</parameter></paramdef>
+<paramdef>double *<parameter>data</parameter></paramdef>
+</funcprototype></funcsynopsis>
+
The number of samples over which the
<function>comedi_sv_measure()</function> averages is limited by the
implementation (currently the limit is 100 samples).
output value due to positive or negative transitions of the
sensitive input. For each transition direction, there are two
bits defined as follows:
-<simplelist>
-
-<member>
-00: transition is ignored.
-</member>
-
-<member>
-01: accumulator is incremented, or output is set.
-</member>
-<member>
-10: accumulator is decremented, or output is cleared.
-</member>
+<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>
-<member>
-11: reserved.
-</member>
-
-</simplelist>
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
to configure an extended trigger, and a
<link linkend="commandsstreaming">command</link>,
specifying
-<link linkend="trig-other">TRIG_OTHER</link> as one of the trigger
-sources.
+<link linkend="trig-other"><constant>TRIG_OTHER</constant></link>
+as one of the trigger sources.
</para>
<para>
<itemizedlist>
<listitem>
<para>
-COMEDI_EV_START
+<constant>COMEDI_EV_START</constant>
</para>
</listitem>
<listitem>
<para>
-COMEDI_EV_SCAN_BEGIN
+<constant>COMEDI_EV_SCAN_BEGIN</constant>
</para>
</listitem>
<listitem>
<para>
-COMEDI_EV_CONVERT
+<constant>COMEDI_EV_CONVERT</constant>
</para>
</listitem>
<listitem>
<para>
-COMEDI_EV_SCAN_END
+<constant>COMEDI_EV_SCAN_END</constant>
</para>
</listitem>
<listitem>
<para>
-COMEDI_EV_STOP
+<constant>COMEDI_EV_STOP</constant>
</para>
</listitem>
</itemizedlist>
The <link linkend="insn-data-structure-data">data</link> field
of the <link linkend="insn-data-structure">instruction data
structure</link> is used as follows:
-<simplelist>
- <member>
-data[1]: trigger and combining machine configuration.
- </member>
- <member>
-data[2]: analog triggering signal chanspec.
- </member>
- <member>
-data[3]: primary analog level.
- </member>
- <member>
-data[4]: secondary analog level.
- </member>
-</simplelist>
+<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>
</para>
<para>
Analog triggering is described by a digital combining machine that
<para>
If only one analog comparator signal is used, the combining machine
for the secondary input should be set to ignored, and the secondary
-analog level should be set to 0.
+analog level should be set to <literal>0</literal>.
</para>
<para>
of the <link linkend="insn-data-structure">instruction data
structure</link> is used as follows:
</para>
-<simplelist>
- <member>
-data[1]: trigger flags.
- </member>
- <member>
-data[2]: mask.
- </member>
- <member>
-data[3]: pattern.
- </member>
-</simplelist>
+<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>
<para>
The pattern matching trigger issues a trigger when all of a specifed
<para>
Discovery: The number of bits can be discovered by setting the mask
-to all 1's. The driver must modify this value and return -EAGAIN.
+to all 1's. The driver must modify this value and return
+<constant>-EAGAIN</constant>.
</para>
</section>
of the <link linkend="insn-data-structure">instruction data
structure</link> is used as follows:
</para>
-<simplelist>
- <member>
-data[1]: trigger configuration.
- </member>
- <member>
-data[2]: primary input chanspec.
- </member>
- <member>
-data[3]: primary combining machine configuration.
- </member>
- <member>
-data[4]: secondary input chanspec.
- </member>
- <member>
-data[5]: secondary combining machine configuration.
- </member>
- <member>
-data[6]: latch configuration.
- </member>
-</simplelist>
+<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>
<para>
Note that this configuration is only useful if the counting has to be
</para>
<para>
Counters can be operated either in synchronous mode (using
-<link linkend="comediinsnstructure">INSN_READ</link>)
+<link linkend="comediinsnstructure"><constant>INSN_READ</constant></link>)
or asynchronous mode (using
<link linkend="commandsstreaming">commands</link>), similar to analog
input subdevices.
The input signal for both modes is the accumulator.
Commands on counter subdevices are almost always specified using
<link linkend="command-data-struct-scan-begin-src">scan_begin_src</link>
-= <link linkend="trigother-event">TRIG_OTHER</link>, with the
-counter configuration also serving as the extended configuration for
+= <link linkend="trigother-event"><constant>TRIG_OTHER</constant></link>,
+with the counter configuration also serving as the extended configuration for
the scan begin source.
</para>
</para>
<para>
-<simplelist>
- <member>
-data[1]: is flags, including the flags for the command triggering
+<variablelist spacing="compact">
+ <varlistentry>
+ <term>data[1]</term>
+ <listitem>
+is flags, including the flags for the command triggering
configuration. If a command is not subsequently issued on the
subdevice, the command triggering portion of the flags are ignored.
- </member>
- <member>
-data[2]: determines the mode of operation. The mode of operation
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>data[2]</term>
+ <listitem>
+determines the mode of operation. The mode of operation
is actually a bitfield that encodes what to do for various
transitions of the source signals.
-</member>
-
-<member>
-data[3], data[4]: determine the primary source for the counter,
-similar to the
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>data[3]</term>
+ <term>data[4]</term>
+ <listitem>
+determine the primary source for the counter, similar to the
<link linkend="command-data-struct-scan-begin-src">_src</link> and the
<link linkend="command-data-struct-scan-begin-arg">_arg</link> fields
used in the
<link linkend="command-data-struct">command data structure</link>.
-</member>
-
-</simplelist>
+ </listitem>
+ </varlistentry>
+</variablelist>
</para>
<para>
</para>
<para>
The subdevice also supports the
-INSN_CONFIG_SET_CLOCK_SRC and INSN_CONFIG_GET_CLOCK_SRC configuration
+<constant>INSN_CONFIG_SET_CLOCK_SRC</constant> and
+<constant>INSN_CONFIG_GET_CLOCK_SRC</constant> configuration
instructions, which can be
used to configure/query what source the board uses to synchronize its
master clock to. The various possibilities are defined in the comedi.h
</thead>
<tbody>
<row>
-<entry>NI_MIO_INTERNAL_CLOCK</entry>
+<entry><constant>NI_MIO_INTERNAL_CLOCK</constant></entry>
<entry>
Use the board's internal oscillator.
</entry>
</row>
<row>
-<entry>NI_MIO_RTSI_CLOCK</entry>
+<entry><constant>NI_MIO_RTSI_CLOCK</constant></entry>
<entry>
Use the RTSI line 7 as the master clock. This source is
only supported on pre-m-series boards. The newer m-series boards
</entry>
</row>
<row>
-<entry>NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK</entry>
+<entry><constant>NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK</constant></entry>
<entry>
Only available for newer m-series PXI boards. Synchronizes the board's
phased-locked loop (which runs at 80MHz) to the PXI star trigger
</entry>
</row>
<row>
-<entry>NI_MIO_PLL_PXI10_CLOCK</entry>
+<entry><constant>NI_MIO_PLL_PXI10_CLOCK</constant></entry>
<entry>
Only available for newer m-series PXI boards.
Synchronizes the board's
</entry>
</row>
<row>
-<entry><programlisting>unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned n)</programlisting></entry>
+<entry>
+<function>NI_MIO_PLL_RTSI_CLOCK<parameter>n</parameter></function>
+</entry>
<entry>
Only available for newer m-series boards.
The function returns a clock source which will cause the board's
</informaltable>
<para>
-For all clock sources except NI_MIO_INTERNAL_CLOCK and NI_MIO_PLL_PXI10_CLOCK,
+For all clock sources except <constant>NI_MIO_INTERNAL_CLOCK</constant>
+and <constant>NI_MIO_PLL_PXI10_CLOCK</constant>,
you should pass the period of the clock your are feeding to the board when
-using INSN_CONFIG_SET_CLOCK_SRC.
+using <constant>INSN_CONFIG_SET_CLOCK_SRC</constant>.
</para>
<para>
-Finally, the configuration instructions INSN_CONFIG_SET_ROUTING and
-INSN_CONFIG_GET_ROUTING can be used to select/query which internal signal
+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
will appear on a given RTSI output line. The header file comedi.h defines
the following signal sources which can be routed to an RTSI line:
</para>
</thead>
<tbody>
<row>
-<entry>NI_RTSI_OUTPUT_ADR_START1</entry>
+<entry><constant>NI_RTSI_OUTPUT_ADR_START1</constant></entry>
<entry>
ADR_START1, an analog input start signal. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_ADR_START2</entry>
+<entry><constant>NI_RTSI_OUTPUT_ADR_START2</constant></entry>
<entry>
ADR_START2, an analog input stop signal. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_SCLKG</entry>
+<entry><constant>NI_RTSI_OUTPUT_SCLKG</constant></entry>
<entry>
SCLKG, a sample clock signal. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_DACUPDN</entry>
+<entry><constant>NI_RTSI_OUTPUT_DACUPDN</constant></entry>
<entry>
DACUPDN, a dac update signal. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_DA_START1</entry>
+<entry><constant>NI_RTSI_OUTPUT_DA_START1</constant></entry>
<entry>
DA_START1, an analog output start signal. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_G_SRC0</entry>
+<entry><constant>NI_RTSI_OUTPUT_G_SRC0</constant></entry>
<entry>
G_SRC0, the source signal to general purpose counter 0. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_G_GATE0</entry>
+<entry><constant>NI_RTSI_OUTPUT_G_GATE0</constant></entry>
<entry>
G_GATE0, the gate signal to general purpose counter 0. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_RGOUT0</entry>
+<entry><constant>NI_RTSI_OUTPUT_RGOUT0</constant></entry>
<entry>
RGOUT0, the output signal of general purpose counter 0. See the NI's
DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry><programlisting>unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)</programlisting></entry>
+<entry>
+<function>NI_RTSI_OUTPUT_RTSI_BRD<parameter>n</parameter></function>
+</entry>
<entry>
RTSI_BRD0 though RTSI_BRD3 are four internal signals which can
have various other signals routed to them in turn. Currently, comedi
</entry>
</row>
<row>
-<entry>NI_RTSI_OUTPUT_RTSI_OSC</entry>
+<entry><constant>NI_RTSI_OUTPUT_RTSI_OSC</constant></entry>
<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
<para>
The RTSI bus pins may be used as trigger inputs for many of the
-COMEDI trigger functions. To use the RTSI bus pins, set the source to be
-TRIG_EXT and the source argument using the return values from the
-NI_EXT_RTSI() function (or similarly the NI_EXT_PFI() function if you want
-to trigger from a PFI line). The CR_EDGE and CR_INVERT flags may
+&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
+from the <function>NI_EXT_RTSI()</function> function (or similarly the
+<function>NI_EXT_PFI()</function> function if you want
+to trigger from a PFI line). The <constant>CR_EDGE</constant> and
+<constant>CR_INVERT</constant> flags may
also be set on the trigger source argument to specify edge and
falling edge/low level triggering.
</para>
<programlisting><![CDATA[
-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);
- }
+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);
+ }
}
]]></programlisting>
<para>
An example to slave a m-series device from this master follows. A pre-m-series
-device would need to use NI_MIO_RTSI_CLOCK for the clock source instead. In
+device would need to use <constant>NI_MIO_RTSI_CLOCK</constant> for
+the clock source instead. In
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).
</para>
<programlisting><![CDATA[
-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);
- }
+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);
+ }
}
-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;
+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;
}
]]></programlisting>