Advanced usage#

Advanced usage is termed to mean the implementation of multiple endpoints in a single task as well as the addition of real-time processing to an endpoint task.

The functions documented in Basic usage such as XUD_SetBuffer() and XUD_GetBuffer() are synchronous in nature - they block until data has either been successfully sent or received to or from the host. For this reason it is not generally possible to handle multiple endpoints in a single thread efficiently (or at all, depending on the protocols involved).

To solve this lib_xud provides an API that is asynchronous in nature with functions that allow the separation of requesting to send/receive a packet and the notification of a successful transfer. This API utilises xcore events by using the XC select statement language feature.

General operation is as follows:

  • A XUD_SetReady_ function is called to mark an endpoint as ready to send or receive data

  • A``select`` statement is used, along with a select handler to wait for, and capture, send/receive notifications from the XUD_Main task

Function details#

The available XUD_SetReady_ functions for the asynchronous API are listed below.

XUD_SetReady_Out()#

int XUD_SetReady_Out(XUD_ep ep, unsigned char buffer[])#

Marks an OUT endpoint as ready to receive data.

Parameters:
  • ep – 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.

Returns:

XUD_RES_OKAY on success, for errors see Status Reporting.

XUD_SetReady_In()#

static inline XUD_Result_t XUD_SetReady_In(XUD_ep ep, unsigned char buffer[], int len)#

Marks an IN endpoint as ready to transmit data.

Parameters:
  • ep – The IN endpoint identifier (created by XUD_InitEp).

  • buffer – The buffer to transmit to the host. The buffer is assumed be word aligned.

  • len – The length of the data to transmit.

Returns:

XUD_RES_OKAY on success, for errors see Status Reporting.

The following functions are also provided to ease integration with more complex buffering schemes than a single packet buffer. A example might be a circular-buffer for an audio stream.

XUD_SetReady_OutPtr()#

static inline XUD_Result_t XUD_SetReady_OutPtr(XUD_ep ep, unsigned addr)#

Marks an OUT endpoint as ready to receive data.

Parameters:
  • ep – The OUT endpoint identifier (created by XUD_InitEp).

  • addr – The address of the buffer in which to store data received from the host. The buffer is assumed to be word aligned.

Returns:

XUD_RES_OKAY on success, for errors see Status Reporting.

XUD_SetReady_InPtr()#

static inline XUD_Result_t XUD_SetReady_InPtr(XUD_ep ep, unsigned addr, int len)#

Marks an IN endpoint as ready to transmit data.

Parameters:
  • ep – The IN endpoint identifier (created by XUD_InitEp).

  • addr – The address of the buffer to transmit to the host. The buffer is assumed be word aligned.

  • len – The length of the data to transmit.

Returns:

XUD_RES_OKAY on success, for errors see Status Reporting.

Once an endpoint has been marked ready to send/receive by calling one of the above XUD_SetReady_ functions, an XC select statement can be used to handle notifications of a packet being sent/received from XUD_Main(). These notifications are communicated via channels.

For convenience, select handler functions are provided to handle events in the select statement. These are documented below.

XUD_GetData_Select()#

void XUD_GetData_Select(chanend c, XUD_ep ep, REFERENCE_PARAM(unsigned, length), REFERENCE_PARAM(XUD_Result_t, result))#

Select handler function for receiving OUT endpoint data in a select.

Parameters:
  • c – The chanend related to the endpoint

  • ep – The OUT endpoint identifier (created by XUD_InitEp).

  • length – Passed by reference. The number of bytes written to the buffer (that was passed into XUD_SetReady_Out())

  • result – XUD_Result_t passed by reference. XUD_RES_OKAY on success, for errors see Status Reporting.

XUD_SetData_Select()#

void XUD_SetData_Select(chanend c, XUD_ep ep, REFERENCE_PARAM(XUD_Result_t, result))#

Select handler function for transmitting IN endpoint data in a select.

Parameters:
  • c – The chanend related to the endpoint

  • ep – The IN endpoint identifier (created by XUD_InitEp).

  • result – Passed by reference. XUD_RES_OKAY on success, for errors see Status Reporting.

Warning

It is currently not possible to share control endpoint (i.e. endpoint 0) functionalty with other endpoints/tasks. This is because a control endpoint must remain responsive to the host.

Example#

A simple example of the functionality described in this section is shown below:


void ExampleEndpoint(chanend c_ep_out, chanend c_ep_in)
{
    unsigned char rxBuffer[1024];
    unsigned char txBuffer[] = {0, 1, 2, 3, 4};
    int length, returnVal;


    XUD_ep ep_out = XUD_InitEp(c_ep_out);
    XUD_ep ep_in = XUD_InitEp(c_ep_in);

    /* Mark OUT endpoint as ready to receive */
    XUD_SetReady_Out(ep_out, rxBuffer);
    XUD_SetReady_In(ep_in, txBuffer, 5);

    while(1)
    {
        select
        {
            case XUD_GetData_Select(c_ep_out, ep_out, length):

                /* Packet from host received */

                for(int i = 0; i< length; i++)
                {
                    /* Process packet... */
                }

                /* Mark EP as ready again */
                XUD_SetReady_Out(ep_out, rxBuffer);
                break;

            case XUD_SetData_Select(c_ep_in, ep_in, returnVal):

                /* Packet successfully sent to host */

                /* Create new buffer */
                for(int i = 0; i < 5; i++)
                {
                    txBuffer[i]++;
                }

                /* Mark EP as ready again */
                XUD_SetReady_In(ep_in, txBuffer, 5);
                break;

        }
    }
}