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 dataA``select`` statement is used, along with a
select handler
to wait for, and capture, send/receive notifications from theXUD_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;
}
}
}