</title>
<para>
-This Section gives an overview of all &comedi; functions with which
+This Section gives an overview of all &comedi; functions with which
application programmers can implement their data acquisition. (With
<quote>acquisition</quote> we mean all possible kinds of interfacing
with the cards: input, output, configuration, streaming, etc.)
<link linkend="func-ref-comedi-dio-config">comedi_dio_config</link>(device,subdevice,channel,unsigned int dir);
</programlisting>
The parameter <parameter class=function>dir</parameter> should be
-either <literal>COMEDI_INPUT</literal> or
+either <literal>COMEDI_INPUT</literal> or
<literal>COMEDI_OUTPUT</literal>.
Many digital I/O subdevices group channels into blocks for
configuring direction. Changing one channel in a block changes
<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.
-Each digital line is then read and placed into
+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>12</literal>, or <literal>16</literal> bits.
</para>
<para>
-The
+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,
+ 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,
+ 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>
works in the opposite direction. Data values returned by this function
<listitem>
<para>
-<link linkend="ref-type-lsampl-t">lsampl_t</link>: this
+<link linkend="ref-type-lsampl-t">lsampl_t</link>: this
<quote>data structure</quote> represents one single sample. On most
architectures, it's nothing more than a 32 bits value. Internally,
&comedi; does some conversion from raw sample data to
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,
+ 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>
The number of samples, <parameter class=function>n</parameter>, is
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,
+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>
All these read and write acquisition functions are implemented on top
<section id="instructions">
<title>
-Instructions for multiple acquisitions
+Instructions for multiple acquisitions
</title>
<para>
The <emphasis>instruction</emphasis> is one of the most generic,
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
-of &comedi; requires the
+of &comedi; requires the
<link linkend="insn-data-structure-data">data</link> field to be at
least one byte long.
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> flag of the
-<link linkend="insn-data-structure">instruction data structure</link>
+The <link linkend="insn-data-structure-insn">insn</link> flag of the
+<link linkend="insn-data-structure">instruction data structure</link>
determines the type of acquisition executed in the corresponding
instruction:
<itemizedlist>
<listitem>
<para>
-INSN_WRITE: the instruction executes a write on an analog channel.
+INSN_WRITE: the instruction executes a write on an analog channel.
</para>
</listitem>
-
+
<listitem>
<para>
INSN_BITS: indicates that the instruction must
</para>
</section>
-
+
</section>
For example, the configuration of digital I/O channels is done as
follows. The
<link linkend="ref-macro-CR-PACK">chanspec</link> field in the
-<link linkend="insn-data-structure-chanspec">comedi_insn</link>
+<link linkend="insn-data-structure-chanspec">comedi_insn</link>
data structure, contains the channel to be configured. And
<link linkend="insn-data-structure-data">data</link>[0] contains
either COMEDI_INPUT or COMEDI_OUTPUT, depending on the desired
Instruction for internal triggering
</title>
<para>
-This special instruction has
+This special instruction has
<anchor id="insn-inttrig">INSN_INTTRIG as the
<link linkend="insn-data-structure-insn">insn</link> flag in its
<link linkend="insn-data-structure">instruction data structure</link>.
depends on the card and its particular driver.
</para>
<para>
-The
+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>.
<listitem>
<para>
accompanied with various <emphasis>callback</emphasis> functionalities
-(DMA, interrupts, driver-specific callback functions),
+(DMA, interrupts, driver-specific callback functions),
</para>
</listitem>
<listitem>
<para>
-for <emphasis>any number of channels</emphasis>,
+for <emphasis>any number of channels</emphasis>,
</para>
</listitem>
<listitem>
<para>
with an <emphasis>arbitrary order</emphasis> of channels in each scan
-(possibly even with repeated channels per scan),
+(possibly even with repeated channels per scan),
</para>
</listitem>
<para>
and with various scan <emphasis>triggering sources</emphasis>,
external (i.e., hardware pulses) as well as internal (i.e., pulses
-generated on the DAQ card itself, or generated by a
+generated on the DAQ card itself, or generated by a
<link linkend="inttrigconfiguration">software trigger instruction</link>).
</para>
</listitem>
</para>
<para>
-A command specifies a particular data
+A command specifies a particular data
<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
<para>
The command function is complementary to the
<link linkend="instructionsconfiguration">configuration instruction</link>
-function: each channel in the command's
+function: each channel in the command's
<link linkend="command-data-struct-chanlist">chanlist</link>
should first be configured by an appropriate instruction.
</para>
<link linkend="func-ref-comedi-get-cmd-src-mask">comedi_get_cmd_src_mask()</link>
function.
</para>
-
+
</section>
<para>
The command executes according to the information about the requested
acquisition, which is stored in the
-<link linkend="ref-type-comedi-cmd">comedi_cmd</link>
+<link linkend="ref-type-comedi-cmd">comedi_cmd</link>
<anchor id="command-data-struct">data structure:
<programlisting>
typedef struct comedi_cmd_struct comedi_cmd;
struct comedi_cmd_struct{
unsigned int subdev; // which subdevice to sample
- unsigned int <anchor id="command-data-struct-flags">flags; // encode some configuration possibilities
+ unsigned int <anchor id="command-data-struct-flags">flags; // encode some configuration possibilities
// of the command execution; e.g.,
// whether a callback routine is to be
// called at the end of the command
<link linkend="command-data-struct">comedi_cmd</link> structure is the
<link linkend="command-data-struct-flags">flags</link> field,
i.e., bits in a word that can be bitwise-or'd together. The meaning of
-these bits are explained in a
+these bits are explained in a
<link linkend="source.flags.anchor">later section</link>.
</para>
software sources determine when acquisitions are started, performed,
and stopped. More specifically, the command
<link linkend="command-data-struct">data structure</link>
-has <emphasis>five</emphasis> types of events: start the
+has <emphasis>five</emphasis> types of events: start the
<link linkend="acquisitionterminology">acquisition</link>,
-start a <link linkend="scan">scan</link>, start a
+start a <link linkend="scan">scan</link>, start a
<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>
structure). And each event source can have a corresponding
argument (the <parameter class=function>*_arg</parameter> members of
the <link linkend="ref-type-comedi-cmd">comedi_cmd</link> data
-structure) whose meaning depends on the type of source trigger.
+structure) whose meaning depends on the type of source trigger.
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
<para>
<anchor id="trig-now-start-src">
TRIG_NOW: the
-<link linkend="command-data-struct-start-src">start_src</link>
-event occurs
-<link linkend="command-data-struct-start-arg">start_arg</link>
+<link linkend="command-data-struct-start-src">start_src</link>
+event occurs
+<link linkend="command-data-struct-start-arg">start_arg</link>
nanoseconds after the
-<link linkend="ref-type-comedi-cmd">comedi_cmd</link>
-is called. Currently, only
+<link linkend="ref-type-comedi-cmd">comedi_cmd</link>
+is called. Currently, only
<link linkend="command-data-struct-start-arg">start_arg</link>=0 is
supported.
</para>
<listitem>
<para>
<anchor id="trig-follow-start-src">
-TRIG_FOLLOW: (For an output device.) The
+TRIG_FOLLOW: (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>
<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.
+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>
<para>
<anchor id="trig-int-start-src">
TRIG_INT: the start event occurs on a &comedi; internal signal, which
-is typically caused by an
+is typically caused by an
<link linkend="insn-inttrig">INSN_INTTRIG instruction</link>.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-timer-start-scan">
-TRIG_TIMER:
-<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
+TRIG_TIMER:
+<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>
+<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
events is
-<link linkend="command-data-struct-convert-arg">convert_arg</link>
+<link linkend="command-data-struct-convert-arg">convert_arg</link>
nanoseconds.
</para>
</listitem>
<listitem>
<para>
<anchor id="trig-ext-start-scan">
-TRIG_EXT: the
+TRIG_EXT: 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.
+occurs; e.g., a rising edge of a digital line.
<link linkend="command-data-struct-scan-begin-arg">scan_begin_arg</link>
chooses the particular digital line.
</para>
</listitem>
</itemizedlist>
-The
+The
<link linkend="command-data-struct-scan-begin-arg">scan_begin_arg</link>
used here may not be supported exactly by the device, but it
-will be adjusted to the nearest supported value by
+will be adjusted to the nearest supported value by
<link linkend="func-ref-comedi-command-test">comedi_command_test()</link>.
</para>
<para>
-The timing between each sample in a
+The timing between each sample in a
<link linkend="scan">scan</link> is controlled by the
<link linkend="command-data-struct-convert-src">convert_*</link>
fields:
<anchor id="convert-trig-timer">
<anchor id="trig-timer">
TRIG_TIMER: the conversion events occur periodically. The time
-between convert events is
+between convert events is
<link linkend="command-data-struct-convert-arg">convert_arg</link>
nanoseconds.
</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.
+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
+TRIG_NOW: 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
+using
<link linkend="trig-count">TRIG_COUNT</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.
+be strange.
</para>
<para>
The end of an
<para>
<anchor id="acquisition-end-trig-count">
<anchor id="trig-count">
-TRIG_COUNT: stop the acquisition after
+TRIG_COUNT: stop the acquisition after
<link linkend="command-data-struct-stop-arg">stop_arg</link>
scans.
</para>
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
-driver. The
+driver. The
<link linkend="func-ref-comedi-get-cmd-src-mask">comedi_get_cmd_src_mask()</link>
function is useful for determining what trigger sources a subdevice
supports.
</programlisting>
The number of samples over which the
<function>comedi_sv_measure()</function> averages is limited by the
-implementation (currently the limit is 100 samples).
+implementation (currently the limit is 100 samples).
</para>
<para>
<member>
10: accumulator is decremented, or output is cleared.
</member>
-
+
<member>
11: reserved.
</member>
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
this yet).)</emphasis>
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
<link linkend="instructionsconfiguration">configuration instructions</link>
to configure an extended trigger, and a
<link linkend="commandsstreaming">command</link>,
-specifying
+specifying
<link linkend="trig-other">TRIG_OTHER</link> as one of the trigger
sources.
</para>
</para>
<para>
-Extended triggers must use
+Extended triggers must use
<link linkend="insn-data-structure-data">data[1]</link> as flags. The
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
</para>
<para>
-Various types of extended triggers must use
+Various types of extended triggers must use
<link linkend="insn-data-structure-data">data[1]</link> to know which
event the extended trigger will be assigned to in the command
structure. The possible values are an OR'd mask of the following:
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
</simplelist>
<para>
-The pattern matching trigger issues a trigger when all of a specifed
+The pattern matching trigger issues a trigger when all of a specifed
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
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
<para>
Counters can be operated either in synchronous mode (using
<link linkend="comediinsnstructure">INSN_READ</link>)
-or asynchronous mode (using
+or asynchronous mode (using
<link linkend="commandsstreaming">commands</link>), similar to analog
-input subdevices.
+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>
</para>
<para>
-The <link linkend="insn-data-structure-insn">insn</link> field of the
+The <link linkend="insn-data-structure-insn">insn</link> field of the
<link linkend="insn-data-structure">instruction data structure</link>
has not been assigned yet.
</para>
<member>
data[3], data[4]: determine the primary source for the counter,
-similar to the
-<link linkend="command-data-struct-scan-begin-src">_src</link> and the
+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>.
National instruments RTSI trigger bus
</title>
<para>
-A number of NI boards support the RTSI bus. The RTSI Bus consists of an 48 pin
-IDC connector on the PCI-6143 and special bus signal lines on PXI boards.
-It's primary use is to synchronise multiple DAQ cards together.
-There are 8 digital signal lines that are bi-directional. Each of these signal lines
-can be configured as an input or output also the signal appearing on the output
-can be configured to one of many internal board timing signals. We have added
-basic RSTI support to enable a board to be set as a master and other boards to
-be set as slaves. To simplify the API and code we have hard-coded the actual
-set of internal timing signals that appear on the RTSI lines and just provide
-the ability to set the I/O direction of the lines. It would be good to add a
-new configure command to set up this routing to a different setup. The COMEDI
-API is provided as a Digital I/O subdevice number 10 with an extra config
-command to set up the master clock mode. This provides a number of configure
-commands through the COMEDI config API which can be accessed using the
-comedi_do_insn(), comedi_dio_config() and comedi_dio_get_config() functions.
-The config API calls are:
+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).
+The ni_pcimio, ni_atmio, and ni_mio_cs drivers expose the RTSI bus
+as a digital I/O subdevice (subdevice number 10).
+</para>
+<para>
+The functions comedi_dio_config() and comedi_dio_get_config() can be used on
+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
+INSN_CONFIG_SET_CLOCK_SRC and INSN_CONFIG_GET_CLOCK_SRC 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
+header file:
</para>
<informaltable>
<tgroup cols='2' align='left'>
<thead>
<row>
-<entry>API Command</entry>
+<entry>Clock Source</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
-<entry>INSN_CONFIG_SET_RTSI_CLOCK_MODE</entry>
+<entry>NI_MIO_INTERNAL_CLOCK</entry>
+<entry>
+Use the board's internal oscillator.
+</entry>
+</row>
+<row>
+<entry>NI_MIO_RTSI_CLOCK</entry>
<entry>
-This sets the boards main clock
-mode. The argument defines the setting as one of:
-COMEDI_RTSI_CLOCK_MODE_INTERNAL - Internal Clock.
-COMEDI_RTSI_CLOCK_MODE_OUTPUT - Run from internal clock and output this
-on the RTSI bus bit as RTSI_7.
-COMEDI_RTSI_CLOCK_MODE_SLAVE - Run from the clock on the RTSI bus bit
-RTSI_7.
-COMEDI_RTSI_CLOCK_MODE_MASTER - Output the clock on the RTSI bus bit as
-RTSI_7 and run from this external clock.
+Use the RTSI line 7 as the master clock. This source is
+only supported on pre-m-series boards. The newer m-series boards
+use NI_MIO_PLL_RTSI_CLOCK() instead.
</entry>
</row>
<row>
-<entry>INSN_CONFIG_DIO_OUTPUT</entry>
+<entry>NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK</entry>
<entry>
-Configure the "channel" bit as
-an output. Channel is one of NI_RTSI_[0-6]
+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.
</entry>
</row>
<row>
-<entry>INSN_CONFIG_DIO_INPUT</entry>
+<entry>NI_MIO_PLL_PXI10_CLOCK</entry>
<entry>
-Configure the "channel" bit as
-an input. Channel is one of NI_RTSI_[0-6].
+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.
</entry>
</row>
<row>
-<entry>INSN_CONFIG_DIO_QUERY</entry>
+<entry>unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned n)</entry>
<entry>
-Find the direction of one of the
-RTSI "channels". Channel is one of NI_RTSI_[0-6].
+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.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
+
+<para>
+For all clock sources except NI_MIO_INTERNAL_CLOCK and NI_MIO_PLL_PXI10_CLOCK,
+you should pass the period of the clock your are feeding to the board when
+using INSN_CONFIG_SET_CLOCK_SRC.
+</para>
<para>
-The RTSI bus pins and default output routing is:
+Finally, the configuration instructions INSN_CONFIG_SET_ROUTING and
+INSN_CONFIG_GET_ROUTING 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>
<informaltable>
<tgroup cols='2' align='left'>
<thead>
<row>
-<entry>Name</entry>
-<entry>Standard Routing</entry>
-<entry>Pin</entry>
+<entry>Signal Source</entry>
+<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
-<entry>RTSI_0
-</entry>
-<entry>NI_RTSI_STD_AI_START1
-</entry>
-<entry>20
+<entry>NI_RTSI_OUTPUT_ADR_START1</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>RTSI_1</entry>
-<entry>NI_RTSI_STD_AI_START2
-</entry>
-<entry>22
+<entry>NI_RTSI_OUTPUT_ADR_START2</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>RTSI_2</entry>
-<entry>NI_RTSI_STD_AI_CONV
-</entry>
-<entry>24
+<entry>NI_RTSI_OUTPUT_SCLKG</entry>
+<entry>
+SCLKG, a sample clock signal. See the NI's
+DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>RTSI_3</entry>
-<entry>NI_RTSI_STD_CT1_SRC
-</entry>
-<entry>26
+<entry>NI_RTSI_OUTPUT_DACUPDN</entry>
+<entry>
+DACUPDN, a dac update signal. See the NI's
+DAQ-STC Technical Reference Manual for more information.
</entry>
</row>
<row>
-<entry>RTSI_4</entry>
-<entry>NI_RTSI_STD_CT1_GATE
-</entry>
-<entry>28
+<entry>NI_RTSI_OUTPUT_DA_START1</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>RTSI_5</entry>
-<entry>NI_RTSI_STD_AO_SAMP_CLOCK
-</entry>
-<entry>30
+<entry>NI_RTSI_OUTPUT_G_SRC0</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>RTSI_6</entry>
-<entry>NI_RTSI_STD_AO_START_TRIG
-</entry>
-<entry>32
+<entry>NI_RTSI_OUTPUT_G_GATE0</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>RTSI_7 or RTSI_CLK
+<entry>NI_RTSI_OUTPUT_RGOUT0</entry>
+<entry>
+RGOUT0, the output signal of general purpose counter 0. See the NI's
+DAQ-STC Technical Reference Manual for more information.
</entry>
-<entry>Master Clock
+</row>
+<row>
+<entry>unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)</entry>
+<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.
</entry>
-<entry>34
+</row>
+<row>
+<entry>NI_RTSI_OUTPUT_RTSI_OSC</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
+m-series boards, any RTSI line can be configured to output the clock
+signal.
</entry>
</row>
</tbody>
</informaltable>
<para>
-The RTSI bus pins are available to 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 to be a value between 10 and 16 corresponding
-to RTSI_0 through RTSI_6. We have provided the defines NI_EXT_PFI_[0-9] and
-NI_EXT_RTSI_[0-6] to define all the available external trigger sources.
+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
+also be set on the trigger source argument to specify edge and
+falling edge/low level triggering.
+
</para>
<para>
-A simple example to set up a device as a master is given below.
+An example to set up a device as a master is given below.
</para>
<programlisting><![CDATA[
void comediEnableMaster(comedi_t* dev){
- comedi_insn configCmd;
- lsampl_t configData[2];
- int ret;
- unsigned int d = 0;
-
- // Configure the PFI bus device
- memset(&configCmd, 0, sizeof(configCmd));
- memset(&configData, 0, sizeof(configData));
- configCmd.insn = INSN_CONFIG;
- configCmd.subdev = 10;
- configCmd.chanspec = 0;
- configCmd.n = 2;
- configCmd.data = configData;
- configCmd.data[0] = INSN_CONFIG_SET_RTSI_CLOCK_MODE;
- configCmd.data[1] = COMEDI_RTSI_CLOCK_MODE_MASTER;
-
- ret = comedi_do_insn(dev, &configCmd);
- if(ret < 0){
- comedi_perror("comedi_command: INSN_CONFIG");
- exit(1);
- }
-
- // Set direction of the 3 main AI RTSI signals to output
- ret = comedi_dio_config(dev, 10, NI_RTSI_0, INSN_CONFIG_DIO_OUTPUT);
- ret = comedi_dio_config(dev, 10, NI_RTSI_1, INSN_CONFIG_DIO_OUTPUT);
- ret = comedi_dio_config(dev, 10, NI_RTSI_2, INSN_CONFIG_DIO_OUTPUT);
+ 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 device from this master follows:
+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
+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[2];
- int ret;
- unsigned int d = 0;;
-
- // Configure the PFI bus device
- memset(&configCmd, 0, sizeof(configCmd));
- memset(&configData, 0, sizeof(configData));
- configCmd.insn = INSN_CONFIG;
- configCmd.subdev = 10;
- configCmd.chanspec = 0;
- configCmd.n = 2;
- configCmd.data = configData;
- configCmd.data[0] = INSN_CONFIG_SET_RTSI_CLOCK_MODE;
- configCmd.data[1] = COMEDI_RTSI_CLOCK_MODE_SLAVE;
-
- ret = comedi_do_insn(dev, &configCmd);
- if(ret < 0){
- comedi_perror("comedi_command: INSN_CONFIG");
- exit(1);
- }
+ 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;
+ 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>