Texas Instruments TMS320DM357 User Manual

Page 21

Advertising
background image

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

Advertising