OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [ref/] [usbs-writing.html] - Diff between revs 28 and 174

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 28 Rev 174
<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
<!-- This material may be distributed only subject to the terms      -->
<!-- This material may be distributed only subject to the terms      -->
<!-- and conditions set forth in the Open Publication License, v1.0  -->
<!-- and conditions set forth in the Open Publication License, v1.0  -->
<!-- or later (the latest version is presently available at          -->
<!-- or later (the latest version is presently available at          -->
<!-- http://www.opencontent.org/openpub/).                           -->
<!-- http://www.opencontent.org/openpub/).                           -->
<!-- Distribution of the work or derivative of the work in any       -->
<!-- Distribution of the work or derivative of the work in any       -->
<!-- standard (paper) book form is prohibited unless prior           -->
<!-- standard (paper) book form is prohibited unless prior           -->
<!-- permission is obtained from the copyright holder.               -->
<!-- permission is obtained from the copyright holder.               -->
<HTML
<HTML
><HEAD
><HEAD
><TITLE
><TITLE
>Writing a USB Device Driver</TITLE
>Writing a USB Device Driver</TITLE
><meta name="MSSmartTagsPreventParsing" content="TRUE">
><meta name="MSSmartTagsPreventParsing" content="TRUE">
<META
<META
NAME="GENERATOR"
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
"><LINK
REL="HOME"
REL="HOME"
TITLE="eCos Reference Manual"
TITLE="eCos Reference Manual"
HREF="ecos-ref.html"><LINK
HREF="ecos-ref.html"><LINK
REL="UP"
REL="UP"
TITLE="eCos USB Slave Support"
TITLE="eCos USB Slave Support"
HREF="io-usb-slave.html"><LINK
HREF="io-usb-slave.html"><LINK
REL="PREVIOUS"
REL="PREVIOUS"
TITLE="Data Endpoints"
TITLE="Data Endpoints"
HREF="usbs-data.html"><LINK
HREF="usbs-data.html"><LINK
REL="NEXT"
REL="NEXT"
TITLE="Testing"
TITLE="Testing"
HREF="usbs-testing.html"></HEAD
HREF="usbs-testing.html"></HEAD
><BODY
><BODY
CLASS="REFENTRY"
CLASS="REFENTRY"
BGCOLOR="#FFFFFF"
BGCOLOR="#FFFFFF"
TEXT="#000000"
TEXT="#000000"
LINK="#0000FF"
LINK="#0000FF"
VLINK="#840084"
VLINK="#840084"
ALINK="#0000FF"
ALINK="#0000FF"
><DIV
><DIV
CLASS="NAVHEADER"
CLASS="NAVHEADER"
><TABLE
><TABLE
SUMMARY="Header navigation table"
SUMMARY="Header navigation table"
WIDTH="100%"
WIDTH="100%"
BORDER="0"
BORDER="0"
CELLPADDING="0"
CELLPADDING="0"
CELLSPACING="0"
CELLSPACING="0"
><TR
><TR
><TH
><TH
COLSPAN="3"
COLSPAN="3"
ALIGN="center"
ALIGN="center"
>eCos Reference Manual</TH
>eCos Reference Manual</TH
></TR
></TR
><TR
><TR
><TD
><TD
WIDTH="10%"
WIDTH="10%"
ALIGN="left"
ALIGN="left"
VALIGN="bottom"
VALIGN="bottom"
><A
><A
HREF="usbs-data.html"
HREF="usbs-data.html"
ACCESSKEY="P"
ACCESSKEY="P"
>Prev</A
>Prev</A
></TD
></TD
><TD
><TD
WIDTH="80%"
WIDTH="80%"
ALIGN="center"
ALIGN="center"
VALIGN="bottom"
VALIGN="bottom"
></TD
></TD
><TD
><TD
WIDTH="10%"
WIDTH="10%"
ALIGN="right"
ALIGN="right"
VALIGN="bottom"
VALIGN="bottom"
><A
><A
HREF="usbs-testing.html"
HREF="usbs-testing.html"
ACCESSKEY="N"
ACCESSKEY="N"
>Next</A
>Next</A
></TD
></TD
></TR
></TR
></TABLE
></TABLE
><HR
><HR
ALIGN="LEFT"
ALIGN="LEFT"
WIDTH="100%"></DIV
WIDTH="100%"></DIV
><H1
><H1
><A
><A
NAME="USBS-WRITING">Writing a USB Device Driver</H1
NAME="USBS-WRITING">Writing a USB Device Driver</H1
><DIV
><DIV
CLASS="REFNAMEDIV"
CLASS="REFNAMEDIV"
><A
><A
NAME="AEN16705"
NAME="AEN16705"
></A
></A
><H2
><H2
>Name</H2
>Name</H2
>Writing a USB Device Driver&nbsp;--&nbsp;USB Device Driver Porting Guide</DIV
>Writing a USB Device Driver&nbsp;--&nbsp;USB Device Driver Porting Guide</DIV
><DIV
><DIV
CLASS="REFSECT1"
CLASS="REFSECT1"
><A
><A
NAME="AEN16708"
NAME="AEN16708"
></A
></A
><H2
><H2
>Introduction</H2
>Introduction</H2
><P
><P
>Often the best way to write a USB device driver will be to start with
>Often the best way to write a USB device driver will be to start with
an existing one and modify it as necessary. The information given here
an existing one and modify it as necessary. The information given here
is intended primarily as an outline rather than as a complete guide.</P
is intended primarily as an outline rather than as a complete guide.</P
><DIV
><DIV
CLASS="NOTE"
CLASS="NOTE"
><BLOCKQUOTE
><BLOCKQUOTE
CLASS="NOTE"
CLASS="NOTE"
><P
><P
><B
><B
>Note: </B
>Note: </B
>At the time of writing only one USB device driver has been
>At the time of writing only one USB device driver has been
implemented. Hence it is possible, perhaps probable, that some
implemented. Hence it is possible, perhaps probable, that some
portability issues have not yet been addressed. One issue
portability issues have not yet been addressed. One issue
involves the different types of transfer, for example the initial
involves the different types of transfer, for example the initial
target hardware had no support for isochronous or interrupt transfers,
target hardware had no support for isochronous or interrupt transfers,
so additional functionality may be needed to switch between transfer
so additional functionality may be needed to switch between transfer
types. Another issue would be hardware where a given endpoint number,
types. Another issue would be hardware where a given endpoint number,
say endpoint 1, could be used for either receiving or transmitting
say endpoint 1, could be used for either receiving or transmitting
data, but not both because a single fifo is used. Issues like these
data, but not both because a single fifo is used. Issues like these
will have to be resolved as and when additional USB device drivers are
will have to be resolved as and when additional USB device drivers are
written.</P
written.</P
></BLOCKQUOTE
></BLOCKQUOTE
></DIV
></DIV
></DIV
></DIV
><DIV
><DIV
CLASS="REFSECT1"
CLASS="REFSECT1"
><A
><A
NAME="AEN16713"
NAME="AEN16713"
></A
></A
><H2
><H2
>The Control Endpoint</H2
>The Control Endpoint</H2
><P
><P
>A USB device driver should provide a single <A
>A USB device driver should provide a single <A
HREF="usbs-control.html"
HREF="usbs-control.html"
><SPAN
><SPAN
CLASS="STRUCTNAME"
CLASS="STRUCTNAME"
>usbs_control_endpoint</SPAN
>usbs_control_endpoint</SPAN
></A
></A
>
>
data structure for every USB device. Typical peripherals will have
data structure for every USB device. Typical peripherals will have
only one USB port so there will be just one such data structure in the
only one USB port so there will be just one such data structure in the
entire system, but theoretically it is possible to have multiple USB
entire system, but theoretically it is possible to have multiple USB
devices. These may all involve the same chip, in which case a single
devices. These may all involve the same chip, in which case a single
device driver should support multiple device instances, or they may
device driver should support multiple device instances, or they may
involve different chips. The name or names of these data structures
involve different chips. The name or names of these data structures
are determined by the device driver, but appropriate care should be
are determined by the device driver, but appropriate care should be
taken to avoid name clashes. </P
taken to avoid name clashes. </P
><P
><P
>A USB device cannot be used unless the control endpoint data structure
>A USB device cannot be used unless the control endpoint data structure
exists. However, the presence of USB hardware in the target processor
exists. However, the presence of USB hardware in the target processor
or board does not guarantee that the application will necessarily want
or board does not guarantee that the application will necessarily want
to use that hardware. To avoid unwanted code or data overheads, the
to use that hardware. To avoid unwanted code or data overheads, the
device driver can provide a configuration option to determine whether
device driver can provide a configuration option to determine whether
or not the endpoint 0 data structure is actually provided. A default
or not the endpoint 0 data structure is actually provided. A default
value of <TT
value of <TT
CLASS="LITERAL"
CLASS="LITERAL"
>CYGINT_IO_USB_SLAVE_CLIENTS</TT
>CYGINT_IO_USB_SLAVE_CLIENTS</TT
> ensures that
> ensures that
the USB driver will be enabled automatically if higher-level code does
the USB driver will be enabled automatically if higher-level code does
require USB support, while leaving ultimate control to the user.</P
require USB support, while leaving ultimate control to the user.</P
><P
><P
>The USB device driver is responsible for filling in the
>The USB device driver is responsible for filling in the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>start_fn</I
>start_fn</I
></TT
></TT
>,
>,
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>poll_fn</I
>poll_fn</I
></TT
></TT
> and
> and
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>interrupt_vector</I
>interrupt_vector</I
></TT
></TT
> fields. Usually this can
> fields. Usually this can
be achieved by static initialization. The driver is also largely
be achieved by static initialization. The driver is also largely
responsible for maintaining the <TT
responsible for maintaining the <TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>state</I
>state</I
></TT
></TT
>
>
field. The <TT
field. The <TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>control_buffer</I
>control_buffer</I
></TT
></TT
> array should be
> array should be
used to hold the first packet of a control message. The
used to hold the first packet of a control message. The
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>buffer</I
>buffer</I
></TT
></TT
> and other fields related to data
> and other fields related to data
transfers will be managed <A
transfers will be managed <A
HREF="usbs-control.html#AEN16615"
HREF="usbs-control.html#AEN16615"
>jointly</A
>jointly</A
> by higher-level code and
> by higher-level code and
the device driver. The remaining fields are generally filled in by
the device driver. The remaining fields are generally filled in by
higher-level code, although the driver should initialize them to NULL
higher-level code, although the driver should initialize them to NULL
values.</P
values.</P
><P
><P
>Hardware permitting, the USB device should be inactive until the
>Hardware permitting, the USB device should be inactive until the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>start_fn</I
>start_fn</I
></TT
></TT
> is invoked, for example by
> is invoked, for example by
tristating the appropriate pins. This prevents the host from
tristating the appropriate pins. This prevents the host from
interacting with the peripheral before all other parts of the system
interacting with the peripheral before all other parts of the system
have initialized. It is expected that the
have initialized. It is expected that the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>start_fn</I
>start_fn</I
></TT
></TT
> will only be invoked once, shortly
> will only be invoked once, shortly
after power-up.</P
after power-up.</P
><P
><P
>Where possible the device driver should detect state changes, such as
>Where possible the device driver should detect state changes, such as
when the connection between host and peripheral is established, and
when the connection between host and peripheral is established, and
<A
<A
HREF="usbs-control.html#AEN16552"
HREF="usbs-control.html#AEN16552"
>report</A
>report</A
> these to higher-level
> these to higher-level
code via the <TT
code via the <TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>state_change_fn</I
>state_change_fn</I
></TT
></TT
> callback, if
> callback, if
any. The state change to and from configured state cannot easily be
any. The state change to and from configured state cannot easily be
handled by the device driver itself, instead higher-level code such as
handled by the device driver itself, instead higher-level code such as
the common USB slave package will take care of this.</P
the common USB slave package will take care of this.</P
><P
><P
>Once the connection between host and peripheral has been established,
>Once the connection between host and peripheral has been established,
the peripheral must be ready to accept control messages at all times,
the peripheral must be ready to accept control messages at all times,
and must respond to these within certain time constraints. For
and must respond to these within certain time constraints. For
example, the standard set-address control message must be handled
example, the standard set-address control message must be handled
within 50ms. The USB specification provides more information on these
within 50ms. The USB specification provides more information on these
constraints. The device driver is responsible for receiving the
constraints. The device driver is responsible for receiving the
initial packet of a control message. This packet will always be eight
initial packet of a control message. This packet will always be eight
bytes and should be stored in the
bytes and should be stored in the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>control_buffer</I
>control_buffer</I
></TT
></TT
> field. Certain standard
> field. Certain standard
control messages should be detected and handled by the device driver
control messages should be detected and handled by the device driver
itself. The most important is set-address, but usually the get-status,
itself. The most important is set-address, but usually the get-status,
set-feature and clear-feature requests when applied to halted
set-feature and clear-feature requests when applied to halted
endpoints should also be handled by the driver. Other standard control
endpoints should also be handled by the driver. Other standard control
messages should first be passed on to the
messages should first be passed on to the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>standard_control_fn</I
>standard_control_fn</I
></TT
></TT
> callback (if any), and
> callback (if any), and
finally to the default handler
finally to the default handler
<TT
<TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_handle_standard_control</TT
>usbs_handle_standard_control</TT
> provided by the
> provided by the
common USB slave package. Class, vendor and reserved control messages
common USB slave package. Class, vendor and reserved control messages
should always be dispatched to the appropriate callback and there is
should always be dispatched to the appropriate callback and there is
no default handler for these.</P
no default handler for these.</P
><P
><P
>Some control messages will involve further data transfer, not just the
>Some control messages will involve further data transfer, not just the
initial packet. The device driver must handle this in accordance with
initial packet. The device driver must handle this in accordance with
the USB specification and the <A
the USB specification and the <A
HREF="usbs-control.html#AEN16615"
HREF="usbs-control.html#AEN16615"
>buffer management strategy</A
>buffer management strategy</A
>. The
>. The
driver is also responsible for keeping track of whether or not the
driver is also responsible for keeping track of whether or not the
control operation has succeeded and generating an ACK or STALL
control operation has succeeded and generating an ACK or STALL
handshake. </P
handshake. </P
><P
><P
>The polling support is optional and may not be feasible on all
>The polling support is optional and may not be feasible on all
hardware. It is only used in certain specialised environments such as
hardware. It is only used in certain specialised environments such as
RedBoot. A typical implementation of the polling function would just
RedBoot. A typical implementation of the polling function would just
check whether or not an interrupt would have occurred and, if so, call
check whether or not an interrupt would have occurred and, if so, call
the same code that the interrupt handler would.</P
the same code that the interrupt handler would.</P
></DIV
></DIV
><DIV
><DIV
CLASS="REFSECT1"
CLASS="REFSECT1"
><A
><A
NAME="AEN16741"
NAME="AEN16741"
></A
></A
><H2
><H2
>Data Endpoints</H2
>Data Endpoints</H2
><P
><P
>In addition to the control endpoint data structure, a USB device
>In addition to the control endpoint data structure, a USB device
driver should also provide appropriate <A
driver should also provide appropriate <A
HREF="usbs-data.html"
HREF="usbs-data.html"
>data
>data
endpoint</A
endpoint</A
> data structures. Obviously this is only relevant if
> data structures. Obviously this is only relevant if
the USB support generally is desired, that is if the control endpoint is
the USB support generally is desired, that is if the control endpoint is
provided. In addition, higher-level code may not require all the
provided. In addition, higher-level code may not require all the
endpoints, so it may be useful to provide configuration options that
endpoints, so it may be useful to provide configuration options that
control the presence of each endpoint. For example, the intended
control the presence of each endpoint. For example, the intended
application might only involve a single transmit endpoint and of
application might only involve a single transmit endpoint and of
course control messages, so supporting receive endpoints might waste
course control messages, so supporting receive endpoints might waste
memory.</P
memory.</P
><P
><P
>Conceptually, data endpoints are much simpler than the control
>Conceptually, data endpoints are much simpler than the control
endpoint. The device driver has to supply two functions, one for
endpoint. The device driver has to supply two functions, one for
data transfers and another to control the halted condition. These
data transfers and another to control the halted condition. These
implement the functionality for
implement the functionality for
<A
<A
HREF="usbs-start-rx.html"
HREF="usbs-start-rx.html"
><TT
><TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_start_rx_buffer</TT
>usbs_start_rx_buffer</TT
></A
></A
>,
>,
<A
<A
HREF="usbs-start-tx.html"
HREF="usbs-start-tx.html"
><TT
><TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_start_tx_buffer</TT
>usbs_start_tx_buffer</TT
></A
></A
>,
>,
<A
<A
HREF="usbs-halt.html"
HREF="usbs-halt.html"
><TT
><TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_set_rx_endpoint_halted</TT
>usbs_set_rx_endpoint_halted</TT
></A
></A
> and
> and
<A
<A
HREF="usbs-halt.html"
HREF="usbs-halt.html"
><TT
><TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_set_tx_endpoint_halted</TT
>usbs_set_tx_endpoint_halted</TT
></A
></A
>.
>.
The device driver is also responsible for maintaining the
The device driver is also responsible for maintaining the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>halted</I
>halted</I
></TT
></TT
> status.</P
> status.</P
><P
><P
>For data transfers, higher-level code will have filled in the
>For data transfers, higher-level code will have filled in the
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>buffer</I
>buffer</I
></TT
></TT
>,
>,
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>buffer_size</I
>buffer_size</I
></TT
></TT
>,
>,
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>complete_fn</I
>complete_fn</I
></TT
></TT
> and
> and
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>complete_data</I
>complete_data</I
></TT
></TT
> fields. The transfer function
> fields. The transfer function
should arrange for the transfer to start, allowing the host to send or
should arrange for the transfer to start, allowing the host to send or
receive packets. Typically this will result in an interrupt at the end
receive packets. Typically this will result in an interrupt at the end
of the transfer or after each packet. Once the entire transfer has
of the transfer or after each packet. Once the entire transfer has
been completed, the driver's interrupt handling code should invoke the
been completed, the driver's interrupt handling code should invoke the
completion function. This can happen either in DSR context or thread
completion function. This can happen either in DSR context or thread
context, depending on the driver's implementation. There are a number
context, depending on the driver's implementation. There are a number
of special cases to consider. If the endpoint is halted when the
of special cases to consider. If the endpoint is halted when the
transfer is started then the completion function can be invoked
transfer is started then the completion function can be invoked
immediately with <TT
immediately with <TT
CLASS="LITERAL"
CLASS="LITERAL"
>-EAGAIN</TT
>-EAGAIN</TT
>. If the transfer cannot be
>. If the transfer cannot be
completed because the connection is broken then the completion
completed because the connection is broken then the completion
function should be invoked with <TT
function should be invoked with <TT
CLASS="LITERAL"
CLASS="LITERAL"
>-EPIPE</TT
>-EPIPE</TT
>. If the
>. If the
endpoint is stalled during the transfer, either because of a standard
endpoint is stalled during the transfer, either because of a standard
control message or because higher-level code calls the appropriate
control message or because higher-level code calls the appropriate
<TT
<TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>set_halted_fn</I
>set_halted_fn</I
></TT
></TT
>, then again the completion
>, then again the completion
function should be invoked with <TT
function should be invoked with <TT
CLASS="LITERAL"
CLASS="LITERAL"
>-EAGAIN</TT
>-EAGAIN</TT
>. Finally,
>. Finally,
the &#60;<TT
the &#60;<TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_start_rx_endpoint_wait</TT
>usbs_start_rx_endpoint_wait</TT
> and
> and
<TT
<TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_start_tx_endpoint_wait</TT
>usbs_start_tx_endpoint_wait</TT
> functions involve
> functions involve
calling the device driver's data transfer function with a buffer size
calling the device driver's data transfer function with a buffer size
of 0 bytes.</P
of 0 bytes.</P
><DIV
><DIV
CLASS="NOTE"
CLASS="NOTE"
><BLOCKQUOTE
><BLOCKQUOTE
CLASS="NOTE"
CLASS="NOTE"
><P
><P
><B
><B
>Note: </B
>Note: </B
>Giving a buffer size of 0 bytes a special meaning is problematical
>Giving a buffer size of 0 bytes a special meaning is problematical
because it prevents transfers of that size. Such transfers are allowed
because it prevents transfers of that size. Such transfers are allowed
by the USB protocol, consisting of just headers and acknowledgements
by the USB protocol, consisting of just headers and acknowledgements
and an empty data phase, although rarely useful. A future modification
and an empty data phase, although rarely useful. A future modification
of the device driver specification will address this issue, although
of the device driver specification will address this issue, although
care has to be taken that the functionality remains accessible through
care has to be taken that the functionality remains accessible through
devtab entries as well as via low-level accesses.</P
devtab entries as well as via low-level accesses.</P
></BLOCKQUOTE
></BLOCKQUOTE
></DIV
></DIV
></DIV
></DIV
><DIV
><DIV
CLASS="REFSECT1"
CLASS="REFSECT1"
><A
><A
NAME="AEN16768"
NAME="AEN16768"
></A
></A
><H2
><H2
>Devtab Entries</H2
>Devtab Entries</H2
><P
><P
>For some applications or higher-level packages it may be more
>For some applications or higher-level packages it may be more
convenient to use traditional open/read/write I/O calls rather than
convenient to use traditional open/read/write I/O calls rather than
the non-blocking USB I/O calls. To support this the device driver can
the non-blocking USB I/O calls. To support this the device driver can
provide a devtab entry for each endpoint, for example:</P
provide a devtab entry for each endpoint, for example:</P
><TABLE
><TABLE
BORDER="5"
BORDER="5"
BGCOLOR="#E0E0F0"
BGCOLOR="#E0E0F0"
WIDTH="70%"
WIDTH="70%"
><TR
><TR
><TD
><TD
><PRE
><PRE
CLASS="PROGRAMLISTING"
CLASS="PROGRAMLISTING"
>#ifdef CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY
>#ifdef CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY
 
 
static CHAR_DEVIO_TABLE(usbs_sa11x0_ep1_devtab_functions,
static CHAR_DEVIO_TABLE(usbs_sa11x0_ep1_devtab_functions,
                        &amp;cyg_devio_cwrite,
                        &amp;cyg_devio_cwrite,
                        &amp;usbs_devtab_cread,
                        &amp;usbs_devtab_cread,
                        &amp;cyg_devio_bwrite,
                        &amp;cyg_devio_bwrite,
                        &amp;cyg_devio_bread,
                        &amp;cyg_devio_bread,
                        &amp;cyg_devio_select,
                        &amp;cyg_devio_select,
                        &amp;cyg_devio_get_config,
                        &amp;cyg_devio_get_config,
                        &amp;cyg_devio_set_config);
                        &amp;cyg_devio_set_config);
 
 
static CHAR_DEVTAB_ENTRY(usbs_sa11x0_ep1_devtab_entry,
static CHAR_DEVTAB_ENTRY(usbs_sa11x0_ep1_devtab_entry,
                         CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "1r",
                         CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "1r",
                         0,
                         0,
                         &amp;usbs_sa11x0_ep1_devtab_functions,
                         &amp;usbs_sa11x0_ep1_devtab_functions,
                         &amp;usbs_sa11x0_devtab_dummy_init,
                         &amp;usbs_sa11x0_devtab_dummy_init,
                         0,
                         0,
                         (void*) &amp;usbs_sa11x0_ep1);
                         (void*) &amp;usbs_sa11x0_ep1);
#endif</PRE
#endif</PRE
></TD
></TD
></TR
></TR
></TABLE
></TABLE
><P
><P
>Again care must be taken to avoid name clashes. This can be achieved
>Again care must be taken to avoid name clashes. This can be achieved
by having a configuration option to control the base name, with a
by having a configuration option to control the base name, with a
default value of e.g. <TT
default value of e.g. <TT
CLASS="LITERAL"
CLASS="LITERAL"
>/dev/usbs</TT
>/dev/usbs</TT
>, and appending an
>, and appending an
endpoint-specific string. This gives the application developer
endpoint-specific string. This gives the application developer
sufficient control to eliminate any name clashes. The common USB slave
sufficient control to eliminate any name clashes. The common USB slave
package provides functions <TT
package provides functions <TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_devtab_cwrite</TT
>usbs_devtab_cwrite</TT
> and
> and
<TT
<TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>usbs_devtab_cread</TT
>usbs_devtab_cread</TT
>, which can be used in the
>, which can be used in the
function tables for transmit and receive endpoints respectively. The
function tables for transmit and receive endpoints respectively. The
private field <TT
private field <TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>priv</I
>priv</I
></TT
></TT
> of the devtab entry
> of the devtab entry
should be a pointer to the underlying endpoint data structure.</P
should be a pointer to the underlying endpoint data structure.</P
><P
><P
>Because devtab entries are never accessed directly, only indirectly,
>Because devtab entries are never accessed directly, only indirectly,
they would usually be eliminated by the linker. To avoid this the
they would usually be eliminated by the linker. To avoid this the
devtab entries should normally be defined in a separate source file
devtab entries should normally be defined in a separate source file
which ends up the special library <TT
which ends up the special library <TT
CLASS="FILENAME"
CLASS="FILENAME"
>libextras.a</TT
>libextras.a</TT
>
>
rather than in the default library <TT
rather than in the default library <TT
CLASS="FILENAME"
CLASS="FILENAME"
>libtarget.a</TT
>libtarget.a</TT
>.</P
>.</P
><P
><P
>Not all applications or higher-level packages will want to use the
>Not all applications or higher-level packages will want to use the
devtab entries and the blocking I/O facilities. It may be appropriate
devtab entries and the blocking I/O facilities. It may be appropriate
for the device driver to provide additional configuration options that
for the device driver to provide additional configuration options that
control whether or not any or all of the devtab entries should be
control whether or not any or all of the devtab entries should be
provided, to avoid unnecessary memory overheads.</P
provided, to avoid unnecessary memory overheads.</P
></DIV
></DIV
><DIV
><DIV
CLASS="REFSECT1"
CLASS="REFSECT1"
><A
><A
NAME="AEN16781"
NAME="AEN16781"
></A
></A
><H2
><H2
>Interrupt Handling</H2
>Interrupt Handling</H2
><P
><P
>A typical USB device driver will need to service interrupts for all of
>A typical USB device driver will need to service interrupts for all of
the endpoints and possibly for additional USB events such as entering
the endpoints and possibly for additional USB events such as entering
or leaving suspended mode. Usually these interrupts need not be
or leaving suspended mode. Usually these interrupts need not be
serviced directly by the ISR. Instead, they can be left to a DSR. If
serviced directly by the ISR. Instead, they can be left to a DSR. If
the peripheral is not able to accept or send another packet just yet,
the peripheral is not able to accept or send another packet just yet,
the hardware will generate a NAK and the host will just retry a little
the hardware will generate a NAK and the host will just retry a little
bit later. If high throughput is required then it may be desirable to
bit later. If high throughput is required then it may be desirable to
handle the bulk transfer protocol largely at ISR level, that is take
handle the bulk transfer protocol largely at ISR level, that is take
care of each packet in the ISR and only activate the DSR once the
care of each packet in the ISR and only activate the DSR once the
whole transfer has completed.</P
whole transfer has completed.</P
><P
><P
>Control messages may involve invoking arbitrary callback functions in
>Control messages may involve invoking arbitrary callback functions in
higher-level code. This should normally happen at DSR level. Doing it
higher-level code. This should normally happen at DSR level. Doing it
at ISR level could seriously affect the system's interrupt latency and
at ISR level could seriously affect the system's interrupt latency and
impose unacceptable constraints on what operations can be performed by
impose unacceptable constraints on what operations can be performed by
those callbacks. If the device driver requires a thread anyway then it
those callbacks. If the device driver requires a thread anyway then it
may be appropriate to use this thread for invoking the callbacks, but
may be appropriate to use this thread for invoking the callbacks, but
usually it is not worthwhile to add a new thread to the system just
usually it is not worthwhile to add a new thread to the system just
for this; higher-level code is expected to write callbacks that
for this; higher-level code is expected to write callbacks that
function sensibly at DSR level. Much the same applies to the
function sensibly at DSR level. Much the same applies to the
completion functions associated with data transfers. These should also
completion functions associated with data transfers. These should also
be invoked at DSR or thread level.</P
be invoked at DSR or thread level.</P
></DIV
></DIV
><DIV
><DIV
CLASS="REFSECT1"
CLASS="REFSECT1"
><A
><A
NAME="AEN16785"
NAME="AEN16785"
></A
></A
><H2
><H2
>Support for USB Testing</H2
>Support for USB Testing</H2
><P
><P
>Optionally a USB device driver can provide support for the
>Optionally a USB device driver can provide support for the
<A
<A
HREF="usbs-testing.html"
HREF="usbs-testing.html"
>USB test software</A
>USB test software</A
>. This requires
>. This requires
defining a number of additional data structures, allowing the
defining a number of additional data structures, allowing the
generic test code to work out just what the hardware is capable of and
generic test code to work out just what the hardware is capable of and
hence what testing can be performed.</P
hence what testing can be performed.</P
><P
><P
>The key data structure is
>The key data structure is
<SPAN
<SPAN
CLASS="STRUCTNAME"
CLASS="STRUCTNAME"
>usbs_testing_endpoint</SPAN
>usbs_testing_endpoint</SPAN
>, defined in <TT
>, defined in <TT
CLASS="FILENAME"
CLASS="FILENAME"
>cyg/io/usb/usbs.h</TT
>cyg/io/usb/usbs.h</TT
>. In addition some
>. In addition some
commonly required constants are provided by the common USB package in
commonly required constants are provided by the common USB package in
<TT
<TT
CLASS="FILENAME"
CLASS="FILENAME"
>cyg/io/usb/usb.h</TT
>cyg/io/usb/usb.h</TT
>. One
>. One
<SPAN
<SPAN
CLASS="STRUCTNAME"
CLASS="STRUCTNAME"
>usbs_testing_endpoint</SPAN
>usbs_testing_endpoint</SPAN
> structure should be
> structure should be
defined for each supported endpoint. The following fields need to be
defined for each supported endpoint. The following fields need to be
filled in:</P
filled in:</P
><P
><P
></P
></P
><DIV
><DIV
CLASS="VARIABLELIST"
CLASS="VARIABLELIST"
><DL
><DL
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>endpoint_type</I
>endpoint_type</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    This specifies the type of endpoint and should be one of
>    This specifies the type of endpoint and should be one of
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL</TT
>USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL</TT
>,
>,
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>BULK</TT
>BULK</TT
>, <TT
>, <TT
CLASS="LITERAL"
CLASS="LITERAL"
>ISOCHRONOUS</TT
>ISOCHRONOUS</TT
> or
> or
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>INTERRUPT</TT
>INTERRUPT</TT
>.
>.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>endpoint_number</I
>endpoint_number</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    This identifies the number that should be used by the host
>    This identifies the number that should be used by the host
    to address this endpoint. For a control endpoint it should
    to address this endpoint. For a control endpoint it should
    be 0. For other types of endpoints it should be between
    be 0. For other types of endpoints it should be between
    1 and 15.
    1 and 15.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>endpoint_direction</I
>endpoint_direction</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    For control endpoints this field is irrelevant. For other
>    For control endpoints this field is irrelevant. For other
    types of endpoint it should be either
    types of endpoint it should be either
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN</TT
>USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN</TT
> or
> or
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT</TT
>USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT</TT
>. If a given
>. If a given
    endpoint number can be used for traffic in both directions then
    endpoint number can be used for traffic in both directions then
    there should be two entries in the array, one for each direction.
    there should be two entries in the array, one for each direction.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>endpoint</I
>endpoint</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    This should be a pointer to the appropriate
>    This should be a pointer to the appropriate
    <SPAN
    <SPAN
CLASS="STRUCTNAME"
CLASS="STRUCTNAME"
>usbs_control_endpoint</SPAN
>usbs_control_endpoint</SPAN
>,
>,
    <SPAN
    <SPAN
CLASS="STRUCTNAME"
CLASS="STRUCTNAME"
>usbs_rx_endpoint</SPAN
>usbs_rx_endpoint</SPAN
> or
> or
    <SPAN
    <SPAN
CLASS="STRUCTNAME"
CLASS="STRUCTNAME"
>usbs_tx_endpoint</SPAN
>usbs_tx_endpoint</SPAN
> structure, allowing the
> structure, allowing the
    generic testing code to perform low-level I/O.
    generic testing code to perform low-level I/O.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>devtab_entry</I
>devtab_entry</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    If the endpoint also has an entry in the system's device table then
>    If the endpoint also has an entry in the system's device table then
    this field should give the corresponding string, for example
    this field should give the corresponding string, for example
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>&quot;/dev/usbs1r&quot;</TT
>&quot;/dev/usbs1r&quot;</TT
>. This allows the
>. This allows the
    generic testing code to access the device via higher-level
    generic testing code to access the device via higher-level
    calls like <TT
    calls like <TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>open</TT
>open</TT
> and <TT
> and <TT
CLASS="FUNCTION"
CLASS="FUNCTION"
>read</TT
>read</TT
>.
>.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>min_size</I
>min_size</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    This indicates the smallest transfer size that the hardware can
>    This indicates the smallest transfer size that the hardware can
    support on this endpoint. Typically this will be one.
    support on this endpoint. Typically this will be one.
  </P
  </P
><DIV
><DIV
CLASS="NOTE"
CLASS="NOTE"
><BLOCKQUOTE
><BLOCKQUOTE
CLASS="NOTE"
CLASS="NOTE"
><P
><P
><B
><B
>Note: </B
>Note: </B
>    Strictly speaking a minimum size of one is not quite right since it
>    Strictly speaking a minimum size of one is not quite right since it
    is valid for a USB transfer to involve zero bytes, in other words a
    is valid for a USB transfer to involve zero bytes, in other words a
    transfer that involves just headers and acknowledgements and an
    transfer that involves just headers and acknowledgements and an
    empty data phase, and that should be tested as well. However current
    empty data phase, and that should be tested as well. However current
    device drivers interpret a transfer size of 0 as special, so that
    device drivers interpret a transfer size of 0 as special, so that
    would have to be resolved first.
    would have to be resolved first.
  </P
  </P
></BLOCKQUOTE
></BLOCKQUOTE
></DIV
></DIV
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>max_size</I
>max_size</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    Similarly, this specifies the largest transfer size. For control
>    Similarly, this specifies the largest transfer size. For control
    endpoints the USB protocol uses only two bytes to hold the transfer
    endpoints the USB protocol uses only two bytes to hold the transfer
    length, so there is an upper bound of 65535 bytes. In practice
    length, so there is an upper bound of 65535 bytes. In practice
    it is very unlikely that any control transfers would ever need to
    it is very unlikely that any control transfers would ever need to
    be this large, and in fact such transfers would take a long time
    be this large, and in fact such transfers would take a long time
    and probably violate timing constraints. For other types of endpoint
    and probably violate timing constraints. For other types of endpoint
    any of the protocol, the hardware, or the device driver may impose
    any of the protocol, the hardware, or the device driver may impose
    size limits. For example a given device driver might be unable to
    size limits. For example a given device driver might be unable to
    cope with transfers larger than 65535 bytes. If it should be
    cope with transfers larger than 65535 bytes. If it should be
    possible to transfer arbitrary amounts of data then a value of
    possible to transfer arbitrary amounts of data then a value of
    <TT
    <TT
CLASS="LITERAL"
CLASS="LITERAL"
>-1</TT
>-1</TT
> indicates no upper limit, and transfer
> indicates no upper limit, and transfer
    sizes will be limited by available memory and by the capabilities
    sizes will be limited by available memory and by the capabilities
    of the host machine.
    of the host machine.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>max_in_padding</I
>max_in_padding</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    This field is needed on some hardware where it is impossible to
>    This field is needed on some hardware where it is impossible to
    send packets of a certain size. For example the hardware may be
    send packets of a certain size. For example the hardware may be
    incapable of sending an empty bulk packet to terminate a transfer
    incapable of sending an empty bulk packet to terminate a transfer
    that is an exact multiple of the 64-byte bulk packet size.
    that is an exact multiple of the 64-byte bulk packet size.
    Instead the driver has to do some padding and send an extra byte,
    Instead the driver has to do some padding and send an extra byte,
    and the host has to be prepared to receive this extra byte. Such a
    and the host has to be prepared to receive this extra byte. Such a
    driver should specify a value of <TT
    driver should specify a value of <TT
CLASS="LITERAL"
CLASS="LITERAL"
>1</TT
>1</TT
> for the
> for the
    padding field. For most drivers this field should be set to
    padding field. For most drivers this field should be set to
  <TT
  <TT
CLASS="LITERAL"
CLASS="LITERAL"
>0</TT
>0</TT
>.
>.
  </P
  </P
><P
><P
>    A better solution would be for the device driver to supply a
>    A better solution would be for the device driver to supply a
    fragment of Tcl code that would adjust the receive buffer size
    fragment of Tcl code that would adjust the receive buffer size
    only when necessary, rather than for every transfer. Forcing
    only when necessary, rather than for every transfer. Forcing
    receive padding on all transfers when only certain transfers
    receive padding on all transfers when only certain transfers
    will actually be padded reduces the accuracy of certain tests.
    will actually be padded reduces the accuracy of certain tests.
  </P
  </P
></DD
></DD
><DT
><DT
><TT
><TT
CLASS="STRUCTFIELD"
CLASS="STRUCTFIELD"
><I
><I
>alignment</I
>alignment</I
></TT
></TT
></DT
></DT
><DD
><DD
><P
><P
>    On some hardware data transfers may need to be aligned to certain
>    On some hardware data transfers may need to be aligned to certain
    boundaries, for example a word boundary or a cacheline boundary.
    boundaries, for example a word boundary or a cacheline boundary.
    Although in theory device drivers could hide such alignment
    Although in theory device drivers could hide such alignment
    restrictions from higher-level code by having their own buffers and
    restrictions from higher-level code by having their own buffers and
    performing appropriate copying, that would be expensive in terms of
    performing appropriate copying, that would be expensive in terms of
    both memory and cpu cycles. Instead the generic testing code will
    both memory and cpu cycles. Instead the generic testing code will
    align any buffers passed to the device driver to the specified
    align any buffers passed to the device driver to the specified
    boundary. For example, if the driver requires that buffers be
    boundary. For example, if the driver requires that buffers be
    aligned to a word boundary then it should specify an alignment
    aligned to a word boundary then it should specify an alignment
    value of 4.
    value of 4.
  </P
  </P
></DD
></DD
></DL
></DL
></DIV
></DIV
><P
><P
>The device driver should provide an array of these structures
>The device driver should provide an array of these structures
<TT
<TT
CLASS="VARNAME"
CLASS="VARNAME"
>usbs_testing_endpoints[]</TT
>usbs_testing_endpoints[]</TT
>. The USB testing code
>. The USB testing code
examines this array and uses the information to perform appropriate
examines this array and uses the information to perform appropriate
tests. Because different USB devices support different numbers of
tests. Because different USB devices support different numbers of
endpoints the number of entries in the array is not known in advance,
endpoints the number of entries in the array is not known in advance,
so instead the testing code looks for a special terminator
so instead the testing code looks for a special terminator
<TT
<TT
CLASS="VARNAME"
CLASS="VARNAME"
>USBS_TESTING_ENDPOINTS_TERMINATOR</TT
>USBS_TESTING_ENDPOINTS_TERMINATOR</TT
>. An example
>. An example
array, showing just the control endpoint and the terminator, might
array, showing just the control endpoint and the terminator, might
look like this:</P
look like this:</P
><TABLE
><TABLE
BORDER="5"
BORDER="5"
BGCOLOR="#E0E0F0"
BGCOLOR="#E0E0F0"
WIDTH="70%"
WIDTH="70%"
><TR
><TR
><TD
><TD
><PRE
><PRE
CLASS="PROGRAMLISTING"
CLASS="PROGRAMLISTING"
>usbs_testing_endpoint usbs_testing_endpoints[] = {
>usbs_testing_endpoint usbs_testing_endpoints[] = {
    {
    {
        endpoint_type       : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
        endpoint_type       : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
        endpoint_number     : 0,
        endpoint_number     : 0,
        endpoint_direction  : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
        endpoint_direction  : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
        endpoint            : (void*) &amp;ep0.common,
        endpoint            : (void*) &amp;ep0.common,
        devtab_entry        : (const char*) 0,
        devtab_entry        : (const char*) 0,
        min_size            : 1,
        min_size            : 1,
        max_size            : 0x0FFFF,
        max_size            : 0x0FFFF,
        max_in_padding      : 0,
        max_in_padding      : 0,
        alignment           : 0
        alignment           : 0
    },
    },
    &#8230;,
    &#8230;,
    USBS_TESTING_ENDPOINTS_TERMINATOR
    USBS_TESTING_ENDPOINTS_TERMINATOR
};</PRE
};</PRE
></TD
></TD
></TR
></TR
></TABLE
></TABLE
><DIV
><DIV
CLASS="NOTE"
CLASS="NOTE"
><BLOCKQUOTE
><BLOCKQUOTE
CLASS="NOTE"
CLASS="NOTE"
><P
><P
><B
><B
>Note: </B
>Note: </B
>The use of a single array <TT
>The use of a single array <TT
CLASS="VARNAME"
CLASS="VARNAME"
>usbs_testing_endpoints</TT
>usbs_testing_endpoints</TT
>
>
limits USB testing to platforms with a single USB device: if there
limits USB testing to platforms with a single USB device: if there
were multiple devices, each defining their own instance of this array,
were multiple devices, each defining their own instance of this array,
then there would a collision at link time. In practice this should not
then there would a collision at link time. In practice this should not
be a major problem since typical USB peripherals only interact with a
be a major problem since typical USB peripherals only interact with a
single host machine via a single slave port. In addition, even if a
single host machine via a single slave port. In addition, even if a
peripheral did have multiple slave ports the current USB testing code
peripheral did have multiple slave ports the current USB testing code
would not support this since it would not know which port to use.</P
would not support this since it would not know which port to use.</P
></BLOCKQUOTE
></BLOCKQUOTE
></DIV
></DIV
></DIV
></DIV
><DIV
><DIV
CLASS="NAVFOOTER"
CLASS="NAVFOOTER"
><HR
><HR
ALIGN="LEFT"
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
SUMMARY="Footer navigation table"
WIDTH="100%"
WIDTH="100%"
BORDER="0"
BORDER="0"
CELLPADDING="0"
CELLPADDING="0"
CELLSPACING="0"
CELLSPACING="0"
><TR
><TR
><TD
><TD
WIDTH="33%"
WIDTH="33%"
ALIGN="left"
ALIGN="left"
VALIGN="top"
VALIGN="top"
><A
><A
HREF="usbs-data.html"
HREF="usbs-data.html"
ACCESSKEY="P"
ACCESSKEY="P"
>Prev</A
>Prev</A
></TD
></TD
><TD
><TD
WIDTH="34%"
WIDTH="34%"
ALIGN="center"
ALIGN="center"
VALIGN="top"
VALIGN="top"
><A
><A
HREF="ecos-ref.html"
HREF="ecos-ref.html"
ACCESSKEY="H"
ACCESSKEY="H"
>Home</A
>Home</A
></TD
></TD
><TD
><TD
WIDTH="33%"
WIDTH="33%"
ALIGN="right"
ALIGN="right"
VALIGN="top"
VALIGN="top"
><A
><A
HREF="usbs-testing.html"
HREF="usbs-testing.html"
ACCESSKEY="N"
ACCESSKEY="N"
>Next</A
>Next</A
></TD
></TD
></TR
></TR
><TR
><TR
><TD
><TD
WIDTH="33%"
WIDTH="33%"
ALIGN="left"
ALIGN="left"
VALIGN="top"
VALIGN="top"
>Data Endpoints</TD
>Data Endpoints</TD
><TD
><TD
WIDTH="34%"
WIDTH="34%"
ALIGN="center"
ALIGN="center"
VALIGN="top"
VALIGN="top"
><A
><A
HREF="io-usb-slave.html"
HREF="io-usb-slave.html"
ACCESSKEY="U"
ACCESSKEY="U"
>Up</A
>Up</A
></TD
></TD
><TD
><TD
WIDTH="33%"
WIDTH="33%"
ALIGN="right"
ALIGN="right"
VALIGN="top"
VALIGN="top"
>Testing</TD
>Testing</TD
></TR
></TR
></TABLE
></TABLE
></DIV
></DIV
></BODY
></BODY
></HTML
></HTML
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.