MityDSP Documentation Index
tcDspHsUsb

Introduction

The tcDspHsUsb class is used to provide access to a high speed USB device, capable of transfer speeds up to 400 Mbps. When each instance of the interface is created, a set of transmit and receive buffers are created. Each buffer is 1/2 the size of the matching firmware buffer. The application may tune the number of buffers in each pool via the tcDspHsUsb constructor.

Once the interface is enabled, the main interaction is via "put" and "get" methods, similar to tcDspSerial. However, the application may also register semaphores that are incremented by tcDspHsUsb whenever the TX FIFO runs empty or the RX FIFO has data available.

Internally, data is retrieved by an ISR that triggers a DMA transfer into the RX buffers. The transfer may occur when the firmware FIFO reaches at least 1/2 full, or when an application programmable time ha elapsed without reaching the required level. A thread monitor the DMA transfers, updates the buffer list, and re-enable RX interrupts as required.

On the TX side, data is assembled into buffers each 1/2 the size of the transmit FIFO. Whenever the firmware TX FIFO becomes less than 1/4 full, a new buffer is sent to the firmware (via DMA) for transmission. A partial transmit buffer is held (to accumulate more data) until it becomes full, or until all other transmit buffers have been consumed. This provides a Nagle-like algorithm to limit the impact of small messages on the overall link throughput. Again, a high priority thread is used to monitor TX DMA completion, update internal data structures, and re-enable interrupts.

These DMA monitoring threads are started by the constructor at a very high priority (14), although this may also be adjusted by passing a different value into the constructor. The threads should have a very low overhead, although they are susceptible to priority inversion due to the need to perform a mutex lock while manipulating buffer pointers.

The USB device itself implements flow control to prevent loss of data if the MityDSP application is not reading as fast as the host is sending or vice versa.

See also:
MityDSP::tcDspHsUsb Class Reference

Example

This is a simple example of tcDspHsUsb creation and usage:

{
int bytes, cnt, rv;
unsigned int myBaseAddr = 0xA0000180;
char input[1024], output[1024];
tcDspHsUsb *myUsb;
SEM_Handle myRxAvail, myTxEmpty;
// create a high-speed USB interface
myUsb = new tcDspHsUsb((void *)myBaseAddr);
// register semaphores
myUsb->registerSemaphores(myRxAvail, myTxEmpty);
// set receive timeout to 50 msec
myUsb->setTimeout(50);
// start using the port
myUsb->enable(true);
...
while (condition)
{
// wait for previous transmission to complete
SEM_pend(myTxEmpty, SYS_FOREVER);
// send something...
bytes = sizeof(output);
for (int i=0; i<bytes; i++) output[i] = i % 256;
rv = cnt = 0;
do
{
rv += myUsb->put((void *)&output[rv], bytes-rv);
} while ((rv < bytes) && (++cnt < 25));
printf("Sent %1d of %1d bytes\r\n", rv, bytes);
}
...
while (another_condition)
{
// wait for data to become available
SEM_pend(myRxAvail, SYS_FOREVER);
// receive something...
bytes = sizeof(input);
do
{
rv = myUsb->get((void *)input, bytes);
printf("Received %1d bytes of data\r\n", rv);
...
} while (rv > 0);
}
}

  
Generated on Mon Apr 22 2013 11:33:02 for MityDSP Core by  Doxygen Version 1.8.1.1
Copyright © 2009, Critical Link LLC, All rights reserved.