USB Controller
Because the uDMA interrupt occurs on the same interrupt vector as any other USB interrupt, the
application must perform an extra check to determine what was the actual source of the interrupt.
It is important to note that this DMA interrupt does not mean that the USB transfer is complete,
but that the data has been transferred to the USB controller’s FIFO. There will also be an interrupt
indicating that the USB transfer is complete. However, both events need to be handled in the same
interrupt routine. This because if other code in the system holds off the USB interrupt routine, both
the uDMA complete and transfer complete can occur before the USB interrupt handler is called.
The USB has no status bit indicating that the interrupt was due to a DMA complete, which means
that the application must remember if a uDMA transaction was in progress. The example below
shows the g_ui32Flags global variable being used to remember that a uDMA transfer was pending.
Example: Interrupt handling with uDMA.
if((g_ui32Flags & EP1_DMA_IN_PEND) &&
(ROM_uDMAChannelModeGet(UDMA_CHANNEL_USBEP1TX) == UDMA_MODE_STOP))
{
//
// Handle the uDMA complete case.
//
...
}
//
// Get the interrupt status.
//
ui32Status = ROM_USBIntStatusEndpoint(USB0_BASE);
if(ui32Status & USB_INT_DEV_IN_EP1)
{
//
// Handler the transfer complete case.
//
...
}
To use the USB device controller with an OUT endpoint, the application must use a receive uDMA
channel. When calling ROM_USBDevEndpointConfigSet() for an endpoint that uses uDMA, the
application must set extra flags in the ui32Flags parameter. The USB_EP_DMA_MODE_0 and
USB_EP_DMA_MODE_1 control the mode of the transaction, USB_EP_AUTO_CLEAR allows the
data to be received automatically without needing to manually acknowledge that the data has been
read. USB_EP_DMA_MODE_0 will not generate an interrupt when each packet is sent over USB
and will only interrupt when the uDMA transfer is complete. USB_EP_DMA_MODE_1 will interrupt
when the uDMA transfer complete or a short packet is received. This is useful for BULK endpoints
that may not have prior knowledge of how much data is being received. USB_EP_AUTO_CLEAR
should normally be specified when using uDMA to prevent the need for application code to ac-
knowledge that the data has been read from the FIFO. The example below configures endpoint 1
as a Device mode Bulk OUT endpoint using DMA mode 1 with a max packet size of 64 bytes.
Example: Configure endpoint 1 receive channel:
//
// Endpoint 1 is a device mode BULK OUT endpoint using uDMA.
//
ROM_USBDevEndpointConfigSet(USB0_BASE, USB_EP_1, 64,
(USB_EP_DEV_OUT | USB_EP_MODE_BULK |
USB_EP_DMA_MODE_1 | USB_EP_AUTO_CLEAR));
Next the configuration of the actual uDMA controller is needed. Like the transmit case, the first a call
to ROM_uDMAChannelAttributeDisable() is made to clear any previous settings. This is followed
300 April 8, 2013