Texas Instruments TMS320DM357 User Manual
Page 21
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