Basic Usage
This section outlines the basic usage of XUD. Basic use is termed to mean each endpoint runs in its own dedicated core. Multiple endpoints in a single core are possible, please see Advanced Usage.
XUD Core: XUD_Manager()
This is the main XUD task that interfaces with the USB transceiver. It performs power-signalling/handshaking on the USB bus, and passes packets to/from the various endpoints.
This function should be called directly from the top-level par statement in main() to ensure that the XUD library is ready within the 100ms allowed by the USB specification.
-
int XUD_Manager(chanend c_epOut[], int noEpOut, chanend c_epIn[], int noEpIn, chanend ?c_sof, XUD_EpType epTypeTableOut[], XUD_EpType epTypeTableIn[], out port ?p_usb_rst, clock ?clk, unsigned rstMask, XUD_BusSpeed_t desiredSpeed, XUD_PwrConfig pwrConfig)
This performs the low-level USB I/O operations.
Note that this needs to run in a thread with at least 80 MIPS worst case execution speed.
Parameters
c_epOut
An array of channel ends, one channel end per output endpoint (USB OUT transaction); this includes a channel to obtain requests on Endpoint 0.
noEpOut
The number of output endpoints, should be at least 1 (for Endpoint 0).
c_epIn
An array of channel ends, one channel end per input endpoint (USB IN transaction); this includes a channel to respond to requests on Endpoint 0.
noEpIn
The number of input endpoints, should be at least 1 (for Endpoint 0).
c_sof
A channel to receive SOF tokens on. This channel must be connected to a process that can receive a token once every 125 ms. If tokens are not read, the USB layer will lock up. If no SOF tokens are required null should be used for this parameter.
epTypeTableOut
See epTypeTableIn.
epTypeTableIn
This and epTypeTableOut are two arrays indicating the type of the endpoint. Legal types include: XUD_EPTYPE_CTL (Endpoint 0), XUD_EPTYPE_BUL (Bulk endpoint), XUD_EPTYPE_ISO (Isochronous endpoint), XUD_EPTYPE_INT (Interrupt endpoint), XUD_EPTYPE_DIS (Endpoint not used). The first array contains the endpoint types for each of the OUT endpoints, the second array contains the endpoint types for each of the IN endpoints.
p_usb_rst
The port to used to connect to an external phy reset line. Should be null for U-Series.
clk
The clock block to use for the p_usb_rst port - this should not be clock block 0. Should be null for U-Series.
rstMask
The mask to use when taking an external phy into/out of reset. The mask is ORed into the port to disable reset, and unset when deasserting reset. Use ‘-1’ as a default mask if this port is not shared.
desiredSpeed
This parameter specifies what speed the device will attempt to run at i.e. full-speed (ie 12Mbps) or high-speed (480Mbps) if supported by the host. Pass XUD_SPEED_HS if high-speed is desired or XUD_SPEED_FS if not. Low speed USB is not supported by XUD.
pwrConfig
Specifies whether the device is bus or self-powered. When self-powered the XUD will monitor the VBUS line for host disconnections. This is required for compliance reasons. Valid values are XUD_PWR_SELF and XUD_PWR_BUS.
Endpoint Type Table
The endpoint type table should take an array of XUD_EpType to inform XUD about endpoints being used. This is mainly used to indicate the transfer-type of each endpoint (bulk, control, isochronous or interrupt) as well as whether the endpoint wishes to be informed about bus-resets (see Status Reporting).
Note: endpoints can also be marked as disabled.
Endpoints that are not used will NAK any traffic from the host.
PwrConfig
The PwrConfig parameter to XUD_Manager() indicates if the device is bus or self-powered.
Valid values for this parameter are XUD_PWR_SELF and XUD_PWR_BUS.
When XUD_PWR_SELF is used, XUD_Manager() monitors the VBUS input for a valid voltage and reponds appropriately. The USB Specification states that the devices pull-ups must be disabled when a valid VBUS is not present. This is important when submitting a device for compliance testing since this is explicitly tested.
If the device is bus-powered XUD_PWR_SELF can be used since is assumed that the device is not powered up when VBUS is not present and therefore no voltage monitoring is required. In this configuration the VBUS input to the device/PHY need not be present.
XUD_PWR_BUS can be used in order to run on a self-powered board without provision for VBUS wiring to the PHY/device, but this is not advised.
Endpoint Communication with XUD_Manager()
Communication state between a core and the XUD library is encapsulated in an opaque type:
-
XUD_ep
Typedef for endpoint identifiers.
All client calls communicating with the XUD library pass in this type. These data structures can be created at the start of execution of a client core with the following call that takes as an argument the endpoint channel connected to the XUD library:
-
XUD_ep XUD_InitEp(chanend c_ep)
Initialises an XUD_ep.
Parameters
c_ep
Endpoint channel to be connected to the XUD library.
Returns
Endpoint identifier
Endpoint data is sent/received using three main functions, XUD_SetData(), XUD_GetData() and XUD_GetSetupData().
These assembly functions implement the low-level shared memory/channel communication with the XUD_Manager() core. For developer convenience these calls are wrapped up by XC functions.
These functions will automatically deal with any low-level complications required such as Packet ID toggling etc.
XUD_GetBuffer()
-
XUD_Result_t XUD_GetBuffer(XUD_ep ep_out, unsigned char buffer[], unsigned &length)
This function must be called by a thread that deals with an OUT endpoint.
When the host sends data, the low-level driver will fill the buffer. It pauses until data is available.
Parameters
ep_out
The OUT endpoint identifier (created by XUD_InitEP).
buffer
The buffer in which to store data received from the host. The buffer is assumed to be word aligned.
length
The number of bytes written to the buffer
Returns
XUD_RES_OKAY on success, for errors see Status Reporting.
XUD_SetBuffer()
-
XUD_Result_t XUD_SetBuffer(XUD_ep ep_in, unsigned char buffer[], unsigned datalength)
This function must be called by a thread that deals with an IN endpoint.
When the host asks for data, the low-level driver will transmit the buffer to the host.
Parameters
ep_in
The endpoint identifier (created by XUD_InitEp).
buffer
The buffer of data to transmit to the host.
datalength
The number of bytes in the buffer.
Returns
XUD_RES_OKAY on success, for errors see Status Reporting.
XUD_SetBuffer_EpMax()
This function provides a similar function to XUD_SetBuffer function but it breaks the data up in packets of a fixed maximum size. This is especially useful for control transfers where large descriptors must be sent in typically 64 byte transactions.
-
XUD_Result_t XUD_SetBuffer_EpMax(XUD_ep ep_in, unsigned char buffer[], unsigned datalength, unsigned epMax)
Similar to XUD_SetBuffer but breaks up data transfers into smaller packets.
This function must be called by a thread that deals with an IN endpoint. When the host asks for data, the low-level driver will transmit the buffer to the host.
Parameters
ep_in
The IN endpoint identifier (created by XUD_InitEp).
buffer
The buffer of data to transmit to the host.
datalength
The number of bytes in the buffer.
epMax
The maximum packet size in bytes.
Returns
XUD_RES_OKAY on success, for errors see Status Reporting.
XUD_DoGetRequest()
-
XUD_Result_t XUD_DoGetRequest(XUD_ep ep_out, XUD_ep ep_in, unsigned char buffer[], unsigned length, unsigned requested)
Performs a combined XUD_SetBuffer and XUD_GetBuffer.
It transmits the buffer of the given length over the ep_in endpoint to answer an IN request, and then waits for a 0 length Status OUT transaction on ep_out. This function is normally called to handle Get control requests to Endpoint 0.
Parameters
ep_out
The endpoint identifier that handles Endpoint 0 OUT data in the XUD manager.
ep_in
The endpoint identifier that handles Endpoint 0 IN data in the XUD manager.
buffer
The data to send in response to the IN transaction. Note that this data is chopped up in fragments of at most 64 bytes.
length
Length of data to be sent.
requested
The length that the host requested, (Typically pass the value wLength).
Returns
XUD_RES_OKAY on success, for errors see Status Reporting
XUD_DoSetRequestStatus()
-
XUD_Result_t XUD_DoSetRequestStatus(XUD_ep ep_in)
This function sends an empty packet back on the next IN request with PID1.
It is normally used by Endpoint 0 to acknowledge success of a control transfer.
Parameters
ep_in
The Endpoint 0 IN identifier to the XUD manager.
Returns
XUD_RES_OKAY on success, for errors see Status Reporting.
XUD_SetDevAddr()
-
XUD_Result_t XUD_SetDevAddr(unsigned addr)
Sets the device’s address.
This function must be called by Endpoint 0 once a setDeviceAddress request is made by the host.
Must be run on USB core
Parameters
addr
New device address.
XUD_SetStall()
-
void XUD_SetStall(XUD_ep ep)
Mark an endpoint as STALLed.
It is cleared automatically if a SETUP received on the endpoint.
Must be run on same tile as XUD core
Parameters
ep
XUD_ep type.
XUD_SetStallByAddr()
-
void XUD_SetStallByAddr(int epNum)
Mark an endpoint as STALL based on its EP address.
Cleared automatically if a SETUP received on the endpoint. Note: the IN bit of the endpoint address is used.
Must be run on same tile as XUD core
Parameters
epNum
Endpoint number.
XUD_ClearStall()
-
void XUD_ClearStall(XUD_ep ep)
Mark an endpoint as NOT STALLed.
Must be run on same tile as XUD core
Parameters
ep
XUD_ep type.
XUD_ClearStallByAddr()
-
void XUD_ClearStallByAddr(int epNum)
Mark an endpoint as NOT STALLed based on its EP address.
Note: the IN bit of the endpoint address is used.
Must be run on same tile as XUD core
Parameters
epNum
Endpoint number.
Status Reporting
Status reporting on an endpoint can be enabled so that bus state is known. This is achieved by ORing XUD_STATUS_ENABLE into the relevant endpoint in the endpoint type table.
This means that endpoints are notified of USB bus resets (and bus-speed changes). The XUD access functions discussed previously (XUD_GetData, XUD_SetData, etc.) return XUD_RES_RST if a USB bus reset is detected.
This reset notification is important if an endpoint core is expecting alternating INs and OUTs. For example, consider the case where an endpoint is always expecting the sequence OUT, IN, OUT (such as a control transfer). If an unplug/reset event was received after the first OUT, the host would return to sending the initial OUT after a replug, while the endpoint would hang on the IN. The endpoint needs to know of the bus reset in order to reset its state machine.
Endpoint 0 therefore requires this functionality since it deals with bi-directional control transfers.
This is also important for high-speed devices, since it is not guaranteed that the host will detect the device as a high-speed device. The device therefore needs to know what bus-speed it is currently running at.
After a reset notification has been received, the endpoint must call the XUD_ResetEndpoint() function. This will return the current bus speed.
XUD_ResetEndpoint()
-
XUD_BusSpeed_t XUD_ResetEndpoint(XUD_ep one, XUD_ep &?two)
This function will complete a reset on an endpoint.
Can take one or two XUD_ep as parameters (the second parameter can be set to null). The return value should be inspected to find the new bus-speed. In Endpoint 0 typically two endpoints are reset (IN and OUT). In other endpoints null can be passed as the second parameter.
Parameters
one
IN or OUT endpoint identifier to perform the reset on.
two
Optional second IN or OUT endpoint structure to perform a reset on.
Returns
Either XUD_SPEED_HS - the host has accepted that this device can execute at high speed, or XUD_SPEED_FS - the device is runnig at full speed.
SOF Channel
An application can pass a channel-end to the c_sof parameter of XUD_Manager(). This will cause a word of data to be output every time the device receives a SOF from the host. This can be used for timing information for audio devices etc. If this functionality is not required null should be passed as the parameter. Please note, if a channel-end is passed into XUD_Manager() there must be a responsive task ready to receive SOF notifications otherwise the XUD_Manager() task will be blocked attempting to send these messages.
USB Test Modes
XUD supports the required test modes for USB Compliance testing.
XUD accepts commands from the endpoint 0 channels (in or out) to signal which test mode to enter via the XUD_SetTestMode() function. The commands are based on the definitions of the Test Mode Selector Codes in the USB 2.0 Specification Table 11-24. The supported test modes are summarised in the table below.
Value |
Test Mode Description |
---|---|
1 |
Test_J |
2 |
Test_K |
3 |
Test_SE0_NAK |
4 |
Test_Packet |
The passing other codes endpoints other than 0 to XUD_SetTestMode() could result in undefined behaviour.
As per the USB 2.0 Specification a power cycle or reboot is required to exit the test mode.
XUD_SetTestMode()
-
void XUD_SetTestMode(XUD_ep ep, unsigned testMode)
Enable a specific USB test mode in XUD.
Must be run on same tile as XUD core
Parameters
ep
XUD_ep type (must be endpoint 0 in or out)
testMode
The desired test-mode