Universal Serial Bus Controller User's Guide

www.ti.com
Introduction
Example 4. Programming the USB DMA Controller (continued)
usbRegs->CHANNEL[i].RCPPIDMASTATEW6 = 0;
tx_desc[i] = 0;
rx_desc[i] = 0;
}
// Routine to flush TX fifo.
// Must call this routine twice for double-buffered FIFO
void flush_tx_fifo(int ep) {
int index_save;
int status;
index_save = usbRegs->INDEX; // Save the index to restore later
usbRegs->INDEX = ep; // Set the index to the desired endpoint
status = usbRegs->PERI_TXCSR & 3; // Isolate the TxPktRdy and FIFONotEmpty bits
if (!(status)) { // Nothing showing in FIFO
usbRegs->PERI_TXCSR |= 1; // Set TxPktRdy in case there is a partial
packet already in FIFO
}
usbRegs->PERI_TXCSR = ((usbRegs->PERI_TXCSR & 0xFFFC) | 8); // Write TXCSR with flush
bit set, FIFONotEmpty=0, and TxPktRdy=0.
while (usbRegs->PERI_TXCSR & 8); // Keep looping until the flush bit clears
usbRegs->INDEX = index_save; // Restore the index to previous value
}
// Routine to start the TX DMA for a given channel
void start_tx_dma(int ch) {
// Must have at least one descriptor before turning on TX DMA
if (rx_desc[ch] < 1) {error++;} else {
//Flush FIFO (2 times in case it is double-buffered)
flush_tx_fifo(ch+1);
flush_tx_fifo(ch+1);
// Start the DMA
usbRegs->TCPPICR = 1; //Enable Tx CPPI DMA
usbRegs->CHANNEL[ch].TCPPIDMASTATEW0 = (Uint32)( & tx_bufferDesc[ch][0]);
CSL_FINS(usbRegs->PERI_TXCSR,USB_PERI_TXCSR_DMAEN,1); // TXCSR, bit DMAReqEnab
}
}
// Routine to add a TX descriptor
void add_tx_descriptor(int ch, unsigned char * inBuf, int bytes) {
if ((bytes < 0) || (bytes >65535)) {bytes = 64; error++;}
// Link previous buffer to this one if this is not the first descriptor of the channel
if (tx_desc[ch] > 0) tx_bufferDesc[ch][4*(tx_desc[ch]-1)] =
(Uint32)( & tx_bufferDesc[ch][4*tx_desc[ch]]);
// Set up DMA buffer descriptors
tx_bufferDesc[ch][4*tx_desc[ch]+0] = (Uint32)(0x00000000); // Next Descriptor pointer
tx_bufferDesc[ch][4*tx_desc[ch]+1] = (Uint32)inBuf; // Buffer pointer
tx_bufferDesc[ch][4*tx_desc[ch]+2] = (0x0000 < < 16) | bytes; // [31:16] Buffer offset
[15:0] Buffer length
if (bytes == 0) bytes = ZERO_BYTE | 1; // Set the ZERO_BYTE bit and size 1 byte
tx_bufferDesc[ch][4*tx_desc[ch]+3] = SOP | EOP | OWNER | bytes; // [31]=SOP, [30]=EOP,
[29]=owner, [28]=EOQ, [23]=zero-byte, [19] = rxabort, [15:0]=packet length
// If DMA already enabled and has stopped, write this to the TX Queue head pointer
if ((usbRegs->TCPPICR == 1) & & (usbRegs->CHANNEL[ch].TCPPIDMASTATEW0 == 0))
usbRegs->CHANNEL[ch].TCPPIDMASTATEW0 = (Uint32)( & tx_bufferDesc[ch][4*tx_desc[ch]+0]);
SPRUGH3 November 2008 Universal Serial Bus (USB) Controller 21
Submit Documentation Feedback