Common subdirectories: ecos_web_cvs/ecos/packages/io/can/current/doc/CVS and ecos/ecos/packages/io/can/current/doc/CVS
diff -Nu ecos_web_cvs/ecos/packages/io/can/current/doc/can.sgml ecos/ecos/packages/io/can/current/doc/can.sgml
--- ecos_web_cvs/ecos/packages/io/can/current/doc/can.sgml	1970-01-01 01:00:00.000000000 +0100
+++ ecos/ecos/packages/io/can/current/doc/can.sgml	2006-12-13 02:14:43.000000000 +0100
@@ -0,0 +1,1831 @@
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     can.sgml                                                    -->
+<!--                                                                 -->
+<!--     Generic CAN documentation.                                  -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited                          -->
+<!-- This material may be distributed only subject to the terms      -->
+<!-- and conditions set forth in the Open Publication License, v1.0  -->
+<!-- or later (the latest version is presently available at          -->
+<!-- http://www.opencontent.org/openpub/)                            -->
+<!-- Distribution of the work or derivative of the work in any       -->
+<!-- standard (paper) book form is prohibited unless prior           -->
+<!-- permission obtained from the copyright holder                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- Author(s):   Uwe Kindler                                        -->
+<!-- Date:        2006/12/04                                         -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART id="io-can"><title>CAN Support</title>
+
+<CHAPTER id="io-can-overview">
+<TITLE>Overview</TITLE>
+
+<SECTION id="io-can-overview-descr">
+<TITLE>Description</TITLE>
+
+<PARA>
+The Controller Area Network, CAN, was originally designed for use in 
+automotive systems where many small sensors report small values frequently. 
+Consequently, CAN uses small messages of up to 8 bytes payload, which 
+permits many messages to be passed each second and also reduces packet 
+transmission latency.
+</PARA>
+    
+<PARA>
+CAN is is a simple broadcast network carried on a twisted pair. It uses 
+CSMA/CD, like ethernet, to access the medium, however the signal levels 
+and messages format are designed to resolve collisions in favour of 
+the highest priority packet, rather than the jam and random retry of 
+ethernet. This yields a priority-based approach to contention that is 
+better suited to real time applications.
+</PARA>
+    
+<PARA>
+CAN messages contain an 11 bit message id, up to 8 bytes of data, a 15 
+bit CRC and assorted control bits. The message ID is also the priority 
+used to resolve collisions, and has to be unique. Since the network is 
+broadcast, and there are no fixed node addresses, receivers need to have 
+hardware acceptance filters to avoid having to process every packet.
+</PARA>
+    
+<PARA>
+There are two very distinct operational modes for CAN devices. The first 
+of these is BasicCAN. This is the approach familiar from Ethernet controllers. 
+Packets to be transmitted are fed one at a time into an output FIFO and are 
+sent on the wire when it appears to be idle. Received packets are pulled off 
+the wire and are compared against one or more acceptance filters. 
+If they match they are placed into an input FIFO ready for the CPU to collect 
+them.
+</PARA>
+    
+<PARA>
+The second approach is FullCAN. Here, the controller contains a number of 
+packet buffers which are used for transmission or reception. To transmit, 
+the packet is put into a buffer and the buffer state changed to "transmit" 
+and the packet goes out when the controller and the line are ready. Received 
+packets are compared against an acceptance filter on each buffer that is 
+marked "receive" and copied into whichever buffer matches first. The clear 
+intention here is that specific buffers are statically dedicated to 
+particular communication channels.
+</PARA>
+    
+<PARA>
+You can find more information at the CAN in Automation website.
+</PARA>
+</SECTION> <!-- "io-can-description" -->
+
+<SECTION id="io-can-ecos-support">
+<TITLE>eCos Support for CAN</TITLE>
+
+<PARA>
+The eCos CAN support for any given platform is spread over a number of 
+different packages:
+</PARA>
+
+<itemizedlist>
+  <listitem>
+    <para>
+This package, <varname>CYGPKG_IO_CAN</varname>, exports a generic 
+API for accessing devices attached to a CAN network. This API handles 
+issues such as locking between threads. The package does not contain any 
+hardware-specific code. Instead it will use a separate CAN device 
+driver to handle the hardware, and it defines the interface that 
+such network drivers should provide.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+Each CAN device will have its own device driver, which is implemented 
+as a separate package, for example 
+<varname>CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN</varname>. For devices that may 
+be attached to a variety of different boards the device driver will be 
+generic and a second platform specific package will be used to customize 
+it to each platform. For devices that are associated with a specific 
+chipset, only a single package may be present.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<PARA>
+Typically all appropriate packages will be loaded automatically when 
+you configure eCos for a given platform. If the application does not use 
+any of the CAN I/O facilities, directly or indirectly, then linker garbage 
+collection should eliminate all unnecessary code and data. All necessary 
+initialization should happen automatically. However the exact details may 
+depend on the platform, so the platform HAL documentation should be 
+checked for further details.
+</PARA>
+    
+<PARA>
+There is an important exception to this: if the CAN devices are attached 
+to an expansion connector, such as PCI, then the platform HAL will not 
+know about these devices. Instead the necessary packages will need to be 
+added explicitly during configuration.
+</PARA>
+</SECTION>
+</CHAPTER>
+
+<CHAPTER id="io-can-api">
+<TITLE>User API</TITLE>
+
+<PARA>
+The CAN driver uses the standard eCos I/O API functions. All functions 
+except <function>cyg_io_lookup()</function> require an I/O "handle".
+</PARA>
+
+<PARA>
+All functions return a value of the type <type>Cyg_ErrNo</type>. 
+If an error condition is detected, this value will be negative and the 
+absolute value indicates the actual error, as specified in 
+<filename>cyg/error/codes.h</filename>. The only other legal return values 
+will be <varname>ENOERR</varname>, <varname>-EINTR</varname> and 
+<varname>-EAGAIN</varname>. All other function arguments are pointers 
+(references). This allows the drivers to pass information efficiently, 
+both into and out of the driver. The most striking example of this is the 
+<parameter>len</parameter> value passed to the read and write functions. 
+This parameter contains the desired length of data on input to the 
+function and the actual transferred length on return.
+</PARA>
+    
+<PROGRAMLISTING>
+// Lookup a CAN device and return its handle 
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_lookup</function>( 
+    const char <parameter>*name</parameter>,
+    cyg_io_handle_t <parameter>*handle</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function maps a CAN device name onto an appropriate handle. If the
+named device is not in the system, then the error
+<varname>-ENOENT</varname> is returned. If the device is found, then
+the handle for the device is returned by way of the handle pointer
+<parameter>*handle</parameter>.
+</PARA>
+
+<PROGRAMLISTING>
+// Send a CAN message
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_write</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    const void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function sends one single CAN message (not a buffer of CAN messages) 
+to a device. The size of data to send is contained in 
+<parameter>*len</parameter> and the actual size sent will be returned in 
+the same place.
+</PARA>
+
+<PROGRAMLISTING>
+// Read one CAN event from device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_read</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function receives one single CAN event from a device. The desired size 
+of data to receive is contained in <parameter>*len</parameter> and the 
+actual size obtained will be returned in the same place. 
+</PARA>
+
+<PROGRAMLISTING>
+// Read configuration of a CAN device
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_get_config</FUNCTION>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    cyg_uint32 <parameter>key</parameter>,
+    void *<parameter>buf</parameter>,
+    cyg_uint32 *<parameter>len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a
+device. The type of information retrieved is specified by the
+<parameter>key</parameter>. The data will be returned in the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data requested, which must be at least as large as the size
+appropriate to the selected key. The actual size of data retrieved is
+placed in <parameter>*len</parameter>. The appropriate key values 
+are all listed in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.
+</PARA>
+
+<PROGRAMLISTING>
+// Change configuration of a CAN device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_set_config</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    cyg_uint32 <parameter>key</parameter>,
+    const void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time
+configuration of a device. The type of information is specified by the
+<parameter>key</parameter>. The data will be obtained from the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data provided, which must match the size appropriate to the
+selected key.  The appropriate key values are all listed in the file
+<filename>&lt;cyg/io/config_keys.h&gt;</filename>.
+</PARA> 
+</CHAPTER>   
+
+<CHAPTER id="io-can-driver-details">
+<TITLE>CAN driver details</TITLE>
+
+<PARA>
+Allow applications and other packages to access CAN devices.
+</PARA>
+
+<SECTION id="io-can-driver-description">
+<TITLE>Description</TITLE>
+
+<PARA>
+A raw CAN driver is is provided as a standard part of the eCos system.
+</PARA>
+
+<PARA>
+Use the include file <filename>&lt;cyg/io/canio.h&gt;</filename> for this driver.
+</PARA>
+    
+<PARA>
+The CAN driver is capable of sending single CAN messages to a device and 
+receiving single CAN events from a CAN device. Controls are provided to 
+configure the actual hardware, but there is no manipulation of the data by 
+this driver. 
+</PARA>
+    
+<PARA>
+There may be many instances of this driver in a given system, one for each 
+CAN channel. Each channel corresponds to a physical device and there will 
+typically be a device module created for this purpose. The device modules 
+themselves are configurable, allowing specification of the actual hardware 
+details.     
+</PARA>
+</SECTION>
+
+<SECTION id="io-can-api-details">
+<TITLE>API Details</TITLE>
+
+<SECTION>
+<TITLE>cyg_io_write</TITLE>
+  
+<PROGRAMLISTING>
+cyg_io_write(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To transmit a message an application must fill a <type>cyg_can_message</type>
+buffer and call <function>cyg_can_send()</function>.
+This function sends one single CAN message (not a buffer of CAN messages) 
+to a device. The size of data to send is contained in <parameter>*len</parameter> 
+and the actual size sent will be returned in the same place. A pointer to a
+<type>cyg_can_message</type> is contained in <parameter>*buf</parameter>. 
+The driver maintains a buffer to hold the data. The size of the intermediate
+buffer is configurable within the interface module. The data is not modified 
+at all while it is being buffered. On return, <parameter>*len</parameter> 
+contains the amount of characters actually consumed - that means 
+<parameter>*len</parameter> always contains 
+<function>sizeof(cyg_can_message)</function>.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be blocking (default) or 
+non-blocking. Non-blocking mode requires both the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, and 
+the specific device to be set to non-blocking mode for writes 
+(see <function>cyg_io_set_config()</function>). In blocking mode, the 
+call will not return until there is space in the buffer and the content 
+of the CAN message has been consumed. In non-blocking mode, if there is 
+no space in buffer for the CAN message, <varname>-EAGAIN</varname> is 
+returned and the caller must try again.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout. 
+None-blocking mode with timeout requires the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, requires 
+the eCos kernel package to be included and the specific device to be set 
+to non-blocking mode for writes (see <function>cyg_io_set_config()</function>). 
+In non-blocking mode with timeouts, if there is no space in buffer for the 
+CAN message, the driver waits a certain amount of time (the timeout time) 
+for space in the buffer. If there is still no space in buffer after 
+expiration of the timeout time, <varname>-EINTR</varname> is returned and 
+the caller must try again.
+</PARA>
+    
+<PARA>
+If a message was sucessfully sent, the function returns <varname>ENOERR</varname>.
+</PARA>
+</SECTION>
+    
+<SECTION>  
+<TITLE>CAN Messages</TITLE>
+    
+<PARA>
+The CAN driver uses <structname>cyg_can_message</structname> structures to 
+pass messages between the application and the CAN driver. The type 
+cyg_can_message provides a device independent type of CAN message. 
+Before calling the write function this message should be setup properly.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct can_message
+{
+    cyg_uint32         id;
+    cyg_uint8          data[8];
+    cyg_can_id_type    ext;
+    cyg_can_frame_type rtr;
+    cyg_uint8          dlc;
+} cyg_can_message;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+ 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>id</varname></term>
+           <listitem><para>
+Message ID. This is the ID to be transmitted with the message, or the 
+ID received. If the <structfield>ext</structfield> field is set, then 
+this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>data</varname></term>
+           <listitem><para>
+Message data. Only the first <structfield>dlc</structfield> bytes of 
+data are valid. If the <structfield>rtr</structfield> field is set, 
+then the contents of this field are ignored.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_id_type</type> <varname>ext</varname></term>
+           <listitem><para>
+Extended ID. If this field is <varname>CYGNUM_CAN_ID_EXT</varname> then the 
+<structname>id</structname> field contains a 29 bit extended ID. If it 
+contains <varname>CYGNUM_CAN_ID_STD</varname> then the ID is 11 bits.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_frame_type</type> <varname>rtr</varname></term>
+           <listitem><para>
+Remote Transmission Request. If this field contains 
+<varname>CYGNUM_CAN_FRAME_RTR</varname> then the RTR bit on the message 
+will be set and the <structfield>data</structfield> field will be ignored. 
+If the field contains <varname>CYGNUM_CAN_FRAME_DATA</varname> then a 
+normal data frame will be send.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>dlc</varname></term>
+           <listitem><para>
+The length of the data carried in the message. This can range from 
+zero to 8. In a message with the <structfield>rtr</structfield> field set, 
+this indicates the size of data being requested.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for sending one single CAN message:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_message tx_msg;
+cyg_uint32      len;
+Cyg_ErrNo       ret;
+
+tx_msg.id  = 0x100;
+tx_msg.ext = CYGNUM_CAN_ID_EXT;
+tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+tx_msg.dlc = 1;
+tx_msg.data[0] = 0xF1;
+
+len = sizeof(tx_msg);
+ret = cyg_io_write(hDrvCAN, &amp;tx_msg, &amp;len);
+</PROGRAMLISTING>       
+</SECTION><!-- can-cyg_can_message -->
+
+<SECTION>
+<TITLE>cyg_io_read</TITLE> 
+ 
+<PROGRAMLISTING>
+cyg_io_read(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To receive a message the application calls <function>cyg_can_recv()</function>.
+This function receives one single event from a device. The desired size 
+of data to receive is contained in <parameter>*len</parameter> and the
+actual size obtained will be returned in the same place. A pointer to 
+a <type>cyg_can_event</type> is contained in <parameter>*buf</parameter>. 
+No manipulation of the data is performed before being transferred. 
+Again, this buffering is completely configurable. On return, 
+<parameter>*len</parameter> contains <function>sizeof(cyg_can_event)</function>.
+</PARA>
+   
+<PARA>    
+It is possible to configure the read call to be blocking (default) or 
+non-blocking. Non-blocking mode requires both the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, 
+and the specific device to be set to non-blocking mode for reads 
+(see <function>cyg_io_set_config()</function>). In blocking mode, 
+the call will not return until one single CAN event has been read. 
+In non-blocking mode, if there is no CAN event in buffer, the call 
+returns immediately with <varname>-EAGAIN</varname> and the caller must 
+try again.
+<PARA>
+    
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout. 
+None-blocking mode with timeout requires the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, 
+requires the eCos kernel package to be included and the specific device 
+to be set to non-blocking mode for reads (see 
+<function>cyg_io_set_config()</function>). In non-blocking mode with timeouts, 
+if there is no CAN event in receive buffer, the driver waits a certain amound 
+of time (the timeout time) for a CAN event to arrive. If there is still no 
+CAN event in buffer after expiration of the timeout time, <varname>-EINTR</varname> 
+is returned and the caller must try again.
+</PARA>
+    
+<PARA>
+If a event was sucessfully received, the function returns <varname>ENOERR</varname>.    
+</PARA>
+</SECTION><!-- cyg_io_read -->
+
+
+<SECTION>  
+<TITLE>CAN Events</TITLE>
+
+<PARA>
+The CAN driver uses <structname>cyg_can_event</structname> structures to
+pass events from hardware device driver to the generic CAN driver.
+A <structname>cyg_can_event</structname> provides a generic device 
+independent type for handling CAN events that may occur.
+</PARA> 
+
+<PROGRAMLISTING>
+typedef struct cyg_can_event_st
+{
+    cyg_uint32      timestamp;
+    cyg_can_message msg;
+    cyg_uint16      flags;
+} cyg_can_event;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+ 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>timestamp</varname></term>
+           <listitem><para>
+If the hardware CAN device driver supports timestamps then this field may 
+contain a timestamp value for an event that occured.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+CAN message. The msg field contains a CAN message if an RX or TX event occured.
+If another type of event occured, the <structfield>data</structfield> field
+of the <structfield>msg</structfield> may contain additional event specific data.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint16</type> <varname>flags</varname></term>
+           <listitem><para>
+Event flags. The <varname>flags</varname> field contains 16 bits that 
+indicate which kind of events occured. 
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+    
+<PARA>
+The following events are supported and after receiving an event the 
+application should check the flag field against these values:
+</PARA>
+    
+<PROGRAMLISTING>
+typedef enum
+{
+  CYGNUM_CAN_EVENT_RX               = 0x0001, // message received
+  CYGNUM_CAN_EVENT_TX               = 0x0002, // mesage transmitted
+  CYGNUM_CAN_EVENT_WARNING_RX       = 0x0004, // (TEC) reached warning level (>96)
+  CYGNUM_CAN_EVENT_WARNING_TX       = 0x0008, // (REC) reached warning level (>96)
+  CYGNUM_CAN_EVENT_ERR_PASSIVE      = 0x0010, // CAN "error passive" occured
+  CYGNUM_CAN_EVENT_BUS_OFF          = 0x0020, // CAN "bus off" error occured
+  CYGNUM_CAN_EVENT_OVERRUN_RX       = 0x0040, // overrun in RX queue or hardware 
+  CYGNUM_CAN_EVENT_OVERRUN_TX       = 0x0080, // overrun in TX queue occured
+  CYGNUM_CAN_EVENT_CAN_ERR          = 0x0100, // a CAN bit or frame error occured
+  CYGNUM_CAN_EVENT_LEAVING_STANDBY  = 0x0200, // CAN hardware leaves standby
+  CYGNUM_CAN_EVENT_ENTERING_STANDBY = 0x0400, // CAN hardware enters standby
+  CYGNUM_CAN_EVENT_ARBITRATION_LOST = 0x0800, // arbitration lost
+  CYGNUM_CAN_EVENT_DEVICE_CHANGED   = 0x1000, // device changed event
+  CYGNUM_CAN_EVENT_PHY_FAULT        = 0x2000, // General failure of physical layer 
+  CYGNUM_CAN_EVENT_PHY_H            = 0x4000, // Fault on CAN-H (Low Speed CAN)
+  CYGNUM_CAN_EVENT_PHY_L            = 0x8000, // Fault on CAN-L (Low Speed CAN)
+} cyg_can_event_flags;
+</PROGRAMLISTING>
+
+<PARA>
+Often the flags field will contain only one single set flag. But it is 
+possible that a number of flags is set and so the flag field should always 
+be checked by a receiver. I.e. if the <varname>CYGNUM_CAN_EVENT_RX</varname> 
+is set then also the <varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> 
+may be set if the received message caused an RX overrun.
+</PARA>
+    
+<PARA>
+The internal receive buffers of the CAN device driver are circular buffers. 
+That means that even if the buffers are completely filled new messages 
+will be received. In this case the newest message will always overwrite 
+the oldest message in receive buffer. If this happens the 
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set for this 
+new message that caused overwriting of the old one. The 
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set also if 
+a overrun occures in hardware message buffers of the CAN device.
+</PARA>
+    
+<PARA>
+Example code for receiving one single CAN event:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_event rx_event;
+cyg_uint32    len;
+Cyg_ErrNo     ret;
+
+len = sizeof(rx_event);
+ret = cyg_io_read(hDrvCAN, &amp;rx_event, &amp;len);
+
+if (ENOERR == ret)
+{
+    if (rx_event.flags &amp; CYGNUM_CAN_EVENT_RX)
+    {
+        // handle RX event
+    }
+    
+    if (rx_event.flags &amp; ~CYGNUM_CAN_EVENT_RX)
+    {
+        // handle other events
+    }
+}
+else if (-EINTR == ret)
+{
+    // handle timeout
+}
+</PROGRAMLISTING>       
+</SECTION><!-- can-cyg_can_event -->
+
+  
+<SECTION>
+<TITLE>cyg_io_get_config</TITLE> 
+  
+<PROGRAMLISTING>
+cyg_io_get_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a device. 
+The type of information retrieved is specified by the <parameter>key</parameter>. 
+The data will be returned in the given buffer. The value of 
+<parameter>*len</parameter> should contain the amount of data requested, 
+which must be at least as large as the size appropriate to the selected 
+<parameter>key</parameter>. The actual size of data retrieved is placed 
+in <parameter>*len</parameter>. The appropriate key values are all listed 
+in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.    
+</PARA>   
+    
+<PARA>
+The following config keys are currently supported:
+</PARA>  
+    
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+CYG_IO_GET_CONFIG_CAN_INFO
+CYG_IO_GET_CONFIG_CAN_BUFFER_INFO
+CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO
+CYG_IO_GET_CONFIG_CAN_TIMEOUT
+CYG_IO_GET_CONFIG_CAN_HDI
+CYG_IO_GET_CONFIG_CAN_STATE
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-get-config -->
+  
+<SECTION>
+<TITLE>cyg_io_set_config</TITLE> 
+  
+<PROGRAMLISTING>
+cyg_io_set_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time configuration 
+of a device. The type of information is specified by the <parameter>key</parameter>. 
+The data will be obtained from the given buffer. The value of 
+<parameter>*len</parameter> should contain the amount of data provided, 
+which must match the size appropriate to the selected <parameter>key</parameter>. 
+The appropriate key values are all listed in the file 
+<filename>&lt;cyg/io/config_keys.h&gt;</filename>.  
+</PARA>   
+    
+<PARA>
+The following config keys are currently supported:
+</PARA>  
+    
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+CYG_IO_SET_CONFIG_CAN_INFO
+CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN
+CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_TIMEOUT
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+CYG_IO_SET_CONFIG_CAN_MODE
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+</SECTION><!-- io-can-api-details -->
+
+<SECTION id="io-can-runtime-cfg">  
+<TITLE>Runtime Configuration</TITLE>
+  
+<PARA>
+Runtime configuration is achieved by exchanging data structures with the 
+driver via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions.
+</PARA>
+
+<SECTION>
+<TITLE>Device configuration</TITLE>
+  
+<PROGRAMLISTING>
+typedef struct cyg_can_info_st {
+    cyg_can_baud_rate_t baud;
+} cyg_can_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Device configuration is achieved by by exchanging 
+<structname>cyg_can_info_t</structname> data structures with the driver 
+via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions using the config keys 
+<varname>CYG_IO_GET_CONFIG_CAN_INFO</varname> and 
+<varname>CYG_IO_SET_CONFIG_CAN_INFO</varname>. 
+The field <structfield>baud</structfield> contains a baud rate selection. 
+This must be one of the follwing values:  
+</PARA>
+  
+<PROGRAMLISTING>
+CYGNUM_CAN_KBAUD_10
+CYGNUM_CAN_KBAUD_20
+CYGNUM_CAN_KBAUD_50
+CYGNUM_CAN_KBAUD_100
+CYGNUM_CAN_KBAUD_125
+CYGNUM_CAN_KBAUD_250
+CYGNUM_CAN_KBAUD_500
+CYGNUM_CAN_KBAUD_800
+CYGNUM_CAN_KBAUD_1000
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+  
+<SECTION>
+<TITLE>Timeout configuration</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_timeout_info_st
+{
+    cyg_uint32 rx_timeout;
+    cyg_uint32 tx_timeout;
+} cyg_can_timeout_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Timeout configuration is achieved by by exchanging 
+<structname>cyg_can_timeout_info_t</structname> data structures with the 
+driver via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions using the config keys 
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname> and 
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname>.   
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_timeout</varname></term>
+           <listitem><para>
+Timeout for <function>cyg_io_read</function> calls.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>tx_timeout</varname></term>
+           <listitem><para>
+Timeout for <function>cyg_io_write</function> calls.
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+
+<PARA>
+Timeout runtime configuration is supported if the configuration options 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> 
+and <varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> are enabled. 
+</PARA>
+</SECTION><!-- can-timeout-config -->
+
+<SECTION>
+<TITLE>Reading buffer configuration</TITLE>
+    
+<PROGRAMLISTING>    
+typedef struct cyg_can_buf_info_st
+{
+    cyg_int32 rx_bufsize;
+    cyg_int32 rx_count;
+    cyg_int32 tx_bufsize;
+    cyg_int32 tx_count;
+} cyg_can_buf_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_BUFFER_INFO</varname> - This function 
+retrieves the current state of the software buffers in the CAN drivers. 
+For the transmit buffer it returns the the total number of 
+<type>cyg_can_message</type> objects in buffer and the current number of 
+<type>cyg_can_message</type> objects occupied in the buffer. 
+For the receive buffer it returns the total number of 
+<type>cyg_can_event</type> objects in receive buffer and the current 
+number of <type>cyg_can_event</type> objects occupied in the buffer. 
+It does not take into account any buffering such as FIFOs or holding 
+registers that the CAN hardware device itself may have.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_bufsize</varname></term>
+           <listitem><para>
+Total number of <type>cyg_can_event</type> buffers in receive queue.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_count</varname></term>
+           <listitem><para>
+Current number of <type>cyg_can_event</type> buffers occupied in receive queue.
+          </para></listitem>
+   </varlistentry>
+      <varlistentry>
+       <term><type>cyg_uint32</type> <varname>tx_bufsize</varname></term>
+           <listitem><para>
+Total number of <type>cyg_can_message</type> buffers in transmit queue.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rtx_count</varname></term>
+           <listitem><para>
+Current number of <type>cyg_can_message</type> buffers occupied in transmit queue.
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+</SECTION>  <!-- can-read-buffer-config -->
+  
+  
+<SECTION>
+<TITLE>Reading hardware description information</TITLE>
+    
+<PROGRAMLISTING>    
+typedef struct cyg_can_hdi_st
+{
+    cyg_uint8 support_flags;
+    cyg_uint8 controller_type;
+} cyg_can_hdi;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_HDI</varname> - This function retrieves 
+information about the used hardware. The Hardware Description Interface 
+provides a method to gather information about the CAN hardware and the 
+functionality of the driver. For this purpose the structure 
+<structname>cyg_can_hdi</structname> is defined.  
+</PARA>
+     
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>support_flags</varname></term>
+           <listitem><para>
+Contains information about the capabilities of the used CAN hardware.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>controller_type</varname></term>
+           <listitem><para>
+A number that identifies the CAN controller type.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+The following flags are available in the field <structfield>support_flags</structfield>:  
+</PARA>
+     
+<PROGRAMLISTING>    
+|   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
++-------+-------+-------+-------+-------+-------+-------+-------+
+|  res  |  res  |  res  |timest.|SW-Filt|FullCAN|   Frametype   |
+</PROGRAMLISTING>
+
+<variablelist>
+  <varlistentry>
+    <term><parameter>Frametype</parameter></term>
+    <listitem><para>
+Bit 0 and Bit 1 of the structure describe the possibilities of the CAN
+controller. The following values are defined:
+    <PROGRAMLISTING>    
+CYGNUM_CAN_HDI_FRAMETYPE_STD          // receives only standard frame
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE  // can recieve but not send extended frames
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE   // can send and receive extended frames
+    </PROGRAMLISTING>
+    </para></listitem>
+  </varlistentry>
+    <varlistentry>
+    <term><parameter>FullCAN</parameter></term>
+    <listitem><para>
+If the Bit 2 - <varname>CYGNUM_CAN_HDI_FULLCAN </varname> - is set to one, 
+the CAN controller supports more than one message buffer.
+    </para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>SW-Filter</parameter></term>
+    <listitem><para>
+If Bit 3 - <varname>CYGNUM_CAN_HDI_FILT_SW</varname> - is set to one then 
+the CAN driver supports some kind of software message filtering.
+    </para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>Timestamp</parameter></term>
+    <listitem><para>
+If Bit 4 - <varname>CYGNUM_CAN_HDI_TIMESTAMP</varname> - is set to one then 
+the CAN hardware supports timestamps for CAN messages
+    </para></listitem>
+  </varlistentry>
+</variablelist>
+</SECTION>  <!-- can-read-buffer-config -->
+   
+<SECTION>
+<TITLE>Reading hardware message buffer configuration</TITLE>
+<PROGRAMLISTING>    
+typedef struct cyg_can_msgbox_info_st
+{
+    cyg_uint8 count; // number of message buffers available for this device
+    cyg_uint8 free;  // number of free message buffers
+} cyg_can_msgbuf_info;
+</PROGRAMLISTING>
+   
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO</varname> - If the CAN hardware supports 
+more than one message buffer for reception of CAN messages (flag 
+<varname>CYGNUM_CAN_HDI_FULLCAN</varname> is set while reading hardware description 
+interface with <varname>CYG_IO_GET_CONFIG_CAN_HDI</varname>) then this function 
+reads the number of message buffers the CAN hardware supports and the number of 
+free message buffers.   
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>count</varname></term>
+           <listitem><para>
+Counts the number of message buffers supported by the device.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>free</varname></term>
+           <listitem><para>
+Contains the number of free message buffers. The free message buffers are 
+available for setting up remote buffers (<varname>CYG_IO_SET_CONFIG_CAN_REMOTE_BUF</varname>) 
+and message filters (<varname>CYG_IO_SET_CONFIG_CAN_FILTER_MSG</varname>).
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+</SECTION> <!-- can-read-buffer-config -->
+   
+<SECTION>
+<TITLE>Reading state of CAN hardware</TITLE>
+
+<PROGRAMLISTING>    
+typedef enum
+{
+  CYGNUM_CAN_STATE_ACTIVE,      // CAN controller active, no errors
+  CYGNUM_CAN_STATE_STOPPED,     // CAN controller in stopped mode
+  CYGNUM_CAN_STATE_STANDBY,     // CAN controller in Sleep mode
+  CYGNUM_CAN_STATE_BUS_WARN,    // CAN controller active, warning level is reached
+  CYGNUM_CAN_STATE_ERR_PASSIVE, // CAN controller went into error passive mode
+  CYGNUM_CAN_STATE_BUS_OFF,     // CAN controller went into bus off mode
+  CYGNUM_CAN_STATE_PHY_FAULT,   // General failure of physical layer 
+  CYGNUM_CAN_STATE_PHY_H,       // Fault on CAN-H detected (Low Speed CAN)
+  CYGNUM_CAN_STATE_PHY_L,       // Fault on CAN-L detected (Low Speed CAN)
+} cyg_can_state;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_STATE</varname> - This function retrieves the 
+present state of the CAN controller. Possible values are defined in the 
+<type>cyg_can_state</type> enumeration.
+</PARA>   
+</SECTION> <!-- can-read-hw-state -->
+
+
+<SECTION>
+<TITLE>Changing mode of CAN hardware</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_MODE</varname> - This function changes 
+the operating mode of the CAN controller. The identifiers for the different 
+operating modes are defined in the <type>cyg_can_mode</type> enumeration.
+</PARA>
+
+<PROGRAMLISTING> 
+typedef enum
+{
+  CYGNUM_CAN_MODE_STOP,   // set controller into stop mode
+  CYGNUM_CAN_MODE_START,  // set controller into operational mode
+  CYGNUM_CAN_MODE_STANDBY // set controller into standby / sleep mode
+} cyg_can_mode;
+</PROGRAMLISTING>
+ 
+<variablelist>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_STOP</type></term>
+           <listitem><para>
+Set controller into stop mode
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_START</type></term>
+           <listitem><para>
+Set controller into operational mode
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_STANDBY</type></term>
+           <listitem><para>
+Set controller into standby / sleep mode.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Befor the hardware configuration of the device is changed, that means if baudrate is changed or the 
+message buffer and filter configuration is changed, the CAN hardware should be set into stop mode 
+and if configuration is finished, then device should be set back into operational mode. 
+Before the device is set into standby mode, the output buffers should be flushed or drained because 
+transmission of a CAN message may wake up the CAN hardware. If a received message wakes up the CAN 
+hardware from standby mode then a <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> event will be 
+inserted into receive message buffer or the <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> flag 
+will be set for the message that caused wake up of CAN hardware.
+</PARA>
+</SECTION> <!-- can-mode-cfg -->
+   
+   
+<SECTION>
+<TITLE>Flush or drain buffers</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN</varname> - This function waits for any buffered output to 
+complete. This function only completes when there is no more data remaining to be sent to the device.
+</PARA>
+   
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH</varname> - This function discards any buffered output for 
+the device.
+</PARA> 
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH</varname> - This function discards any buffered input for the device.
+</PARA>
+</SECTION>
+   
+<SECTION>
+<TITLE>Configuring blocking/non-blocking calls</TITLE>

+<PARA>
+By default all calls to <function>cyg_io_read()</function> and <function>cyg_io_write()</function> 
+are blocking calls. The config keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+
+<PARA>
+enable switching between blocking and nonblocking calls separatly for read and write calls. 
+If blocking calls are configured then the read/write functions return only if a message was 
+stored into TX buffer or a event was received from RX buffer. If non-blocking calls are 
+enabled and there is no space in TX buffer or RX buffer is empty then the function returns 
+immediatelly with <varname>-EAGAIN</varname>. 
+</PARA>
+   
+<PARA>
+If non-blocking calls are enabled and additionally timeouts are supported by driver, then the 
+read/write functions wait until timeout value is expired and then return with <varname>-EINTR</varname>. 
+If the read/write operation succeeds during the timed wait then the functions return succesfully with 
+<varname>ENOERR</varname>.
+</PARA>
+
+<PARA>
+To query if <function>cyg_io_read()</function> and <function>cyg_io_write()</function> are blocking 
+or non-blocking you can use the config keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+</SECTION> <!-- can-cfg-unblock -->
+   
+<SECTION>
+<TITLE>Message buffer management</TITLE>
+
+<PARA>
+Full CAN controllers often support more the one message buffer. These message buffers are often 
+configurable for transmission or reception of certain CAN messages or as a remote buffers. 
+If a CAN hardware supports more than one message buffer then it is possible to configure the 
+CAN hardware to receive only CAN messages with certain identifiers or to configure hardware 
+support for remote buffers. If message filtering is done by hardware, the number of received 
+CAN messages decreases and so also the time for processing received CAN messages and the memory 
+required for buffering received messages decreases. This saves valuable memory and processing time. 
+</PARA>
+
+<PARA>
+The eCos CAN driver supports a generic way of adding message filters or remote buffers. By default the 
+CAN driver is configured for reception of any kind of CAN standard and extended frames. Configuration 
+of message buffers is done by calling <function>cyg_io_set_config()</function> with the config key
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+</PROGRAMLISTING>
+
+<PARA>
+and by exchanging <type>cyg_can_msgbuf_cfg</type> data structures.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbox_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id; // configuration id
+    cyg_can_msgbuf_handle handle; // handle to message buffer
+    cyg_can_message msg;          // CAN message - for configuration of buffer
+} cyg_can_msgbuf_cfg;
+</PROGRAMLISTING>
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+Contains a reference to a certain message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+Required for configuration of message buffer parameters.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+The following configuration identifiers are supported:
+</PARA>
+
+<PROGRAMLISTING>
+CYGNUM_CAN_MSGBUF_RESET_ALL        // clears alle message buffers
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL    // cfg driver for reception of all can messges
+CYGNUM_CAN_MSGBUF_RX_FILTER_ADD    // add single message filter
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD   // add new remote response buffer
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE // stores data into existing remote buffer 
+</PROGRAMLISTING>
+
+<variablelist>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RESET_ALL</type></term>
+           <listitem><para>
+Clears alle message buffers - no message will be received and all remote buffers are deleted.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL</type></term>
+           <listitem><para>
+Configure driver for reception of all can messges
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ADD</type></term>
+           <listitem><para>
+Add single message filter.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</type></term>
+           <listitem><para>
+Add new remote response buffer.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</type></term>
+           <listitem><para>
+Stores data into existing remote buffer (remote buffer handle required).
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for resetting all message buffers:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_msgbuf_cfg msgbox_cfg;
+
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;msgbox_cfg, &amp;len))
+{
+    // handle configuration error
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgbuf-cfg -->
+   
+   
+<SECTION>
+<TITLE>Remote frame response buffer configuration</TITLE>
+
+<PARA>
+The remote frame is a message frame which is transmitted to request a data frame. Some CAN hardware 
+generates receive interrupts when a remote transmission request arrives. Other CAN hardware, i.e. 
+the Motorola FlexCAN module, does not generate any receive interrupt. These CAN hardware chips like the 
+FlexCAN module can be configured to transmit a data frame automatically in response to a 
+remote frame. In oder to support any kind of CAN hardware the eCos CAN driver provides a generic 
+handling of remote transmission requests.
+</PARA>
+
+<PARA>
+The transmission of the data frame in response to a remote frame is completely handled by the CAN driver. 
+If the hardware driver, like the driver for the FlexCAN modul, supports harware message buffers, then 
+the response frame is automatically transmitted if a remote transmission request with a matching ID arrives. 
+If a CAN hardware does not provide hardware support for sending data frames in response to a remote frame, 
+then this need to be implemented in software by the hardware device driver.
+</PARA>
+
+<PARA>
+It is always possible to add remote response buffers. It does not matter if the driver is configured for 
+reception of all CAN messages or if message filtering is used. As long as there are free message buffers 
+available, it is possible to add remote response buffers.
+</PARA>
+   
+<PARA>
+In order to respond to a remote frame, a remote frame reponse buffer need to be initialized before a data 
+frame can be sent in response to a remote frame. This is achieved by by exchanging <type>cyg_can_remote_buf</type> 
+data structures with the driver via the <function>cyg_io_set_config()</function> function using the config 
+key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once the buffer is initialized, the CAN data can be 
+changed at any time by the application.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbuf_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id; // configuration id 
+    cyg_can_msgbuf_handle handle; // handle to message buffer
+    cyg_can_message msg;          // CAN message - for configuration of buffer
+} cyg_can_remote_buf;
+</PROGRAMLISTING> 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer (<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</varname> or 
+<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</varname>).
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+If there is no buffer initialized for this data, the value of the handle field need to be set to 
+<varname>CYGNUM_CAN_MSGBUF_INIT</varname>. After the call to <function>cyg_io_set_config()</function> 
+the handle field contains a valid remote buffer handle ( &gt;= 0) or the value 
+<varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+The CAN frame that should be transmitted in response to a remote frame.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for setting up a remote response buffer:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_remote_buf rtr_buf;
+
+// prepare the remote response buffer
+rtr_buf.cfg_id  = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+rtr_buf.handle  = CYGNUM_CAN_MSGBUF_INIT;
+rtr_buf.msg.id  = 0x7FF;
+rtr_buf.msg.ext = CYGNUM_CAN_ID_STD;
+rtr_buf.msg.rtr = CYGNUM_CAN_FRAME_DATA;
+rtr_buf.msg.dlc = 1;
+rtr_buf.msg.data[0] = 0xAB;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rtr_buf, &amp;len))
+{
+    // handle configuration error
+}
+
+if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
+{
+    // no free message buffer available - handle this problem here
+}
+
+
+// change CAN data for a buffer that is already initialized
+rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE;
+rtr_buf.msg.data[0] = 0x11;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rtr_buf, &amp;len))
+{
+    // handle configuration error
+} 
+</PROGRAMLISTING> 
+</SECTION> <!-- can-rtrbuf-cfg -->
+    
+
+<SECTION>
+<TITLE>Message filter configuration</TITLE>
+
+<PARA>
+If message filtering is done by hardware the number of received CAN messages decreases and so also the 
+time for processing received CAN messages and the memory required for buffering received messages decreases. 
+This saves valuable memory and processing time. The eCos CAN driver supports a generic way of adding 
+message filters. By default the CAN driver is configured for reception of any kind of CAN standard and 
+extended frames. As soon as a message filter is added, the CAN driver will only receive the CAN frames 
+with the identifier of the CAN filter. By adding a number of message filters it is possible for the 
+CAN hardware to receive an number of different CAN messages.
+</PARA>
+
+<PARA>
+Adding message filters is only possible if driver is not configured for reception of all available 
+CAN messages. If the driver is configured for recption of all CAN messages then message buffers need to 
+be reset before adding single message filters.
+</PARA>
+    
+<PARA>
+In order to add a message filter, a message buffer need to be initialized. This is achieved by by 
+exchanging <type>cyg_can_filter</type> data structures with the driver via the <function>cyg_io_set_config()</function> 
+function using the config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once the buffer is initialized, 
+the CAN hardware can recive messages with the identifier of the filter.
+</PARA>
+
+<PROGRAMLISTING> 
+typedef struct cyg_can_msgbox_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id;
+    cyg_can_msgbuf_handle handle;
+    cyg_can_message       msg;
+} cyg_can_filter;
+</PROGRAMLISTING> 
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+After the call to <function>cyg_io_set_config()</function> the handle field contains a valid value 
+( &gt;= 0) or the value <varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available. 
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+The fields <structfield>id</structfield> and <structfield>ext</structfield> of the <structfield>msg</structfield>
+configure the type of message to receive by a certain message filter.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Before adding message filters the device should be stopped and after configuration it should be set 
+into operational mode again.
+</PARA>
+
+<PARA>
+Example code for setting up a message filter:   
+</PARA>
+
+<PROGRAMLISTING> 
+cyg_can_msgbuf_cfg msgbox_cfg;
+cyg_can_filter rx_filter;
+
+// reset all message buffers
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN, 
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;msgbox_cfg, &amp;len))
+{
+    // handle configuration error
+}
+
+// prepare the message filter
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+rx_filter.msg.id  = 0x800;
+rx_filter.msg.ext = CYGNUM_CAN_ID_EXT;
+
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rx_filter, &amp;len))
+{
+    // handle configuration error;
+}
+else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+{
+    // no free message buffer available - handle this problem here
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgfilt-cfg -->
+  
+  
+<SECTION id="can-msgfilt-deact">
+<TITLE>Message filter deactivation</TITLE>
+
+<PARA>
+After startup of your device the CAN driver is configured for reception of all available CAN messages. 
+If you change this configuration by adding single message filters then you can reset this default state 
+with the configuration ID:
+</PARA> 
+
+<PROGRAMLISTING> 
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL
+</PROGRAMLISTING> 
+
+<PARA>
+This message buffer configuration id will clear all message filters and remote buffers and prepares 
+the CAN hardware for recption of any kind of CAN standard and extended frames. It is not neccesary to 
+reset the message buffer configuration before this configuration step is executed because this should be done 
+by device driver.
+</PARA> 
+   
+<PARA>
+Example code for deactivation of message filtering:
+</PARA>
+
+<PROGRAMLISTING> 
+cyg_can_filter rx_filter;
+
+// now setup a RX all configuration
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rx_filter, &amp;len))
+{
+    CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgfilt-cfg -->
+</SECTION>  
+</CHAPTER>
+
+<CHAPTER id="io-can-configuration">
+<TITLE>Configuration</TITLE>
+
+<PARA>
+The CAN subsystem has a number of configuration options.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cdl_interface CYGINT_IO_CAN_TIMESTAMP</type></term>
+           <listitem><para>
+A hardware device driver that supports timestamps should implement this interface.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_TIMESTAMP</type></term>
+           <listitem><para>
+If the CAN hardware driver supports some kind of timestamps then this option enables 
+propagation of timestamps to higher layers. This may add some extra code to hardware 
+drivers.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT</type></term>
+           <listitem><para>
+This option enables support for TX events. If a CAN message is transmitted successfully 
+a TX event will be inserted into the receive event queue and propagated to higher layers. 
+If this option is enabled the RX event queue will be filled faster.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</type></term>
+           <listitem><para>
+This option enables extra code in the generic CAN driver which allows clients to switch 
+read() and write() call semantics from blocking to non-blocking.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_READ</type></term>
+           <listitem><para>
+The initial timeout value in clock ticks for <FUNCTION>cyg_io_read()</FUNCTION> calls.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_WRITE</type></term>
+           <listitem><para>
+The initial timeout value in clock ticks for <FUNCTION>cyg_io_write()</FUNCTION> calls.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+</CHAPTER>
+
+
+<CHAPTER id="io-can-device-drivers">
+<TITLE>Writing a CAN hardware device driver</TITLE>
+
+<PARA>
+A CAN driver is nothing more than a named entity that supports the basic I/O functions - read, 
+write, get config, and set config. The device driver uses and manages interrupts from the 
+device. While the interface is generic and device driver independent, the actual driver 
+implementation is completely up to the device driver designer.
+</PARA>
+
+<PARA>
+That said, the reason for using a device driver is to provide access to a CAN device from 
+application code in as general purpose a fashion as reasonable. Most driver writers are also 
+concerned with making this access as simple as possible while being as efficient as possible.
+</PARA>
+
+<PARA>
+Like other device drivers the CAN device driver is concerned with the movement of information -
+the CAN messages. In order to make the most efficient use of system resources, interrupts are used. 
+This will allow other application processing to take place while the data transfers are under way, 
+with interrupts used to indicate when various events have occurred. For example, a CAN device
+typically generates an interrupt after a CAN message has been sent or a CAN message has been 
+received by a CAN hardware message buffer. It makes sense to allow further application processing 
+while the data is being sent since this can take quite a long time. The interrupt can be used 
+to allow the driver to send a CAN message as soon as the current one is complete, without any 
+active participation by the application code.
+</PARA>
+
+<PARA>
+The main building blocks for CAN device drivers are found in the include files 
+<filename>&lt;cyg/io/devtab.h&gt;</filename> and <filename>&lt;cyg/io/can.h&gt;</filename>
+</PARA>
+
+<PARA>
+Like many other device drivers in eCos, CAN device drivers are described by a device 
+table entry, using the <type>cyg_devtab_entry_t</type> type. The entry should be created using 
+the <varname>DEVTAB_ENTRY()</varname> macro.
+</PARA>
+
+
+<SECTION id="io-can-how-to-write-interface-driver">
+<TITLE>How to Write a CAN Hardware Interface Driver</TITLE>
+
+<PARA>
+The standard CAN driver supplied with eCos is structured as a hardware independent portion 
+and a hardware dependent interface module. To add support for a new CAN device, the user 
+should be able to use the existing hardware independent portion and just add their own 
+interface driver which handles the details of the actual device. The user should have no 
+need to change the hardware independent portion.
+</PARA>
+
+<PARA>
+The interfaces used by the CAN driver and CAN implementation modules are contained in the 
+file <filename>&lt;cyg/io/can.h&gt;</filename>.
+</PARA>
+
+<SECTION>
+<title>DevTab Entry</TITLE>
+
+<PARA>
+The interface module contains the devtab entry (or entries if a single module supports more 
+than one interface). This entry should have the form:
+</PARA>
+
+<PROGRAMLISTING> 
+DEVTAB_ENTRY(&lt;&lt;module_name&gt;&gt;, 
+             &lt;&lt;device_name&gt;&gt;,
+             0,
+             &amp;can_devio, 
+             &lt;&lt;module_init&gt;&gt;, 
+             &lt;&lt;module_lookup&gt;&gt;,
+             &amp;&lt;&lt;can_channel&gt;&gt;
+            );
+</PROGRAMLISTING> 
+
+<variablelist>
+<title>Arguments</title>
+  <varlistentry>
+    <term><parameter>module_name</parameter></term>
+    <listitem><para>The "C" label for this devtab entry</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>device_name</parameter></term>
+    <listitem><para>The "C" string for the
+    device. E.g. <filename>/dev/can0</filename>.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>can_devio</parameter></term>
+    <listitem><para>The table of I/O functions. This set is defined in
+    the hardware independent CAN driver and should be used.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>module_init</parameter></term>
+    <listitem><para>The hardware module initialization function.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>module_lookup</parameter></term>
+    <listitem><para>The device lookup function. This function
+    typically sets up the CAN device for actual use, turning on
+    interrupts, configuring the message buffers, etc.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>can_channel</parameter></term>
+    <listitem><para>This table (defined below) contains the interface
+    between the interface module and the CAN driver proper.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example devtab entry for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+DEVTAB_ENTRY(flexcan_devtab, 
+             CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN0_NAME,
+             0,                     // Does not depend on a lower level interface
+             &amp;cyg_io_can_devio, 
+             flexcan_init, 
+             flexcan_lookup,        // CAN driver may need initializing
+             &amp;flexcan_can0_chan
+    );
+</PROGRAMLISTING>
+</SECTION>
+
+
+<SECTION>
+<title>CAN Channel Structure</TITLE>
+
+<PARA>
+Each CAN device must have a &ldquo;CAN channel&rdquo;.
+This is a set of data which describes all operations on the device.
+It also contains buffers, etc. The CAN channel is created by the macro: 
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,
+                             out_buf, out_buflen,
+                             in_buf,  in_buflen)
+</PROGRAMLISTING>
+
+<variablelist>
+  <title>Arguments</title>
+  <varlistentry>
+    <term><parameter>l</parameter></term>
+    <listitem><para>The "C" label for this structure.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>funs</parameter></term>
+    <listitem><para>The set of interface functions (see below).</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>dev_priv</structfield></term>
+    <listitem><para>A placeholder for any device specific data for
+    this channel.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>baud</structfield></term>
+    <listitem><para>The initial baud rate value
+    (<type>cyg_can_baud_rate_t</type>).</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>out_buf</structfield></term>
+    <listitem><para>Pointer to the output buffer</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>out_buflen</structfield></term>
+    <listitem><para>The length of the output buffer.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>in_buf</structfield></term>
+    <listitem><para>pointer to the input buffer.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>in_buflen</structfield></term>
+    <listitem><para>The length of the input buffer.</PARA></listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example CAN channel implementation for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(
+    flexcan_can0_chan,
+    flexcan_lowlevel_funs,
+    flexcan_can0_info,
+    CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_KBAUD),
+    flexcan_can0_txbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_TX,
+    flexcan_can0_rxbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_RX
+);
+</PROGRAMLISTING>
+
+<PARA>
+The interface from the hardware independent driver into the
+hardware interface module is contained in the <structfield>funs</structfield> table.
+This is defined by the macro:
+</PARA>
+</SECTION>
+
+<SECTION>
+<TITLE>CAN Lowlevel Functions Structure</TITLE>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(l, putmsg, getevent, get_config, set_config, start_xmit, stop_xmit)
+</PROGRAMLISTING>
+
+<variablelist>
+  <title>Arguments</title>
+  <varlistentry>
+    <term><structfield>l</structfield></term>
+    <listitem><para>The "C" label for this structure.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>putmsg</structfield></term>
+    <listitem>
+      <para><literal>
+      bool (*putmsg)(can_channel *priv, cyg_can_message *pmsg, void *pdata)
+      </literal></para>
+      <para>
+      This function sends one CAN message to the interface. It should
+      return <literal>true</literal> if the message is actually consumed. It should
+      return <literal>false</literal> if there is no space in the interface
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>getevent</structfield></term>
+    <listitem>
+      <para><literal>
+      bool (*getevent)(can_channel *priv, cyg_can_event *pevent, void *pdata)
+      </literal></para>
+      <para>
+      This function fetches one event from the interface.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>get_config</structfield></term>
+    <listitem>
+      <para><literal> 
+      Cyg_ErrNo (*get_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+      </literal></para>
+      <para>
+        This function is used to query the configuration of a CAN channel.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>set_config</structfield></term>
+    <listitem>
+      <para><literal> 
+      Cyg_ErrNo (*set_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+      </literal></para>
+      <para>
+        This function is used to change configuration of a CAN channel.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>start_xmit</parameter></term>
+    <listitem><para><literal>void (*start_xmit)(can_channel *priv)</literal></para>
+      <para>
+        Enable the transmit channel and turn on transmit interrupts.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>stop_xmit</parameter></term>
+    <listitem>
+      <para><literal>void (*stop_xmit)(can_channel *priv)</literal></para>
+      <para>Disable the transmit channel and turn transmit interrupts off.</PARA>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example implementation of low level function structure for Motorola FlexCAN 
+device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(flexcan_lowlevel_funs,
+                  flexcan_putmsg,
+                  flexcan_getevent,
+                  flexcan_get_config,
+                  flexcan_set_config,
+                  flexcan_start_xmit,
+                  flexcan_stop_xmit
+     );
+</PROGRAMLISTING>
+</SECTION>
+
+<SECTION>
+<TITLE>Callbacks</TITLE>
+
+<PARA>
+The device interface module can execute functions in the
+hardware independent driver via <literal>chan-&gt;callbacks</literal>.
+These functions are available:
+</PARA>
+
+<PROGRAMLISTING>
+void (*can_init)(can_channel *chan)
+</PROGRAMLISTING>
+
+<PARA>This function is used to initialize the CAN channel.</PARA>
+
+<PROGRAMLISTING>
+void (*xmt_msg)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function would be called from an interrupt handler after a
+transmit interrupt indicating that additional messages may be
+sent. The upper driver will call the <function>putmsg</function>
+function as appropriate to send more data to the device.
+</PARA>
+
+<PROGRAMLISTING>
+void (*rcv_event)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to tell the driver that a message has arrived
+at the interface or that an event has ocured. This function is typically 
+called from the interrupt handler. 
+</PARA>
+</SECTION><!-- Callbacks -->
+
+</SECTION><!-- id="io-can-how-to-write-interface-driver" -->
+</CHAPTER>
+
+</PART>
diff -Nu ecos_web_cvs/ecos/packages/io/can/current/doc/can_driver_doc.html ecos/ecos/packages/io/can/current/doc/can_driver_doc.html
--- ecos_web_cvs/ecos/packages/io/can/current/doc/can_driver_doc.html	2006-03-13 15:46:12.000000000 +0100
+++ ecos/ecos/packages/io/can/current/doc/can_driver_doc.html	1970-01-01 01:00:00.000000000 +0100
@@ -1,495 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
-
-	<head>
-		<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
-		<title>IO/CAN Doc</title>
-	</head>
-
-	<body bgcolor="#ffffff">
-		<h2>CAN driver details</h2>
-		<p>A raw CAN driver is is provided as a standard part of the eCos system. Use the include file <code>&lt;cyg/io/canio.h&gt;</code> for this driver. The CAN driver is capable of sending single CAN messages and receiving single CAN events to a CAN device. Controls are provided to configure the actual hardware, but there is no manipulation of the data by this driver. There may be many instances of this driver in a given system, one for each CAN channel. Each channel corresponds to a physical device and there will typically be a device module created for this purpose. The device modules themselves are configurable, allowing specification of the actual hardware details.</p>
-		<h3>User API</h3>
-		<p>The CAN driver  uses the standard eCos I/O API functions. All functions except <code>cyg_io_lookup()</code> require an I/O &quot;handle&quot;.</p>
-		<p>All functions return a value of the type <code>Cyg_ErrNo</code>. If an error condition is detected, this value will be negative and the absolute value indicates the actual error, as specified in <code>cyg/error/codes.h</code>. The only other legal return value will be <code>ENOERR</code> , <code>-EINTR </code>and<code> -EAGAIN</code>. All other function arguments are pointers (references). This allows the drivers to pass information efficiently, both into and out of the driver. The most striking example of this is the <i>len </i>value passed to the read and write functions. This parameter contains the desired length of data on input to the function and the actual transferred length on return.</p>
-		<h4>Lookup a CAN device</h4>
-		<p><code>Cyg_ErrNo cyg_io_lookup(<br>&nbsp;&nbsp;&nbsp;&nbsp;const char &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*name,<br>&nbsp;&nbsp;&nbsp;&nbsp;cyg_io_handle_t *handle )</code></p>
-		<p>This function maps a device name onto an appropriate handle. If the named device is not in the system, then the error -<code>ENOENT</code> is returned. If the device is found, then the handle for the device is returned by way of the handle pointer <i>*handle</i>.</p>
-		<h4>Send a CAN message</h4>
-		<p><code>Cyg_ErrNo cyg_io_write(<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_io_handle_t &nbsp;handle,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;const void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*buf,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*len )<br>
-			</code></p>
-		<p>This function sends <b>one single</b> CAN message (not a buffer of  CAN messages) to a device. The size of data to send is contained in <i>*len</i> and the actual size sent will be returned in the same place. A pointer to a <code>cyg_can_message</code> is contained in <i>*buf</i> . The driver maintains a buffer to hold the data. The size of the intermediate buffer is configurable within the interface module. The data is not modified at all while it is being buffered. On return,<i> *len</i> contains the amount of characters actually consumed - that means <i>*len</i> always contains <code>sizeof(cyg_can_message)</code>.</p>
-		<p>It is possible to configure the write call to be blocking (default) or non-blocking. Non-blocking mode requires both the configuration option <code>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</code> to be enabled, and the specific device to be set to non-blocking mode for writes (see <code>cyg_io_set_config()</code>). In blocking mode, the call will not return until there is space in the buffer and the content of the CAN message has been consumed. In non-blocking mode, if there is no space in buffer for the CAN message, <code>-EAGAIN</code> is returned and the caller must try again.</p>
-		<p>It is possible to configure the write call to be non-blocking with timeout. None-blocking mode with timeout requires the configuration option <code>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING </code>and<code> CYGOPT_IO_CAN_SUPPORT_TIMEOUTS </code>to be enabled, requires the eCos kernel package to be included and the specific device to be set to non-blocking mode for writes (see <code>cyg_io_set_config()</code>). In non-blocking mode with timeouts, if there is no space in buffer for the CAN message, the driver waits a certain amount of time (the timeout time) for space in the buffer. If there is still no space in buffer after expiration of the timeout time, <code> -EINTR</code> is returned and the caller must try again.</p>
-		<p>If a message was sucessfully sent, the function returns <code>ENOERR</code>. </p>
-		<p><code>typedef struct can_message<br>
-				
-				{<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id;<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint8 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data[8];<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_can_id_type &nbsp;&nbsp;&nbsp;ext;<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_can_frame_type rtr;<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint8 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dlc;<br>
-				
-				} cyg_can_message;</code></p>
-		<p>The type <code>cyg_can_message</code> provides a device independent type of CAN message. Before calling the write function this message should be setup properly. The<i> id</i> field contains the 11 Bit or 29 bit CAN message identifier depending on the value of the <i>ext</i> field. The <i>data</i> field contains the 8 data bytes of one CAN message. The <i>ext</i> field configures the type of CAN message identifier (<code>CYGNUM_CAN_ID_STD</code> = standard 11 Bit id,<i> </i><code>CYGNUM_CAN_ID_EXT</code> = extended 29 Bit id). The <i>rtr</i> field contains the frame type. (<code>CYGNUM_CAN_FRAME_DATA</code> = data frame, <code>CYGNUM_CAN_FRAME_RTR</code> = remote transmission request). The <i>dlc</i> field (data length code) contains the number of valid data bytes (0 - 8) in the <i>data</i> field.</p>
-		<p>Example code for sending one single CAN message:</p>
-		<p><code>cyg_can_message tx_msg;<br>cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len;<br>
-				Cyg_ErrNo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret;<br>
-				<br>
-				
-				
-				tx_msg.id &nbsp;= 0x100;<br>
-				
-				
-				tx_msg.ext = CYGNUM_CAN_ID_EXT;<br>
-				
-				tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;<br>
-				
-				tx_msg.dlc = 1;<br>
-				
-				tx_msg.data[0] = 0xF1;<br>
-				<br>
-				
-				len = sizeof(tx_msg);<br>
-				ret = cyg_io_write(hDrvCAN, &amp;tx_msg, &amp;len);</code></p>
-		<h4>Read a CAN event</h4>
-		<p><code>Cyg_ErrNo cyg_io_read(<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_io_handle_t &nbsp;handle,<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*buf,<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*len )<br>
-			</code></p>
-		<p>This function receives one single event from a device. The desired size of data to receive is contained in <i>*len</i> and the actual size obtained will be returned in the same place. A pointer to a<code> cyg_can_event</code> is contained in <i>*buf</i>. No manipulation of the data is performed before being transferred. Again, this buffering is completely configurable. On return, <i>*len</i> contains  <code>sizeof(cyg_can_event)</code><br>
-		</p>
-		<p>It is possible to configure the read call to be blocking (default) or non-blocking. Non-blocking mode requires both the configuration option <code>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</code> to be enabled, and the specific device to be set to non-blocking mode for reads (<code>see cyg_io_set_config()</code>). In blocking mode, the call will not return until one single CAN event has been read. In<i> </i>non-blocking mode, if there is no CAN event in buffer, the call returns immediately with <code>-EAGAIN</code> and the caller must try again.</p>
-		<p>It is possible to configure the write call to be non-blocking with timeout. None-blocking mode with timeout requires the configuration option <code>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING </code>and<code> CYGOPT_IO_CAN_SUPPORT_TIMEOUTS </code>to be enabled, requires the eCos kernel package to be included and the specific device to be set to non-blocking mode for reads (see <code>cyg_io_set_config()</code>). In non-blocking mode with timeouts, if there is no CAN event in receive buffer, the driver waits a certain amound of time (the timeout time) for a CAN event to arrive. If there is still no CAN event in buffer after expiration of the timeout time, <code> -EINTR</code> is returned and the caller must try again.</p>
-		<p>If a event was sucessfully received, the function returns <code>ENOERR</code>.</p>
-		<p><code>typedef struct cyg_can_event_st<br>
-				{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timestamp;<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_can_message msg;<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flags;<br>
-				} cyg_can_event;<br>
-			</code></p>
-		<p>A <code>cyg_can_event</code>  provides a generic device independent type for handling CAN events that may occur. If the driver supports timestamps then the <i>timestamp</i> field my contain a timestamp value for an event that occured. The <i>msg</i> field contains a CAN message if an RX or TX event occured. The <i>flags</i> field contains 16 bits that indicate which kind of events occured. The following events are supported and after receiving an event the flag field should be checked against these values:</p>
-		<p><code>typedef enum <br>
-				{<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_RX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0001, // message received<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_TX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0002, // mesage transmitted<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_WARNING_RX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0004, // tx error counter (TEC) reached warning level (&gt;96)<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_WARNING_TX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0008, // rx error counter (REC) reached warning level (&gt;96)<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_ERR_PASSIVE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0010, // CAN &quot;error passive&quot; occured<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_BUS_OFF &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0020, // CAN &quot;bus off&quot; error occured<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_OVERRUN_RX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0040, // overrun in RX queue or hardware occured<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_OVERRUN_TX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0080, // overrun in TX queue occured<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_CAN_ERR &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x0100, // a CAN bit or frame error occured<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_LEAVING_STANDBY &nbsp;= 0x0200, // CAN hardware leaves standby / power don mode or is waked up<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_ENTERING_STANDBY = 0x0400, // CAN hardware enters standby / power down mode<br>
-				
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_ARBITRATION_LOST = 0x0800, // arbitration lost<br>
-				&nbsp;&nbsp;CYGNUM_CAN_EVENT_DEVICE_CHANGED &nbsp;&nbsp;= 0x1000, // device changed event<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_EVENT_PHY_FAULT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x2000, // General failure of physical layer detected (if supported by hardware)<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_EVENT_PHY_H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x4000, // Fault on CAN-H detected (Low Speed CAN)<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_EVENT_PHY_L&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0x8000, // Fault on CAN-L detected (Low Speed CAN)<br>
-				} cyg_can_event_flags;</code></p>
-		<p>Often the flags field will contain only one single set flag. But it is possible that a number of flags is set and so the flag field should always be checked by a receiver. I.e. if the <code>CYGNUM_CAN_EVENT_RX </code>is set then also the <code>CYGNUM_CAN_EVENT_OVERRUN_RX </code>may be set if the received message caused an RX overrun.</p>
-		<p>The internal receive buffers of the CAN device driver a circular buffers. That means that even if the buffers are completely filled new messages will be received. In this case the newest message will always overwrite the oldest message in receive buffer. If this happens the <code>CYGNUM_CAN_EVENT_OVERRUN_RX </code>flag will be set for this new message that caused overwriting of the old one. The <code>CYGNUM_CAN_EVENT_OVERRUN_RX </code>flag will be set also if a overrun occures in hardware message buffers of the CAN device.</p>
-		<p>Example code for receiving one single CAN event:</p>
-		<p><code>cyg_can_event rx_event;<br>
-				cyg_uint32 &nbsp;&nbsp;&nbsp;len;<br>
-				Cyg_ErrNo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret;<br>
-				<br>
-				
-				len = sizeof(rx_event);<br>
-				
-				ret = cyg_io_read(hDrvCAN, &amp;rx_event, &amp;len);<br>
-				<br>
-				
-				if (ENOERR == ret)<br>
-				
-				{<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;if (rx_event.flags &amp; CYGNUM_CAN_EVENT_RX)<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;{<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// handle RX event<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(rx_event.flags &amp; ~CYGNUM_CAN_EVENT_RX)<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;{<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// handle other events<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-				
-				}<br>
-				
-				else if (-EINTR == ret)<br>
-				
-				{<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;// handle timeout<br>
-				
-				}<br>
-			</code></p>
-		<h4>Read configuration of a CAN device</h4>
-		<p><code>Cyg_ErrNo cyg_io_get_config(<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_io_handle_t handle,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*buf,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;*len )<br>
-			</code></p>
-		<p>This function is used to obtain run-time configuration about a device. The type of information retrieved is specified by the key. The data will be returned in the given buffer. The value of <i>*len</i> should contain the amount of data requested, which must be at least as large as the size appropriate to the selected key. The actual size of data retrieved is placed in <i>*len</i>. The appropriate key values are all listed in the file<code> &lt;cyg/io/config_keys.h&gt;</code>.</p>
-		<p>The following config keys are currently supported:</p>
-		<p><code>CYG_IO_GET_CONFIG_READ_BLOCKING<br>
-				CYG_IO_GET_CONFIG_WRITE_BLOCKING<br>
-				CYG_IO_GET_CONFIG_CAN_INFO<br>
-				CYG_IO_GET_CONFIG_CAN_BUFFER_INFO<br>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO<br>
-				
-				CYG_IO_GET_CONFIG_CAN_TIMEOUT<br>
-				CYG_IO_GET_CONFIG_CAN_HDI<br>
-				CYG_IO_GET_CONFIG_CAN_STATE<br>
-			</code></p>
-		<h4>Change configuration of a CAN device</h4>
-		<p><code>Cyg_ErrNo cyg_io_set_config(<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_io_handle_t &nbsp;handle,<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key,<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;const void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*buf,<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*len)<br>
-			</code></p>
-		<p>This function is used to manipulate or change the run-time configuration of a device. The type of information is specified by the key. The data will be obtained from the given buffer. The value of <i>*len</i> should contain the amount of data provided, which must match the size appropriate to the selected key. The appropriate key values are all listed in the file <code>&lt;cyg/io/config_keys.h&gt;</code>.</p>
-		<p>The following config keys are currently supported:</p>
-		<p><code>CYG_IO_SET_CONFIG_READ_BLOCKING<br>
-				CYG_IO_SET_CONFIG_WRITE_BLOCKING<br>
-				CYG_IO_SET_CONFIG_CAN_INFO<br>
-				CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN<br>
-				CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH<br>
-				CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH<br>
-				
-				
-				CYG_IO_SET_CONFIG_CAN_TIMEOUT<br>CYG_IO_SET_CONFIG_CAN_MSGBUF<br>
-			</code><code>CYG_IO_SET_CONFIG_CAN_MODE<br>
-				<br>
-			</code></p>
-		<h3>Runtime Configuration</h3>
-		<p>Runtime configuration is achieved by exchanging data structures with the driver via the <code>cyg_io_set_config()</code> and <code>cyg_io_get_config()</code> functions.</p>
-		<h4>Device configuration</h4>
-		<p><code>typedef struct cyg_can_info_st {<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_can_baud_rate_t   baud;<br>
-				} cyg_can_info_t;</code></p>
-		<p>Device configuration is achieved by  by exchanging <code>cyg_can_info_t </code>data structures with the driver via the <code>cyg_io_set_config()</code> and <code>cyg_io_get_config()</code> functions using the config keys <code>CYG_IO_GET_CONFIG_CAN_INFO </code>and<code> CYG_IO_SET_CONFIG_CAN_INFO</code>. The field <i>baud</i> contains a baud rate selection. This must be one of the follwing values:</p>
-		<p><code>CYGNUM_CAN_KBAUD_10<br>
-				CYGNUM_CAN_KBAUD_20<br>
-				CYGNUM_CAN_KBAUD_50<br>
-				CYGNUM_CAN_KBAUD_100<br>
-				CYGNUM_CAN_KBAUD_125<br>
-				CYGNUM_CAN_KBAUD_250<br>
-				CYGNUM_CAN_KBAUD_500<br>
-				CYGNUM_CAN_KBAUD_800<br>
-				CYGNUM_CAN_KBAUD_1000<br>
-			</code></p>
-		<h4>Timeout configuration</h4>
-		<p><code>typedef struct cyg_can_timeout_info_st<br>
-				{<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 rx_timeout; <br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint32 tx_timeout;<br>
-				} cyg_can_timeout_info_t;<br>
-			</code></p>
-		<p>Timeout configuration is achieved by by exchanging <code>cyg_can_timeout_info_t </code>data structures with the driver via the <code>cyg_io_set_config()</code> and <code>cyg_io_get_config()</code> functions using the config keys <code>CYG_IO_SET_CONFIG_CAN_TIMEOUT </code>and<code> CYG_IO_SET_CONFIG_CAN_TIMEOUT</code>.  The field <i>rx_timeout</i> contains the timeout value for <code>cyg_io_read </code>calls and <i>tx_timeout</i> contains the timeout value for  <code>cyg_io_write </code>calls. This call is only available if the configuration options <code>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING  </code>and <code>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</code> are enabled.</p>
-		<h4>Reading buffer configuration</h4>
-		<p><code>typedef struct cyg_can_buf_info_st<br>
-				{  <br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_int32 rx_bufsize; <br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_int32 rx_count;<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_int32 tx_bufsize;<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_int32 tx_count;<br>
-				} cyg_can_buf_info_t;<br>
-			</code></p>
-		<p><code>CYG_IO_GET_CONFIG_CAN_BUFFER_INFO - </code>This function retrieves the current state of the software buffers in the serial drivers. For the transmit buffer it returns the the total number of  <code>cyg_can_message </code>objects in buffer and the current number of  <code>cyg_can_message </code>objects occupied in the buffer. For the recieve buffer it returns the total number of  <code>cyg_can_event </code>objects in receive buffer and the current number of  <code>cyg_can_event </code>objects occupied  in the buffer. It does not take into account any buffering such as FIFOs or holding registers that the CAN hardware device itself may have.</p>
-		<h4>Reading hardware description information</h4>
-		<p><code>typedef struct cyg_can_hdi_st<br>
-				{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint8 support_flags;<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_uint8 controller_type;<br>
-				} cyg_can_hdi;</code></p>
-		<p><code>CYG_IO_GET_CONFIG_CAN_HDI - </code>This function retrieves information about the used hardware. The Hardware Description Interface provides a method to gather information about the CAN hardware and the functionality of the driver. For this purpose the structure <code>cyg_can_hdi </code>is defined. The field support_flags contains information about the capabilities of the used CAN hardware. The following flags are available:</p>
-		<table width="600" border="0" cellspacing="2" cellpadding="0">
-			<tr>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">7</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">6</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">5</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">4</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">3</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">2</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">1</td>
-				<td align="center" valign="middle" bgcolor="#c6c6c6" width="70">0</td>
-			</tr>
-			<tr>
-				<td align="center" valign="middle" width="70">res</td>
-				<td align="center" valign="middle" width="70">res</td>
-				<td align="center" valign="middle" width="70">res</td>
-				<td align="center" valign="middle" width="70">timest.</td>
-				<td align="center" valign="middle" width="70">SW-Filt</td>
-				<td align="center" valign="middle" width="70">FullCAN</td>
-				<td colspan="2" align="center" valign="middle" width="142">Frametype</td>
-			</tr>
-		</table>
-		<p><i>Frametype:<br>
-			</i>Bit 0 and Bit 1 of the structure describe the<i> </i>possibilities of the CAN controller. The following values are defined:</p>
-		<p><code>CYGNUM_CAN_HDI_FRAMETYPE_STD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// receives only standard frame<br>
-				CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE&nbsp;&nbsp;// can recieve but not send extended frames<br>
-				CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE&nbsp;&nbsp;&nbsp;// can send and receive extended frames<br>
-			</code></p>
-		<p><i>FullCAN:<br>
-			</i>If the Bit 2 is set to one, the CAN controller supports more than one message buffer.</p>
-		<p><code>CYGNUM_CAN_HDI_FULLCAN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// supports more than one message buffer<br>
-			</code></p>
-		<p><i>SW-Filter:<br>
-			</i>If Bit3 is set to one then the CAN driver supports some kind of software message filtering.</p>
-		<p><code>CYGNUM_CAN_HDI_FILT_SW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// software message filtering supported<br>
-			</code></p>
-		<p><i>Timestamp:<br>
-			</i>If Bit 4 is set to one then the CAN hardware supports timestamps for CAN messages</p>
-		<p><code>CYGNUM_CAN_HDI_TIMESTAMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// CAN hardware supports timestamps<br>
-			</code></p>
-		<h4>Reading message buffer configuration</h4>
-		<p><code>typedef struct cyg_can_msgbox_info_st<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;c</code><code>yg_uint8 count;    // number of message buffers available for this device<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_uint8 free; &nbsp;// number of free message buffers<br>
-			</code><code>} cyg_can_msgbuf_info;</code></p>
-		<p><code>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO</code> - If the CAN hardware supports more than one message buffer for reception of CAN message (flag <code>CYGNUM_CAN_HDI_FULLCAN </code>is set after reading hardware description interface with <code>CYG_IO_GET_CONFIG_CAN_HDI</code>) then this function reads the number of message buffers the CAN hardware supports and the number of free message buffers. The field<i> count</i> contains the number of message buffers supported by device and the field <i>free</i> contains the number of free message buffers. The free message buffers are available for setting up remote buffers (<code>CYG_IO_SET_CONFIG_CAN_REMOTE_BUF)</code> and message filters (<code>CYG_IO_SET_CONFIG_CAN_FILTER_MSG</code>).</p>
-		<h4>Reading state of CAN hardware</h4>
-		<p><code>typedef enum<br>
-				{<br>&nbsp;&nbsp;CYGNUM_CAN_STATE_ACTIVE, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// CAN controller is active, no errors<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_STOPPED, &nbsp;&nbsp;&nbsp;&nbsp;// CAN controller is in stopped mode<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_STANDBY, &nbsp;&nbsp;&nbsp;&nbsp;// CAN controller is in Sleep mode<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_BUS_WARN, &nbsp;&nbsp;&nbsp;// CAN controller is active, warning level is reached<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_ERR_PASSIVE,  // CAN controller went into error passive mode<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_BUS_OFF,&nbsp;&nbsp;&nbsp;&nbsp; // CAN controller went into bus off mode<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_PHY_FAULT, &nbsp;&nbsp;// General failure of physical layer detected (if supported by hardware)<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_PHY_H, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Fault on CAN-H detected (Low Speed CAN)<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_STATE_PHY_L, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Fault on CAN-L detected (Low Speed CAN)<br>
-			</code><code>} cyg_can_state;</code></p>
-		<p><code>CYG_IO_GET_CONFIG_CAN_STATE</code> - This function retrieves the present state of the CAN controller. Possible values are defined in the <code>cyg_can_state</code> enumeration.</p>
-		<h4>Drain output buffers</h4>
-		<p><code>CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN</code> - This function waits for any buffered output to complete. This function only completes when there is no more data remaining to be sent to the device.</p>
-		<h4>Flush output buffers</h4>
-		<p><code>CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH</code> - This function discards any buffered output for the device.</p>
-		<h4>Flush input buffers</h4>
-		<p><code>CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH</code> - This function discards any buffered input for the device.</p>
-		<h4>Configuring blocking/nonblocking calls</h4>
-		
-		
-		
-		
-		By default all calls to <code>cyg_io_read()</code> and<code> cyg_io_write()</code> are blocking calls. The config keys<br>
-		<br>
-		<code>CYG_IO_GET_CONFIG_READ_BLOCKING<br>
-			CYG_IO_GET_CONFIG_WRITE_BLOCKING<br>
-			<br>
-		</code>and<br>
-		<br>
-		<code>CYG_IO_GET_CONFIG_READ_BLOCKING<br>
-			CYG_IO_GET_CONFIG_WRITE_BLOCKING<br>
-			<br>
-		</code>enable switching between blocking and nonblocking calls separatly for read and write calls. If  blocking calls are configured then the read/write functions return only if a message was stored into TX buffer or a event was received from RX buffer. If nonblocking calls are enabled and there is no space in TX buffer or RX buffer is empty then the function returns immediatelly with <code>-EAGAIN</code>. If nonblocking calls are enabled and additionally timeouts are supported by driver, then the read/write functions wait until  timeout value is expired and then return witn <code>-EINTR</code>. If the read/write operation succeeds during the timed wait then the functions return succesfully with<code> ENOERR</code>.
-
-		<h4>Message buffer configuration</h4>
-		<p><code>typedef struct cyg_can_msgbox_cfg_st<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_msgbuf_cfg_id  cfg_id; // configuration id - cfg. what to do with message buffer<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_msgbuf_handle  handle; // handle to message buffer<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_message msg; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// CAN message - for configuration of buffer<br>
-			</code><code>} cyg_can_msgbuf_cfg;</code></p>
-		<p>Full CAN controllers often support more the one message buffer. These message buffers are often configurable for transmission or reception of certain CAN messages or as a remote buffer. If a CAN hardware supports more than one message buffer then it is possible to configure the CAN hardware to receive only CAN messages with certain identifiers or to configure hardware support for remote buffers. If message filtering is done by hardware, the number of received CAN messages decreases and so also the time for processing received CAN messages and the memory required for buffering received messages decreases. This saves valuable memory and processing time. The eCos CAN driver supports a generic way of adding message filters or remote buffers. By default the CAN driver is configured for reception of any kind of CAN standard and extended frames. Configuration of message buffers is done by calling <code>cyg_io_set_config() </code>with the config key:</p>
-		<p><code>CYG_IO_SET_CONFIG_CAN_MSGBUF<br>
-			</code></p>
-		<p>and exchanging  <code>cyg_can_msgbuf_cfg </code>data structures. The <i>cfg_id</i> field contains the configuration ID that tells the driver what to do with a message buffer, the <i>handle</i> field contains a reference to a certain message buffer and the <i>msg</i> field is necessary for configuration of message buffer parameters. The following configuration identifiers are supported:</p>
-		<p><code>CYGNUM_CAN_MSGBUF_RESET_ALL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// clears alle message buffers, no message will be received, all remote buffers deleted<br>
-			</code><code>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL &nbsp;&nbsp;&nbsp;// cfg driver for reception of all can messges<br>
-			</code><code>CYGNUM_CAN_MSGBUF_RX_FILTER_ADD &nbsp;&nbsp;&nbsp;// add single message filter<br>
-			</code><code>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD &nbsp;&nbsp;// add new remote response buffer<br>
-			</code><code>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE // stores data into existing remote buffer (remote buf handle required)</code></p>
-		<p>Example code for resetting all message buffers:</p>
-		<p><code>cyg_can_msgbuf_cfg     msgbox_cfg;</code></p>
-		<p><code>msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;<br>
-			</code><code>len = sizeof(msgbox_cfg);<br>
-			</code><code>if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&amp;msgbox_cfg, &amp;len))<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// handle configuration error<br>
-			</code><code>} </code></p>
-		<h4>Remote frame response buffer configuration</h4>
-		<p>The remote frame is a message frame which is transmitted to request a data frame. Some CAN hardware generates receive interrupts when a remote transmission request arrives. Other CAN hardware, i.e. the FlexCAN module, does not generate any receive interrupt. These CAN hardware chips, i.e. the FlexCAN module, can be configured to transmit a data frame automatically in response to a remote frame. In oder to support any kind of CAN hardware the eCos CAN driver provides a generic handling of remote transmission requests.</p>
-		<p>The transmission of the data frame in response to a remote frame is completely handled by the CAN driver. If the hardware driver, like the driver for the FlexCAN modul, supports harware message buffers, then the response frame is automatically transmitted if a remote transmission request with a matching ID arrives. If a CAN hardware does not provide hardware support for sending data frames in response to a remote frame, then this need to be implemented in software by the hardware device driver.</p>
-		<p>It is always possible to add remote response buffers. It does not matter if the driver is configured for reception of all CAN messages or if message filtering is used.&nbsp;As long as there are free message buffers available, it is possible to add remote response buffers.</p>
-		<p>In order to respond to a remote frame, a remote frame reponse buffer need to be initialized before a data frame can be sent in response to a remote frame. This is achieved by by exchanging <code>cyg_can_remote_buf </code>data structures with the driver via the <code>cyg_io_set_config()</code> function using the config key <code>CYG_IO_SET_CONFIG_CAN_MSGBUF</code>. Once the buffer is initialized, the CAN data can be changed at any time by the application.</p>
-		<p><code>typedef struct cyg_can_msgbuf_cfg_st<br>
-			</code><code>{<br>&nbsp;&nbsp;&nbsp;&nbsp;cyg_can_msgbuf_cfg_id cfg_id; // configuration id - cfg. what to do with message buffer<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_msgbuf_handle  handle; // handle to message buffer<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_message msg; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// CAN message - for configuration of buffer<br>
-				} cyg_can_remote_buf;<br>
-			</code></p>
-		<p>The CAN frame that should be transmitted in response to a remote frame is stored in the<i> msg</i> field of the <code>cyg_can_remote_buf </code>data structure. If there is no buffer initialized for this data, the value of the <i>handle</i> field need to be set to <code>CYGNUM_CAN_MSGBUF_INIT</code>. After the call to <code>cyg_io_set_config()</code> the <i>handle</i> field contains a valid value ( &gt;= 0) or the value <code>CYGNUM_CAN_MSGBUF_NA</code>  ( &lt; 0) if no free buffer is available. With the valid handle value the CAN data can be changed later by calling  <code>cyg_io_set_config(). </code>Before adding remote buffers the device should be stopped and after configuration it should be set into operational mode again</p>
-		<p>Example code for setting up a remote response buffer:</p>
-		<p><code>cyg_can_remote_buf rtr_buf;<br>
-				<br>
-				// prepare the remote response buffer<br>rtr_buf.cfg_id &nbsp;= CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;<br>
-			</code><code>rtr_buf.handle &nbsp;= CYGNUM_CAN_MSGBUF_INIT;<br>
-			</code><code>rtr_buf.msg.id&nbsp; = 0x7FF;<br>
-			</code><code>rtr_buf.msg.ext     = CYGNUM_CAN_ID_STD;<br>
-			</code><code>rtr_buf.msg.rtr     = CYGNUM_CAN_FRAME_DATA;<br>
-			</code><code>rtr_buf.msg.dlc     = 1;<br>
-			</code><code>rtr_buf.msg.data[0] = 0xAB;<br>
-				<br>
-				
-				len = sizeof(rtr_buf);<br>
-			</code><code>if (ENOERR != cyg_io_set_config(hDrvFlexCAN, <br>
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CYG_IO_SET_CONFIG_CAN_MSGBUF,<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;rtr_buf, &amp;len))<br>
-			</code><code>{<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;// handle configuration error<br>
-			</code><code>} <br>
-			</code><code><br>
-			</code><code>if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)<br>
-			</code><code>{<br>
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;// no free message buffer available - handle this problem here<br>
-			</code><code>}<br>
-				<br>
-				<br>
-				
-				// change CAN data for a buffer that is already initialized<br>
-			</code><code>rtr_buf.cfg_id      = CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE;<br>
-				
-				
-				rtr_buf.msg.data[0] = 0x11;<br>
-				<br>
-				
-				
-				len = sizeof(rtr_buf);<br>
-			</code><code>if (ENOERR != cyg_io_set_config(hDrvFlexCAN, <br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CYG_IO_SET_CONFIG_CAN_MSGBUF,<br>
-				
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;rtr_buf, &amp;len))<br>
-			</code><code>{<br>
-				
-				
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;// handle configuration error<br>
-			</code><code>} <br>
-			</code></p>
-		<h4>Message filter configuration</h4>
-		<p> If message filtering is done by hardware the number of received CAN messages decreases and so also the time for processing received CAN messages and the memory required for buffering received messages decreases. This saves valuable memory and processing time. The eCos CAN driver supports a generic way of adding message filters. By default the CAN driver is configured for reception of any kind of CAN standard and extended frames. As soon as a message filter is added, the CAN driver will only receive the CAN frames with the identifier of the CAN filter. By adding a number of message filters it is possible for the CAN hardware to receive an number of different CAN messages.</p>
-		<p>Adding message filters is only possible if driver is not configured for reception of all available CAN messages. If driver is configured for recption of all CAN messages then message buffers neet to be reset before adding single message filters.</p>
-		<p>In order to add a message filter, a message buffer need to be initialized. This is achieved by by exchanging <code>cyg_can_filter </code>data structures with the driver via the <code>cyg_io_set_config()</code> function using the config key <code>CYG_IO_SET_CONFIG_CAN_MSGBUF</code>. Once the buffer is initialized, the CAN hardware can recive messages with the identifier of the filter.</p>
-		<p><code>typedef struct cyg_can_msgbox_cfg_st<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;cyg_can_msgbuf_cfg_id cfg_id;<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_msgbuf_handle  handle;<br>
-				
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>cyg_can_message &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg;<br>
-			</code><code>} cyg_can_filter;</code></p>
-		<p>After the call to <code>cyg_io_set_config()</code> the <i>handle</i> field contains a valid value ( &gt;= 0) or the value <code>CYGNUM_CAN_MSGBUF_NA</code> ( &lt; 0) if no free buffer is available. Before adding message filters the device should be stopped and after configuration it should be set into operational mode again</p>
-		<p>Example code for setting up a message filter:</p>
-		<p><code>cyg_can_msgbuf_cfg  msgbox_cfg;<br>
-				cyg_can_filter      rx_filter;<br>
-				<br>
-				// reset all message buffers</code><br>
-			<code>msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;<br>
-			</code><code>len = sizeof(msgbox_cfg);<br>
-			</code><code>if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&amp;msgbox_cfg, &amp;len))<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// handle configuration error<br>
-			</code><code>} <br>
-				<br>
-			</code><code>// prepare the message filter<br>
-				rx_filter.cfg_id  = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD<br>
-			</code><code>rx_filter.msg.id &nbsp;= 0x800;<br>
-				rx_filter.msg.ext = CYGNUM_CAN_ID_EXT;<br>
-				<br>
-				len = sizeof(rx_filter);<br>
-				if (ENOERR != cyg_io_set_config(hDrvFlexCAN,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CYG_IO_SET_CONFIG_CAN_MSGBUF,<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;rx_filter, &amp;len))<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// handle configuration error;<br>
-			</code><code>}<br>
-			</code><code>else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;// no free message buffer available - handle this problem here<br>
-				}</code></p>
-		<h4>Receive all CAN  messages</h4>After startup of your device the CAN driver is configured for reception of all available CAN messages. If you change this configuration by adding single message filters then you can reset this default state with the configuration ID:		<p><code>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL</code> </p>
-		<p>A call to this function will clear all message filters and remote buffers and prepares the CAN hardware for recption of any kind of CAN standard and extended frames. It is not neccesary to reset the message buffer configuration before this configuration is setup because this should be done by device driver.</p>
-		<p>Example code for setup of a receive all CAN frames configuration:</p>
-		<p><code>cyg_can_filter rx_filter;<br>
-				<br>
-				// now setup a RX all configuration<br>
-			</code><code>rx_filter.cfg_id  = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;<br>
-			</code><code>len = sizeof(rx_filter);<br>
-			</code><code>if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF , &amp;rx_filter, &amp;len))<br>
-			</code><code>{<br>
-				&nbsp;&nbsp;&nbsp;&nbsp;</code><code>CYG_TEST_FAIL_FINISH(&quot;Error writing config of /dev/can0&quot;);<br>
-			</code><code>}</code></p>
-		<h4>Set mode of CAN hardware</h4>
-		<p><code>typedef enum <br>
-			</code><code>{<br>
-				&nbsp;&nbsp;CYGNUM_CAN_MODE_STOP,&nbsp;&nbsp;&nbsp;// set controller into stop mode<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_MODE_START,&nbsp;&nbsp;// set controller into operational mode<br>
-				&nbsp;&nbsp;</code><code>CYGNUM_CAN_MODE_STANDBY&nbsp;// set controller into standby / sleep mode<br>
-				} cyg_can_mode;</code></p>
-		<p><code>CYG_IO_SET_CONFIG_CAN_MODE</code> - This function changes the operating mode of the CAN controller. Possible values for mode are defined in the <code>cyg_can_mode</code> enumeration. Befor the hardware configuration of the device is changed, that means if baudrate is changed or the message buffer and filter configuration is changed, the CAN hardware should be set into stop mode and if configuration is finished, then device should be set back into operational mode. Before the device is set into standby mode, the output buffers should be flushed or drained because transmission of a CAN message may wake up the CAN hardware. If a received message wakes up the CAN hardware from standby mode then a <code>CYGNUM_CAN_EVENT_LEAVING_STANDBY</code> event will be inserted into receive message buffer or the <code>CYGNUM_CAN_EVENT_LEAVING_STANDBY </code>flag will be set for the message that caused wake up of CAN hardware.</p>
-		<h2>FlexCAN device driver</h2>
-		<p>The FlexCAN module is a communication controller implementing the controller area network (CAN) protocol, an asynchronous communications protocol used in automotive and industrial control systems. It is a high speed (1 Mbit/sec), short distance, priority based protocol which can communicate using a variety of mediums (for example, fiber optic cable or an unshielded twisted pair of wires). The FlexCAN supports both the standard and extended identifier (ID) message formats specified in the CAN protocol specification, revision 2.0, part B.</p>
-		<p>It supports up to 16 flexible flexible message buffers of 0-8 bytes data length, each configurable as Rx or Tx, all supporting standard and extended messages.</p>
-		<p>The message buffer 16 of the FlexCAN modul is reserved for transmission of CAN messages. Message buffers 1 - 15 are available for configuration of remote buffers and message filters. If the FlexCAN modul is configured for reception of all CAN frames, then the user can select the number of buffers used for reception of CAN frames. The interrupt priority of each message box is configurable.</p>
-	</body>
-
-</html>
\ No newline at end of file
