parse errors along the way (mostly unclosed tags).
AC_ARG_ENABLE([docbook],[ --disable-docbook-binding Disable docbook],[ENABLE_DOCBOOK=$enableval],[ENABLE_DOCBOOK="yes"])
if test "$ENABLE_DOCBOOK" == "yes"; then
- AC_PATH_PROG(DOCBOOK2MAN, docbook2man, no)
- if test "$DOCBOOK2MAN" = "no" ; then
- AC_MSG_WARN([docbook2man not found, will not be able to rebuild man pages])
+ AC_PATH_PROG(XMLTO, xmlto, no)
+ if test "$XMLTO" = "no" ; then
+ AC_MSG_WARN([xmlto not found, will not be able to rebuild documentation])
fi
else
- DOCBOOK2MAN="no"
+ XMLTO="no"
fi
-AM_CONDITIONAL(HAVE_DOCBOOK2MAN, [test "$DOCBOOK2MAN" != "no"])
-
-if test "$ENABLE_DOCBOOK" == "yes"; then
- AC_PATH_PROG(DOCBOOK2PDF, docbook2pdf, no)
- if test "$DOCBOOK2PDF" = "no" ; then
- AC_MSG_WARN([docbook2pdf not found, will not be able to rebuild pdf documentation])
- fi
-else
- DOCBOOK2PDF="no"
-fi
-AM_CONDITIONAL(HAVE_DOCBOOK2PDF, [test "$DOCBOOK2PDF" != "no"])
-
-
-if test "$ENABLE_DOCBOOK" == "yes"; then
- AC_PATH_PROG(DOCBOOK2HTML, docbook2html, no)
- if test "$DOCBOOK2HTML" = "no" ; then
- AC_MSG_WARN([docbook2html not found, will not be able to rebuild html documentation])
- fi
-else
- DOCBOOK2HTML="no"
-fi
-AM_CONDITIONAL(HAVE_DOCBOOK2HTML, [test "$DOCBOOK2HTML" != "no"])
-
+AM_CONDITIONAL(HAVE_XMLTO, [test "$XMLTO" != "no"])
pcmciadir="\${sysconfdir}/pcmcia"
AC_SUBST(pcmciadir)
-SGML = calibration_funcref.sgml command_funcref.sgml dio_funcref.sgml \
- deprecated_funcref.sgml error_funcref.sgml extensions_funcref.sgml \
- drivers.sgml funcref.sgml glossary.sgml \
- install.sgml intro.sgml other.sgml reference.sgml tutorial.sgml \
- driverwriting.sgml comedilib.sgml
+XML = calibration_funcref.xml command_funcref.xml dio_funcref.xml \
+ deprecated_funcref.xml error_funcref.xml extensions_funcref.xml \
+ drivers.xml funcref.xml glossary.xml \
+ install.xml intro.xml other.xml reference.xml tutorial.xml \
+ driverwriting.xml comedilib.xml
-EXTRA_DIST = $(SGML) calibration_funcref.txt command_funcref.txt dio_funcref.txt \
+EXTRA_DIST = $(XML) calibration_funcref.txt command_funcref.txt dio_funcref.txt \
deprecated_funcref.txt error_funcref.txt extensions_funcref.txt \
funcref mkref drivers.txt mkdr FAQ \
acq-seq.gif doc_html man
-BUILT_SOURCES = calibration_funcref.sgml command_funcref.sgml dio_funcref.sgml \
- deprecated_funcref.sgml error_funcref.sgml extensions_funcref.sgml \
- funcref.sgml drivers.sgml
+BUILT_SOURCES = calibration_funcref.xml command_funcref.xml dio_funcref.xml \
+ deprecated_funcref.xml error_funcref.xml extensions_funcref.xml \
+ funcref.xml drivers.xml
-if HAVE_DOCBOOK2PDF
-dist_pdf_DATA = comedilib.pdf
-else
-dist_pdf_DATA =
-endif
-
-if HAVE_DOCBOOK2HTML
+if HAVE_XMLTO
all_html = $(srcdir)/doc_html
install_html = install_html
uninstall_html = uninstall_html
-else
-all_html =
-install_html =
-uninstall_html =
-endif
-if HAVE_DOCBOOK2MAN
+#pdf output for xmlto is broken in debian etch
+#dist_pdf_DATA = comedilib.pdf
+dist_pdf_DATA =
+
all_man = $(srcdir)/man
install_man = install_man
uninstall_man = uninstall_man
else
+all_html =
+install_html =
+uninstall_html =
+
+dist_pdf_DATA =
+
all_man =
install_man =
uninstall_man =
#named this doc_html to avoid phony html target that is automatically generated
#(at least by automake1.8)
-$(srcdir)/doc_html: $(SGML)
- { $(DOCBOOK2HTML) -o $(srcdir)/doc_html $(srcdir)/comedilib.sgml && touch $(srcdir)/doc_html; } || { $(RM) -r $(srcdir)/doc_html; exit 1; }
+$(srcdir)/doc_html: $(XML)
+ { $(XMLTO) -o $(srcdir)/doc_html -m $(srcdir)/comedilib_html_config.xsl --skip-validation html $(srcdir)/comedilib.xml && touch $(srcdir)/doc_html; } || { $(RM) -r $(srcdir)/doc_html; exit 1; }
install_html:
$(mkdir_p) $(DESTDIR)$(htmldir)/html
for each in $(srcdir)/doc_html/*.html $(srcdir)/*.gif ; do \
$(RM) $(DESTDIR)$(htmldir)/html/`basename $$each` ; done
-$(srcdir)/man: $(SGML)
- { $(DOCBOOK2MAN) -o $(srcdir)/man $(srcdir)/comedilib.sgml && touch $(srcdir)/man; } || { $(RM) -r $(srcdir)/man; exit 1; }
+$(srcdir)/man: $(XML)
+ { $(XMLTO) -o $(srcdir)/man --skip-validation man $(srcdir)/comedilib.xml && touch $(srcdir)/man; } || { $(RM) -r $(srcdir)/man; exit 1; }
install_man:
$(mkdir_p) -m 755 $(DESTDIR)$(mandir)/man3
uninstall_man:
for each in `find $(srcdir)/man/ -name '*.3'`; do $(RM) $(DESTDIR)$(mandir)/man3/`basename $$each` ; done
-comedilib.pdf: $(SGML)
- $(DOCBOOK2PDF) -o $(srcdir) $(srcdir)/comedilib.sgml
+comedilib.pdf: $(XML)
+ $(XMLTO) -o $(srcdir)/pdf --skip-validation pdf $(srcdir)/comedilib.xml
-funcref.sgml: funcref mkref
- $(srcdir)/mkref $(srcdir)/funcref >$(srcdir)/funcref.sgml
+funcref.xml: funcref mkref
+ $(srcdir)/mkref $(srcdir)/funcref >$(srcdir)/funcref.xml
-calibration_funcref.sgml: calibration_funcref.txt mkref
- $(srcdir)/mkref $(srcdir)/calibration_funcref.txt >$(srcdir)/calibration_funcref.sgml
+calibration_funcref.xml: calibration_funcref.txt mkref
+ $(srcdir)/mkref $(srcdir)/calibration_funcref.txt >$(srcdir)/calibration_funcref.xml
-command_funcref.sgml: command_funcref.txt mkref
- $(srcdir)/mkref $(srcdir)/command_funcref.txt >$(srcdir)/command_funcref.sgml
+command_funcref.xml: command_funcref.txt mkref
+ $(srcdir)/mkref $(srcdir)/command_funcref.txt >$(srcdir)/command_funcref.xml
-dio_funcref.sgml: dio_funcref.txt mkref
- $(srcdir)/mkref $(srcdir)/dio_funcref.txt >$(srcdir)/dio_funcref.sgml
+dio_funcref.xml: dio_funcref.txt mkref
+ $(srcdir)/mkref $(srcdir)/dio_funcref.txt >$(srcdir)/dio_funcref.xml
-deprecated_funcref.sgml: deprecated_funcref.txt mkref
- $(srcdir)/mkref $(srcdir)/deprecated_funcref.txt >$(srcdir)/deprecated_funcref.sgml
+deprecated_funcref.xml: deprecated_funcref.txt mkref
+ $(srcdir)/mkref $(srcdir)/deprecated_funcref.txt >$(srcdir)/deprecated_funcref.xml
-error_funcref.sgml: error_funcref.txt mkref
- $(srcdir)/mkref $(srcdir)/error_funcref.txt >$(srcdir)/error_funcref.sgml
+error_funcref.xml: error_funcref.txt mkref
+ $(srcdir)/mkref $(srcdir)/error_funcref.txt >$(srcdir)/error_funcref.xml
-extensions_funcref.sgml: extensions_funcref.txt mkref
- $(srcdir)/mkref $(srcdir)/extensions_funcref.txt >$(srcdir)/extensions_funcref.sgml
+extensions_funcref.xml: extensions_funcref.txt mkref
+ $(srcdir)/mkref $(srcdir)/extensions_funcref.txt >$(srcdir)/extensions_funcref.xml
-drivers.sgml: drivers.txt mkdr
- $(srcdir)/mkdr $(srcdir)/drivers.txt >$(srcdir)/drivers.sgml
+drivers.xml: drivers.txt mkdr
+ $(srcdir)/mkdr $(srcdir)/drivers.txt >$(srcdir)/drivers.xml
maintainer-clean-local:
$(RM) -r $(srcdir)/doc_html $(srcdir)/man
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
-<!ENTITY intro SYSTEM "intro.sgml">
-<!ENTITY install SYSTEM "install.sgml">
-<!ENTITY tutorial SYSTEM "tutorial.sgml">
-<!ENTITY other SYSTEM "other.sgml">
-<!ENTITY driverwriting SYSTEM "driverwriting.sgml">
-<!ENTITY drivers SYSTEM "drivers.sgml">
-<!ENTITY reference SYSTEM "reference.sgml">
-<!ENTITY funcref SYSTEM "funcref.sgml">
-<!ENTITY calibration-funcref SYSTEM "calibration_funcref.sgml">
-<!ENTITY command-funcref SYSTEM "command_funcref.sgml">
-<!ENTITY dio-funcref SYSTEM "dio_funcref.sgml">
-<!ENTITY deprecated-funcref SYSTEM "deprecated_funcref.sgml">
-<!ENTITY error-funcref SYSTEM "error_funcref.sgml">
-<!ENTITY extensions-funcref SYSTEM "extensions_funcref.sgml">
-<!ENTITY glossary SYSTEM "glossary.sgml">
-<!ENTITY comedi "<acronym>Comedi</acronym>">
-<!ENTITY uuml "ue">
-<!ENTITY hellip "...">
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
]>
-<article>
+<article xmlns:xi="http://www.w3.org/2001/XInclude">
<articleinfo>
<title>
Comedi
<abstract>
<para>
- <emphasis role="strong">Abstract</emphasis>
- </para>
- <para>
&comedi; is a free software project to interface
<emphasis>digital acquisition</emphasis> (DAQ) cards. It is the
combination of three complementary software items: (i) a generic,
</articleinfo>
-&intro;
-
-&install;
-
-&tutorial;
-
-&other;
-
-&driverwriting;
-
-<section id="lowleveldrivers">
- <title>
- Low-level drivers
- </title>
-
-&drivers;
-
-</section>
-
-<section id="comedireference">
- <title>
- &comedi; Reference
- </title>
- <para>
- Reference for
- <link linkend="constantsmacros">constants and macros</link>,
- <link linkend="datatypesstructures">data types and structures</link>,
- and <link linkend="functionreference">functions</link>.
- </para>
-
- &reference;
-
-<!-- </section> -->
-
- <section id="functionreference">
- <title>Functions</title>
- <section>
- <title>Core Functions</title>
- &funcref;
- </section>
- <section>
- <title>Asyncronous Commands</title>
- &command-funcref;
- </section>
- <section>
- <title>Calibration</title>
- &calibration-funcref;
- </section>
- <section>
- <title>Digital I/O</title>
- &dio-funcref;
- </section>
- <section>
- <title>Error Reporting</title>
- &error-funcref;
- </section>
- <section>
- <title>Extensions</title>
- &extensions-funcref;
- </section>
- <section>
- <title>Deprecated</title>
- &deprecated-funcref;
- </section>
- </section>
-</section>
-
- &glossary;
+<xi:include href="intro.xml"/>
+<xi:include href="install.xml"/>
+<xi:include href="tutorial.xml"/>
+<xi:include href="other.xml"/>
+<xi:include href="driverwriting.xml"/>
+<xi:include href="drivers.xml"/>
+<xi:include href="reference.xml"/>
+<xi:include href="glossary.xml"/>
</article>
--- /dev/null
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ version="1.0">
+ <xsl:param name="use.id.as.filename" select="'1'"/>
+ <xsl:param name="admon.graphics" select="'1'"/>
+ <xsl:param name="admon.graphics.path"></xsl:param>
+ <xsl:param name="chunk.section.depth" select="1"></xsl:param>
+ <xsl:param name="generate.section.toc.level" select="4"></xsl:param>
+<!-- <xsl:param name="html.stylesheet" select="'docbook.css'"/> -->
+</xsl:stylesheet>
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
+
<section id="driverwriting">
<title>
Writing a &comedi; driver
such as: timers, management of which drivers
are active, memory management for drivers and buffers, wrapping
of RTOS-specific interfaces, interrupt handler management, general
-error handling, the <filename role=directory>/proc</filename>
+error handling, the <filename role="directory">/proc</filename>
interface, etc. So,
the device driver writers can concentrate on the interesting stuff:
implementing their specific interface card's DAQ functionalities.
<listitem>
<para>
-How does the
+How does the
<link linkend="userkernelhow">communication</link> between user space
and kernel space work?
</para>
<para>
What functionality is provided by the
<link linkend="comedikernelgeneric">generic</link> kernel-space
-&comedi; functions, and what must be provided for each
+&comedi; functions, and what must be provided for each
<link linkend="boardspecific">specific new driver</link>?
</para>
</listitem>
<para>
In user space, you interact with the functions implemented in the
-<filename role=directory>/usr/src/comedilib</filename> directory. Most
+<filename role="directory">/usr/src/comedilib</filename> directory. Most
of the device driver core of the Comedilib library is found in
-<filename role=directory>lib</filename> subdirectory.
+<filename role="directory">lib</filename> subdirectory.
</para>
<para>
-All user-space &comedi;
+All user-space &comedi;
<link linkend="instructions">instructions</link> and
-<link linkend="commandsstreaming">commands</link>
+<link linkend="commandsstreaming">commands</link>
are transmitted to kernel space through a traditional
-<function>ioctl</function> system call.
+<function>ioctl</function> system call.
(See <filename>/usr/src/comedilib/lib/ioctl.c</filename>.)
The user space information command is <emphasis>encoded</emphasis> as
a number in the <function>ioctl</function> call, and decoded in the
the <function>ioctl</function> system call, interprets its contents,
and then calls the corresponding kernel space
<function>do_…_ioctl</function> function(s).
-For example, a &comedi;
+For example, a &comedi;
<link linkend="instructions">instruction</link> is further processed
by the <function>do_insn_ioctl()</function>function. (Which, in turn,
uses <function>parse_insn()</function> for further detailed processing.)
<listitem>
<para>
<filename>include/linux/comedi_rt.h</filename>:
-all the real-time stuff, such as management of ISR in RTAI and
+all the real-time stuff, such as management of ISR in RTAI and
RTLinux/Free, and spinlocks for atomic sections.
</para>
</listitem>
-
+
<listitem>
<para>
<filename>include/linux/comedilib.h</filename>: the header file for
</itemizedlist>
</para>
<para>
-From all the relevant &comedi; device driver code that is found in the
-<filename role=directory>/usr/src/comedi/comedi</filename> directory
+From all the relevant &comedi; device driver code that is found in the
+<filename role="directory">/usr/src/comedi/comedi</filename> directory
(<emphasis>if</emphasis> the &comedi; source has been installed in its
-normal <filename role=directory>/usr/src/comedi</filename> location),
+normal <filename role="directory">/usr/src/comedi</filename> location),
the <emphasis role="strong">generic</emphasis> functionality is
contained in two parts:
<itemizedlist>
From these <filename>C</filename> files, it's especially the
<filename>comedi_fops.c</filename> file that implements what makes
&comedi; into what people want to use it for: a library that has
-solved 90% of the DAQ device driver efforts, once and for all.
+solved 90% of the DAQ device driver efforts, once and for all.
</para>
</listitem>
<listitem>
<para>
For <emphasis role="strong">real-time</emphasis> applications,
-the subdirectory <filename role=directory>kcomedilib</filename>
+the subdirectory <filename role="directory">kcomedilib</filename>
implements an interface in the kernel that is similar to the &comedi;
-interface accessible through the
+interface accessible through the
<link linkend="functionreference">user-space Comedi library</link>.
</para>
<para>
There are some differences in what is possible and/or needed
in kernel space and in user space, so the functionalities offered in
-<filename role=directory>kcomedilib</filename> are not an exact copy
+<filename role="directory">kcomedilib</filename> are not an exact copy
of the user-space library. For example, locking, interrupt handling,
real-time execution, callback handling, etc., are only available in
kernel space.
typedef struct comedi_lrange_struct <link linkend="comedilrange">comedi_lrange</link>;
typedef struct comedi_subdevice_struct <link linkend="comedisubdevice">comedi_subdevice</link>;
typedef struct comedi_device_struct <link linkend="comedidevice">comedi_device</link>:
-typedef struct comedi_async_struct <link linkend="comediasync">comedi_async</link>
+typedef struct comedi_async_struct <link linkend="comediasync">comedi_async</link>
typedef struct comedi_driver_struct <link linkend="comedidriver">comedi_driver</link>;
</programlisting>
They can be found in
<emphasis>hardware</emphasis>, not with the <emphasis>user</emphasis>.
</para>
<para>
-However, the <link linkend="ref-type-comedi-insn">comedi_insn</link>
-and <link linkend="ref-type-comedi-cmd">comedi_cmd</link>
+However, the <link linkend="ref-type-comedi-insn">comedi_insn</link>
+and <link linkend="ref-type-comedi-cmd">comedi_cmd</link>
data structures are shared between user space and kernel space: this
should come as no surprise, since these data structures contain all
information that the user-space program must transfer to the
operating system level, and the data structure
<link linkend="comediasync">comedi_async</link> that stores the
information about all <emphasis>asynchronous</emphasis> activities
-(interrupts, callbacks and events).
+(interrupts, callbacks and events).
</para>
<section id="comedilrange">
<link linkend="ref-type-lsampl-t">lsampl_t</link> maxdata; /* if maxdata==0, use list */
<link linkend="ref-type-lsampl-t">lsampl_t</link> *maxdata_list; /* list is channel specific */
-
+
unsigned int flags;
unsigned int *flaglist;
-
+
<link linkend="comedilrange">comedi_lrange</link> *range_table;
<link linkend="comedilrange">comedi_lrange</link> **range_table_list;
-
+
unsigned int *chanlist; /* driver-owned chanlist (not used) */
-
+
int (*insn_read)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *,<link linkend="ref-type-comedi-insn">comedi_insn</link> *,<link linkend="ref-type-lsampl-t">lsampl_t</link> *);
int (*insn_write)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *,<link linkend="ref-type-comedi-insn">comedi_insn</link> *,<link linkend="ref-type-lsampl-t">lsampl_t</link> *);
int (*insn_bits)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *,<link linkend="ref-type-comedi-insn">comedi_insn</link> *,<link linkend="ref-type-lsampl-t">lsampl_t</link> *);
int (*insn_config)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *,<link linkend="ref-type-comedi-insn">comedi_insn</link> *,<link linkend="ref-type-lsampl-t">lsampl_t</link> *);
-
+
int (*do_cmd)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *);
int (*do_cmdtest)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *,<link linkend="ref-type-comedi-cmd">comedi_cmd</link> *);
int (*poll)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *);
int (*cancel)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *);
-
+
int (*buf_change)(<link linkend="comedidevice">comedi_device</link> *,<link linkend="comedisubdevice">comedi_subdevice</link> *s,unsigned long new_size);
void (*munge)(<link linkend="comedidevice">comedi_device</link> *, <link linkend="comedisubdevice">comedi_subdevice</link> *s, void *data, unsigned int num_bytes, unsigned int start_chan_index );
-
+
unsigned int state;
};
</programlisting>
The function pointers <function>(*insn_read)</function> …
<function>(*cancel)</function> .
-offer (pointers to) the standardized
+offer (pointers to) the standardized
<link linkend="functionreference">user-visible API</link>
that every subdevice should offer; every device driver has to fill
in these functions with their board-specific implementations.
The <function>buf_change()</function> and <function>munge()</function>
functions offer functionality that is not visible to the user and for
which the device driver writer must provide a board-specific
-implementation:
+implementation:
<function>buf_change()</function> is called when a change in the
data buffer requires handling; <function>munge()</function> transforms
different bit-representations of DAQ values, for example from
int rt;
spinlock_t spinlock;
int in_request_module;
-
+
int n_subdevices;
<link linkend="comedisubdevice">comedi_subdevice</link> *subdevices;
int options[COMEDI_NDEVCONFOPTS];
-
+
/* dumb */
int iobase;
int irq;
-
+
<link linkend="comedisubdevice">comedi_subdevice</link> *read_subdev;
wait_queue_head_t read_wait;
-
+
<link linkend="comedisubdevice">comedi_subdevice</link> *write_subdev;
wait_queue_head_t write_wait;
-
+
struct fasync_struct *async_queue;
-
+
void (*open)(<link linkend="comedidevice">comedi_device</link> *dev);
void (*close)(<link linkend="comedidevice">comedi_device</link> *dev);
};
<para>
The following data structure contains all relevant information:
addresses and sizes of buffers, pointers to the actual data, and the
-information needed for
+information needed for
<link linkend="drivercallbacks">event handling</link>:
<programlisting>
struct comedi_async_struct{
unsigned long *buf_page_list; /* physical address of each page */
unsigned int max_bufsize; /* maximum buffer size, bytes */
unsigned int mmap_count; /* current number of mmaps of prealloc_buf */
-
+
volatile unsigned int buf_write_count; /* byte count for writer (write completed) */
volatile unsigned int buf_write_alloc_count; /* byte count for writer (allocated for writing) */
volatile unsigned int buf_read_count; /* byte count for reader (read completed)*/
-
+
unsigned int buf_write_ptr; /* buffer marker for writer */
unsigned int buf_read_ptr; /* buffer marker for reader */
-
+
unsigned int cur_chan; /* useless channel marker for interrupt */
/* number of bytes that have been received for current scan */
unsigned int scan_progress;
/* keeps track of where we are in chanlist as for munging */
unsigned int munge_chan;
-
+
unsigned int events; /* events that have occurred */
-
+
<link linkend="ref-type-comedi-cmd">comedi_cmd</link> cmd;
-
+
// callback stuff
unsigned int cb_mask;
int (*cb_func)(unsigned int flags,void *);
void *cb_arg;
-
- int (*inttrig)(<link linkend="comedidevice">comedi_device</link> *dev,<link linkend="comedisubdevice">comedi_subdevice</link> *s,unsigned int x);
+
+ int (*inttrig)(<link linkend="comedidevice">comedi_device</link> *dev,<link linkend="comedisubdevice">comedi_subdevice</link> *s,unsigned int x);
};
</programlisting>
</para>
<para>
The directory
-<filename role=directory>comedi</filename> contains a large set of
+<filename role="directory">comedi</filename> contains a large set of
support functions. Some of the most important ones are given below.
</para>
<para>
</title>
<para>
-The <filename role=directory>/usr/src/comedi/comedi/drivers</filename>
+The <filename role="directory">/usr/src/comedi/comedi/drivers</filename>
subdirectory contains
the <emphasis role="strong">board-specific</emphasis> device driver
code. Each new card must get an entry in this directory.
all properties of a device and its subdevices are defined, and filled
in in the generic &comedi; data structures. As part of this, pointers
to the low level instructions being supported by the subdevice have to
-be set, which define the basic functionality. In somewhat more detail,
+be set, which define the basic functionality. In somewhat more detail,
the <function>mydriver_attach()</function> function must:
<itemizedlist>
an appropriate initialization. The good news, of course, is that
&comedi; provides the data structures and the defines that fit very
well with almost all DAQ functionalities found on interface cards.
-These can be found in the
+These can be found in the
<link linkend="comedikernelgeneric">header files</link> of the
-<filename role=directory>/usr/src/comedi/include/linux/</filename>
+<filename role="directory">/usr/src/comedi/include/linux/</filename>
directory.
</para>
<para>
</itemizedlist>
In some drivers, you want to catch interrupts, and/or want to use the
<link linkend="insn-inttrig">INSN_INTTRIG</link> instruction. In this
-case, you must provide and register these
+case, you must provide and register these
<link linkend="drivercallbacks">callback</link> functions.
</para>
<para>
has finished (or even started). So, not only the acquired data must be
sent back to the user's buffer <quote>in the background</quote>, but
various types of asynchronous <emphasis>event handling</emphasis> can
-be needed during the acquisition:
+be needed during the acquisition:
<itemizedlist>
<listitem>
The event handling is done in the existing &comedi; drivers in
statements such as this one:
<programlisting>
-<anchor id="async-events">
+<anchor id="async-events"/>
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR
</programlisting>
-It fills in the bits corresponding to particular events in the
+It fills in the bits corresponding to particular events in the
<link linkend="comediasync">comedi_async</link> data structure.
The possible event bits are:
<itemizedlist>
<listitem>
<para>
-<anchor id="comedi-cb-eoa">
+<anchor id="comedi-cb-eoa"/>
<parameter>COMEDI_CB_EOA</parameter>: execute the callback at the
<quote>End Of-Acquisition</quote>.
</para>
<listitem>
<para>
-<anchor id="comedi-cb-eos">
+<anchor id="comedi-cb-eos"/>
<parameter>COMEDI_CB_EOS</parameter>: execute the callback at the
<quote>End-Of-Scan</quote>.
</para>
<listitem>
<para>
-<anchor id="comedi-cb-overflow">
+<anchor id="comedi-cb-overflow"/>
<parameter>COMEDI_CB_OVERFLOW</parameter>: execute the callback when a
buffer overflow has occurred.
</para>
<listitem>
<para>
-<anchor id="comedi-cb-error">
+<anchor id="comedi-cb-error"/>
<parameter>COMEDI_CB_ERROR</parameter>: execute the callback at the
occurrence of an (undetermined) error.
</para>
and has no interrupts available.
</para>
</listitem>
-
+
<listitem>
<para>
Drivers are to have absolutely <emphasis role="strong">no</emphasis>
a driver/device combination.
</para>
</listitem>
-
+
<listitem>
<para>
Drivers should report errors and warnings via the
Put your new driver into <quote>comedi/drivers/mydriver.c</quote>.
</para>
</listitem>
-
+
<listitem>
<para>
Edit <quote>comedi/drivers/Makefile.am</quote> and add <quote>mydriver.ko</quote>
-to the <quote>module_PROGRAMS</quote> list. Also add a line
+to the <quote>module_PROGRAMS</quote> list. Also add a line
<programlisting>
mydriver_ko_SOURCES = mydriver.c
</programlisting>
<listitem>
<para>
Run ./autogen.sh in the top-level comedi directory. You will
-need to have (a recent version of) autoconf and automake
+need to have (a recent version of) autoconf and automake
installed to successfully run autogen.sh. Afterwards, your driver will
be built along with the rest of the drivers when you 'make'.
</para>
</listitem>
-
+
<listitem>
<para>
If you want to have your driver included in the &comedi; distribution
<table COLSEP="1" ROWSEP="1" ORIENT="port" PGWIDE="1">
<title>subdevice flags</title>
- <tgroup COLS="3" ALIGN="left" >
+ <tgroup cols="3" align="left" >
<thead>
<row>
<entry>Subdevice Flag</entry>
-<!-- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook V4.2//EN"> -->
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
<glossary id="comedilib-glossary">
<title>
-<!-- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook V4.2//EN"> -->
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
<section id="install">
<title>
</para>
<para>
-In the <filename role=directory>demo/</filename> directory, there is a
+In the <filename role="directory">demo/</filename> directory, there is a
command called <command>info</command>, which provides information
about each subdevice on the board. Its output can be rather long,
if the board has several subdevices.
-<!-- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook V4.2//EN"> -->
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
<section id="introduction">
application in user space. So, the operating system provides an
interface between both. In Linux or Unix, these interfaces are in the
form of <quote>files</quote>
- in the <filename class=directory>/dev</filename> directory (2.2.x kernels or
-earlier) or <filename class=directory>/devfs</filename> directory
+ in the <filename class="directory">/dev</filename> directory (2.2.x kernels or
+earlier) or <filename class="directory">/devfs</filename> directory
(2.4.x kernels and later). Each device supported in the kernel has a
representative as such a user space device file, and its functionality can
be accessed by classical Unix file I/O:
<listitem>
<para>
- <emphasis role="strong"><filename class=directory>/proc</filename> interface.</emphasis>
+ <emphasis role="strong"><filename class="directory">/proc</filename> interface.</emphasis>
Linux (and some other UNIX operating systems) offer a file-like
interface to attached devices (and other OS-related information) via
-the <filename class=directory>/proc</filename> directories. These
+the <filename class="directory">/proc</filename> directories. These
<quote>files</quote> do not really exist, but it gives a familiar
interface to users, with which they can inspect the current status of
each device.
<para>
This Section introduces the terminology that this document uses when
-talking about <quote>acquisitions.</quote> <xref linkend="fig-acq-seq">
+talking about <quote>acquisitions.</quote> <xref linkend="fig-acq-seq"/>
depicts a typical acquisition <emphasis role="strong">sequence</emphasis>:
<itemizedlist>
<listitem>
<para>
-<anchor id="scan">
+<anchor id="scan"/>
The sequence consists of a number of identically repeated
<emphasis role="strong">scans</emphasis>. This is where the actual
data acquisitions are taking place: data is read from the card, or
<listitem>
<para>
Each scan contains one or more
-<anchor id="conversion">
+<anchor id="conversion"/>
<emphasis role="strong">conversions</emphasis> on particular channels,
i.e., the AD/DA converter is activated on each of the programmed
channels, and produces a sample, again in a finite
<emphasis role="strong">conversion time</emphasis>, starting from the
moment in time called the
<emphasis role="strong">sample time</emphasis>
-in <xref linkend="fig-acq-seq">
+in <xref linkend="fig-acq-seq"/>
(sometimes also called the <quote>timestamp</quote>),
and caused by a
triggering event, called <emphasis role="strong">convert</emphasis>.
</title>
<mediaobject>
<imageobject>
-<imagedata fileref="acq-seq.gif" format="GIF">
+<imagedata fileref="acq-seq.gif" format="GIF"/>
</imageobject>
<!--
<imageobject>
Finally, &comedi; offers the previously mentioned
<quote>high-level</quote> interaction, i.e., at the level of user space
device drivers, through file operations on entries in the
-<filename class=directory>/dev</filename> directory (for access to the
+<filename class="directory">/dev</filename> directory (for access to the
device's functionality), or interactively from the command line
through the <quote>files</quote> in the
-<filename class=directory>/proc</filename> directory (which allow to
+<filename class="directory">/proc</filename> directory (which allow to
inspect the status of a &comedi; device).
</para>
$end = "";
print
-"<!--This file is autogenerated. Do not edit-->
-<section>
+'<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
+<!--This file is autogenerated. Do not edit-->
+<section id="lowleveldrivers">
<title>
- Low-level drivers
+ Kernel Drivers
</title>
-";
+';
while(<>){
push @lines,$_;
$author =~ s/@/@/g;
$author =~ s/</</g;
$author =~ s/>/>/g;
- print
+ $description =~ s/&/&/g;
+ print
"
<section>
<title>
$refentry_end = "";
print
-"<!--This file is autogenerated. Do not edit-->
-";
+'<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
+<!--This file is autogenerated. Do not edit-->
+<section>
+';
while($s = <>){
chomp $s;
print $end;
print $refentry_end;
+print "</section>";
exit(0);
-<!-- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook V4.3//EN"> -->
-
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
<section id="acquisitionfunctions">
<title>
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.)
-<xref linkend="comedireference"> explains the function calls in full
+<xref linkend="comedireference"/> explains the function calls in full
detail.
</para>
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>
-The <parameter class=function>device</parameter> parameter is a
+The <parameter class="function">device</parameter> parameter is a
<link linkend="ref-type-comedi-t">pointer</link>
to a successfully opened &comedi; device.
-The <parameter class=function>subdevice</parameter> and
-<parameter class=function>channel</parameter> parameters are positive
+The <parameter class="function">subdevice</parameter> and
+<parameter class="function">channel</parameter> parameters are positive
integers that indicate which subdevice and channel is used in the
-acquisition. The integer <parameter class=function>bit</parameter>
+acquisition. The integer <parameter class="function">bit</parameter>
contains the value of the acquired bit.
</para>
<para>
<programlisting>
<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
+The parameter <parameter class="function">dir</parameter> should be
either <literal>COMEDI_INPUT</literal> or
<literal>COMEDI_OUTPUT</literal>.
Many digital I/O subdevices group channels into blocks for
<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
-<parameter class=function>write_mask</parameter> and
-<parameter class=function>bits</parameter>
+<parameter class="function">write_mask</parameter> and
+<parameter class="function">bits</parameter>
bitfield. If a bit in
-<parameter class=function>write_mask</parameter> is set, the
-corresponding bit in <parameter class=function>*bits</parameter> will
+<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
-<parameter class=function>*bits</parameter>. The value
-of bits in <parameter class=function>*bits</parameter> corresponding
+<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
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 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>
also to perform a
<link linkend="instructionsconfiguration">configuration</link> of a
channel.
-<anchor id="anchor.instruction.list">
+<anchor id="anchor.instruction.list"/>
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
<link linkend="ref-type-comedi-insn">comedi_insn</link>
data structure:
<programlisting>
-struct <anchor id="insn-data-structure">comedi_insn_struct{
- <anchor id="insn-data-structure-insn">unsigned int insn; // integer encoding the type of acquisition
+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
- <link linkend="ref-type-lsampl-t">lsampl_t</link> <anchor id="insn-data-structure-data">*data; // pointer to data buffer
+ <link linkend="ref-type-lsampl-t">lsampl_t</link> <anchor id="insn-data-structure-data"/>*data; // pointer to data buffer
unsigned int subdev; // subdevice
- unsigned int <anchor id="insn-data-structure-chanspec"><link linkend="ref-macro-CR-PACK">chanspec</link>; // encoded channel specification
+ unsigned int <anchor id="insn-data-structure-chanspec"/><link linkend="ref-macro-CR-PACK">chanspec</link>; // encoded channel specification
unsigned int unused[3];
} comedi_insn;
</programlisting>
Instructions for configuration
</title>
<para>
-<xref linkend="instructions"> explains how instructions are used to do
+<xref linkend="instructions"/> explains how instructions are used to do
<emphasis>acquisition</emphasis> on channels. This section explains
how they are used to <emphasis>configure</emphasis> a subdevice.
There are various sorts of configurations, and the
</title>
<para>
This special instruction has
-<anchor id="insn-inttrig">INSN_INTTRIG as the
+<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>.
Its execution causes an
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>
-<anchor id="command-data-struct">data structure:
+<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
- 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
+ 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
- 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`
+ 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`
- 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
+ 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
- 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
+ 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
- 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
+ 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
- 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
+ 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
- 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
+ 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
};
</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
-<xref linkend="comedicmdsources">.
+<xref linkend="comedicmdsources"/>.
</para>
<para>
-The <parameter class=function>subdev</parameter> member of the
+The <parameter class="function">subdev</parameter> member of the
<link linkend="ref-type-comedi-cmd">comedi_cmd</link> structure is
the index of the subdevice the command is intended for. The
<link linkend="func-ref-comedi-find-subdevice-by-type">comedi_find_subdevice_by_type()</link>
<link linkend="command-data-struct-chanlist">chanlist</link> array should be
initialized by <quote>packing</quote> the channel, range and reference
information together with the
-<parameter class=function>
+<parameter class="function">
<link linkend="ref-macro-CR-PACK">CR_PACK()</link>
</parameter>
macro.
<section id="comedicmdsources">
<title>
The command trigger events
-<anchor id="source.trigger.anchor">
+<anchor id="source.trigger.anchor"/>
</title>
<para>
A command is a very versatile acquisition instruction, in the sense
<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>
-(the <parameter class=function>*_src</parameter> members in the
+(the <parameter class="function">*_src</parameter> members in the
<link linkend="ref-type-comedi-cmd">comedi_cmd</link> data
structure). And each event source can have a corresponding
-argument (the <parameter class=function>*_arg</parameter> members of
+argument (the <parameter class="function">*_arg</parameter> members of
the <link linkend="ref-type-comedi-cmd">comedi_cmd</link> data
structure) whose meaning depends on the type of source trigger.
For example, to specify an external digital line <quote>3</quote> as a
</para>
<para>
The following paragraphs discuss in somewhat more detail the trigger
-event sources(<parameter class=function>*_src</parameter>), and the
-corresponding arguments (<parameter class=function>*_arg</parameter>).
+event sources(<parameter class="function">*_src</parameter>), and the
+corresponding arguments (<parameter class="function">*_arg</parameter>).
</para>
<para>
The start of an acquisition is controlled by the
<listitem>
<para>
-<anchor id="trig-now-start-src">
+<anchor id="trig-now-start-src"/>
TRIG_NOW: the
<link linkend="command-data-struct-start-src">start_src</link>
event occurs
<listitem>
<para>
-<anchor id="trig-follow-start-src">
+<anchor id="trig-follow-start-src"/>
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.
<listitem>
<para>
-<anchor id="trig-ext-start-src">
+<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.
<link linkend="command-data-struct-start-arg">start_arg</link>
<listitem>
<para>
-<anchor id="trig-int-start-src">
+<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>.
<listitem>
<para>
-<anchor id="trig-timer-start-scan">
+<anchor id="trig-timer-start-scan"/>
TRIG_TIMER:
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
events occur periodically. The time between
<listitem>
<para>
-<anchor id="trig-follow-start-scan">
+<anchor id="trig-follow-start-scan"/>
TRIG_FOLLOW: The
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
event occurs immediately after a
<listitem>
<para>
-<anchor id="trig-ext-start-scan">
+<anchor id="trig-ext-start-scan"/>
TRIG_EXT: the
<link linkend="command-data-struct-scan-begin-src">scan_begin</link>
event occurs when an external trigger signal
<listitem>
<para>
-<anchor id="convert-trig-timer">
-<anchor id="trig-timer">
+<anchor id="convert-trig-timer"/>
+<anchor id="trig-timer"/>
TRIG_TIMER: the conversion events occur periodically. The time
between convert events is
<link linkend="command-data-struct-convert-arg">convert_arg</link>
<listitem>
<para>
-<anchor id="convert-trig-ext">
-<anchor id="trig-ext">
+<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.
<link linkend="command-data-struct-convert-arg">convert_arg</link>
<listitem>
<para>
-<anchor id="convert-trig-now">
-<anchor id="trig-now">
+<anchor id="convert-trig-now"/>
+<anchor id="trig-now"/>
TRIG_NOW: All conversion events in a
<link linkend="scan">scan</link> occur simultaneously.
</para>
<listitem>
<para>
-<anchor id="acquisition-end-trig-count">
-<anchor id="trig-count">
+<anchor id="acquisition-end-trig-count"/>
+<anchor id="trig-count"/>
TRIG_COUNT: stop the acquisition after
<link linkend="command-data-struct-stop-arg">stop_arg</link>
scans.
<listitem>
<para>
-<anchor id="acquisition-end-trig-none">
-<anchor id="trig-none">
+<anchor id="acquisition-end-trig-none"/>
+<anchor id="trig-none"/>
TRIG_NONE: perform continuous acquisition, until stopped using
<link linkend="func-ref-comedi-cancel">comedi_cancel()</link>.
</para>
<listitem>
<para>
-<anchor id="trig-time">
+<anchor id="trig-time"/>
TRIG_TIME:
cause an event to occur at a particular time.
</para>
<listitem>
<para>
-<anchor id="trigother-event">
+<anchor id="trigother-event"/>
TRIG_OTHER: driver specific event trigger.
</para>
<para>
<section id="comedicmdflags">
<title>
The command flags
-<anchor id="source.flags.anchor">
+<anchor id="source.flags.anchor"/>
</title>
<para>
<listitem>
<para>
-<anchor id="trig-rt">
+<anchor id="trig-rt"/>
TRIG_RT: 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
<listitem>
<para>
-<anchor id="trig-wake-eos">
+<anchor id="trig-wake-eos"/>
TRIG_WAKE_EOS:
where <quote>EOS</quote> stands for <quote>End of Scan</quote>. Some
drivers will change their behaviour when this flag is set, trying to
<listitem>
<para>
-<anchor id="trig-round-nearest">
+<anchor id="trig-round-nearest"/>
TRIG_ROUND_NEAREST:
round to nearest supported timing period, the default.
This flag (as well as the following three), indicates how timing
<listitem>
<para>
-<anchor id="trig-round-down">
+<anchor id="trig-round-down"/>
TRIG_ROUND_DOWN: round period down.
</para>
</listitem>
<listitem>
<para>
-<anchor id="trig-round-up">
+<anchor id="trig-round-up"/>
TRIG_ROUND_UP: round period up.
</para>
</listitem>
<listitem>
<para>
-<anchor id="trig-round-up-next">
+<anchor id="trig-round-up-next"/>
TRIG_ROUND_UP_NEXT:
this one doesn't do anything, and I don't know what it was intended
to do…?
<listitem>
<para>
-<anchor id="trig-dither">
+<anchor id="trig-dither"/>
TRIG_DITHER: enable dithering? Dithering is a software technique to
smooth the influence of discretization <quote>noise</quote>.
</para>
<listitem>
<para>
-<anchor id="trig-deglitch">
+<anchor id="trig-deglitch"/>
TRIG_DEGLITCH: enable deglitching? Another <quote>noise</quote>
smoothing technique.
</para>
<listitem>
<para>
-<anchor id="trig-write">
+<anchor id="trig-write"/>
TRIG_WRITE:
write to bidirectional devices. Could be useful, in principle, if
someone wrote a driver that supported commands for a digital I/O
<listitem>
<para>
-<anchor id="trig-bogus">
+<anchor id="trig-bogus"/>
TRIG_BOGUS: do the motions?
</para>
</listitem>
<listitem>
<para>
-<anchor id="trig-other">
+<anchor id="trig-other"/>
TRIG_CONFIG: perform configuration, not triggering. This is a legacy
of the deprecated
<link linkend="ref-type-comedi-cmd">comedi_trig_struct</link>
-<!-- <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN" -->
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
+
+<section id="comedireference" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>
+ &comedi; Reference
+ </title>
<section id="comedi-comedilib-h">
<title>
want the device to use. It can be any of the following:
<variablelist>
<varlistentry>
- <term>AREF_GROUND <anchor id="aref-ground"> </term>
+ <term>AREF_GROUND <anchor id="aref-ground"/> </term>
<listitem>
<para>
is for inputs/outputs referenced to ground.
</listitem>
</varlistentry>
<varlistentry>
- <term>AREF_COMMON <anchor id="aref-common"> </term>
+ <term>AREF_COMMON <anchor id="aref-common"/> </term>
<listitem>
<para>
is for a <quote>common</quote> reference (the low inputs of all the
</listitem>
</varlistentry>
<varlistentry>
- <term>AREF_DIFF <anchor id="aref-diff"> </term>
+ <term>AREF_DIFF <anchor id="aref-diff"/> </term>
<listitem>
<para>
is for differential inputs/outputs.
</listitem>
</varlistentry>
<varlistentry>
- <term>AREF_OTHER <anchor id="aref-other"> </term>
+ <term>AREF_OTHER <anchor id="aref-other"/> </term>
<listitem>
<para>
is for any reference that does not fit into the above categories.
automatically when the driver is loaded (<quote>attached</quote>), so
programmers need not access this data structure directly.
<programlisting>
-typedef struct subdevice_struct <anchor id="ref-type-subdevice">subdevice;
+typedef struct subdevice_struct <anchor id="ref-type-subdevice"/>subdevice;
struct subdevice_struct{
unsigned int type;
<variablelist>
<varlistentry>
<term>
-<anchor id="insn-read">
+<anchor id="insn-read"/>
INSN_READ
</term>
<listitem>
</varlistentry>
<varlistentry>
<term>
-<anchor id="insn-write">
+<anchor id="insn-write"/>
INSN_WRITE
</term>
<listitem>
</varlistentry>
<varlistentry>
<term>
-<anchor id="insn-bits">
+<anchor id="insn-bits"/>
INSN_BITS
</term>
<listitem>
</varlistentry>
<varlistentry>
<term>
-<anchor id="insn-config">
+<anchor id="insn-config"/>
INSN_CONFIG
</term>
<listitem>
</varlistentry>
<varlistentry>
<term>
-<anchor id="insn-gtod">
+<anchor id="insn-gtod"/>
INSN_GTOD
</term>
<listitem>
</varlistentry>
<varlistentry>
<term>
-<anchor id="insn-wait">
+<anchor id="insn-wait"/>
INSN_WAIT
</term>
<listitem>
</section>
+</section>
+
+ <section id="functionreference">
+ <title>Functions</title>
+ <section>
+ <title>Core</title>
+ <xi:include href="funcref.xml"/>
+ </section>
+ <section>
+ <title>Asyncronous Commands</title>
+ <xi:include href="command_funcref.xml"/>
+ </section>
+ <section>
+ <title>Calibration</title>
+ <xi:include href="calibration_funcref.xml"/>
+ </section>
+ <section>
+ <title>Digital I/O</title>
+ <xi:include href="dio_funcref.xml"/>
+ </section>
+ <section>
+ <title>Error Reporting</title>
+ <xi:include href="error_funcref.xml"/>
+ </section>
+ <section>
+ <title>Extensions</title>
+ <xi:include href="extensions_funcref.xml"/>
+ </section>
+ <section>
+ <title>Deprecated</title>
+ <xi:include href="deprecated_funcref.xml"/>
+ </section>
+ </section>
</section>
-<!-- <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "docbook/dtd/4.2/docbook.dtd"> -->
+<?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" [
+<!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
+%comedilib_entities;
+]>
<section id="writingprograms">
<title>
This Section describes how a well-installed and configured &comedi;
package can be used in an application, to communicate data with a set
of &comedi; devices.
-<xref linkend="acquisitionfunctions"> gives more details about
+<xref linkend="acquisitionfunctions"/> gives more details about
the various acquisition functions with which the application
programmer can perform data acquisition in &comedi;.
</para>
<para>
Also don't forget to take a good look at the
-<filename class=directory>demo</filename>
+<filename class="directory">demo</filename>
directory of the Comedilib source code. It contains lots of examples
for the basic functionalities of &comedi;.
</para>
it=<link linkend="func-ref-comedi-open">comedi_open</link>("/dev/comedi0");
- <link linkend="func-ref-comedi-data-read">comedi_data_read</link>(it,subdev,chan,range,aref, & data);
+ <link linkend="func-ref-comedi-data-read">comedi_data_read</link>(it,subdev,chan,range,aref, &data);
printf("%d\n",data);
<link linkend="func-ref-comedi-open">comedi_open()</link>
</function> can only be successful if the
<filename>comedi0</filename> device file is configured to point to a
-valid &comedi; driver. <xref linkend="cardconfiguration"> explains
+valid &comedi; driver. <xref linkend="cardconfiguration"/> explains
how this driver is linked to the <quote>device file</quote>.
</para>
<para>
</para>
<para>
-The <parameter class=function>range</parameter> variable tells
+The <parameter class="function">range</parameter> variable tells
&comedi; which gain to use when measuring an analog voltage. Since we
don't know (yet) which numbers are valid, or what each means, we'll
use <literal>0</literal>, because it won't cause errors. Likewise
-with <parameter class=function>aref</parameter>, which determines the
+with <parameter class="function">aref</parameter>, which determines the
analog reference used.
</para>
</section>
unsigned int unit;
}comedi_range;
</programlisting>
-The structure element <parameter class=function>min</parameter>
+The structure element <parameter class="function">min</parameter>
represents the voltage corresponding to
<link linkend="func-ref-comedi-data-read">comedi_data_read()</link>
returning <literal>0</literal>,
-and <parameter class=function>max</parameter> represents
+and <parameter class="function">max</parameter> represents
<link linkend="func-ref-comedi-data-read">comedi_data_read()</link>
-returning <parameter class=function>maxdata</parameter>,
+returning <parameter class="function">maxdata</parameter>,
(i.e., <literal>4095</literal> for <literal>12</literal> bit A/C
converters, <literal>65535</literal> for <literal>16</literal> bit,
or, <literal>1</literal> for digital input; more on this in a bit.)
-The <parameter class=function>unit</parameter> entry tells you if
-<parameter class=function>min</parameter> and
-<parameter class=function>max</parameter> refer to voltage, current,
+The <parameter class="function">unit</parameter> entry tells you if
+<parameter class="function">min</parameter> and
+<parameter class="function">max</parameter> refer to voltage, current,
or are dimensionless (e.g., for digital I/O).
</para>
</programlisting>
<para>
-where <parameter class=function>file</parameter> is of type
+where <parameter class="function">file</parameter> is of type
<parameter>(<link linkend="ref-type-comedi-t">comedi_t</link> *)</parameter>.
This function calls <function>open()</function>, as done explicitly in
a previous section, but also fills the
<para>
Specifically, you need to know
-<parameter class=function>maxdata</parameter> for a specific
+<parameter class="function">maxdata</parameter> for a specific
subdevice/channel. How about:
<programlisting>
void <link linkend="dds-init">dds_init</link>(void);
/* This define determines which waveform to use. */
-#define <anchor id="dds-init-function">dds_init_function <link linkend="dds-init-sine">dds_init_sine</link>
+#define <anchor id="dds-init-function"/>dds_init_function <link linkend="dds-init-sine">dds_init_sine</link>
void <link linkend="dds-init-sine">dds_init_sine</link>(void);
void <link linkend="dds-init-pseudocycloid">dds_init_pseudocycloid</link>(void);
void <link linkend="dds-init-sawtooth">dds_init_sawtooth</link>(void);
-int <anchor id="comedi-internal-trigger">comedi_internal_trigger(<link linkend="ref-type-comedi-t">comedi_t</link> *dev, unsigned int subd, unsigned int trignum)
+int <anchor id="comedi-internal-trigger"/>comedi_internal_trigger(<link linkend="ref-type-comedi-t">comedi_t</link> *dev, unsigned int subd, unsigned int trignum)
{
<link linkend="ref-type-comedi-insn">comedi_insn</link> insn;
<link linkend="ref-type-lsampl-t">lsampl_t</link> data[1];
<link linkend="dds-output">dds_output</link>(data,BUF_LEN);
<link linkend="dds-output">dds_output</link>(data,BUF_LEN);
- dump_cmd(stdout,<![CDATA[&cmd]]>);
+ dump_cmd(stdout,&cmd);
- if ((err = <link linkend="func-ref-comedi-command">comedi_command</link>(dev, <![CDATA[&cmd]]>)) < 0) {
+ if ((err = <link linkend="func-ref-comedi-command">comedi_command</link>(dev, &cmd)) < 0) {
<link linkend="func-ref-comedi-perror">comedi_perror</link>("comedi_command");
exit(1);
}
m=write(comedi_fileno(dev),data,BUF_LEN*sizeof(sampl_t));
- if(<![CDATA[m<0]]>){
+ if(m < 0){
perror("write");
exit(1);
}
printf("m=%d\n",m);
ret = <link linkend="comedi-internal-trigger">comedi_internal_trigger</link>(dev, subdevice, 0);
-<![CDATA[
- if(ret<0){
-]]>
+ if(ret < 0){
perror("comedi_internal_trigger\n");
exit(1);
}
n=BUF_LEN*sizeof(sampl_t);
while(n>0){
m=write(comedi_fileno(dev),(void *)data+(BUF_LEN*sizeof(sampl_t)-n),n);
-<![CDATA[
- if(m<0){
-]]>
+ if(m < 0){
perror("write");
exit(0);
}
}
#define WAVEFORM_SHIFT 16
-<![CDATA[
-#define WAVEFORM_LEN (1<<WAVEFORM_SHIFT)
-]]>
-#define WAVEFORM_MASK (WAVEFORM_LEN-1)
+#define WAVEFORM_LEN (1 << WAVEFORM_SHIFT)
+#define WAVEFORM_MASK (WAVEFORM_LEN - 1)
sampl_t waveform[WAVEFORM_LEN];
unsigned int acc;
unsigned int adder;
-void <anchor id="dds-init">dds_init(void)
+void <anchor id="dds-init"/>dds_init(void)
{
<![CDATA[
adder=waveform_frequency/freq*(1<<16)*(1<<WAVEFORM_SHIFT);
<link linkend="dds-init-function">dds_init_function</link>();
}
-void <anchor id="dds-output">dds_output(sampl_t *buf,int n)
+void <anchor id="dds-output"/>dds_output(sampl_t *buf,int n)
{
int i;
sampl_t *p=buf;
}
-void <anchor id="dds-init-sine">dds_init_sine(void)
+void <anchor id="dds-init-sine"/>dds_init_sine(void)
{
int i;
}
/* Yes, I know this is not the proper equation for a cycloid. Fix it. */
-void <anchor id="dds-init-pseudocycloid">dds_init_pseudocycloid(void)
+void <anchor id="dds-init-pseudocycloid"/>dds_init_pseudocycloid(void)
{
int i;
double t;
]]>
}
-void <anchor id="dds-init-sawtooth">dds_init_sawtooth(void)
+void <anchor id="dds-init-sawtooth"/>dds_init_sawtooth(void)
{
int i;