I am using a descriptor based DMA to transmit 16 bit data via SPORT1 on the ADSP-2191. The issue that I am seeing
is that when the DMA complete interrupt goes off, the DMA FS(DMA Buffer Status) bits 12 and 13 of the SP1DT_CFG
register is showing anywhere from 1, 2 or 3 words remaining in the DMA buffer. These data words remaining in the DMA
buffer will be transmitted on the next descriptor based DMA TX transaction, which is causing a delay of the transmitted data.
If I transmit 1 or 2 words for a given descriptor configuration then the DMA appears to transfer this data to SPORT1 just fine.
If >= 3 words are transmitted per a descriptor configuration then the DMA status is showing 1, 2, or 3 words remaining in the DMA
buffer. The maximum number of data words that I transmit per DMA descriptor transaction is 8.
The DMA (Head + 4) Next Chain Pointer is assigned to an address location that conatins zero in order to halt the
DMA after each descriptor based transfer is complete. There is an anomaly related to DMA halting for silicon revision
0.2, but not for silicon revision 1.0 of the ADSP-2191. Does anyone know what is going on here?
Below is psuedo code for how the DMA is being initialized and configured for each descriptor based
DMA SPORT1 transmission. Note that SPORT1 has already been configured for 16 bit word transfers, and
enabled prior to configuring and enabling the DMA. SPORT1 is enabled, but the SPORT1 TX interrupt is
masked or disabled. The SPORT1 TX interrupt is umasked after the DMA is enabled.
sysreg_IOPG = SPORT1_Controller_Page; /* SPORT1 configuration page */
SP1DT_CFG = 0x0000; /* Set DMA transmit direction and clear DMA Configuration register */
DMADescriptor = 0x8005; /* Head, Descriptor Owner = DMA, Interrupt on completion, Enable DMA */
DMADescriptor = 0x0000; /* Head + 1, DMA Start Page, SP1DT_SRP, internal memory page */
DMADescriptor = TxDataBuffer; /* Head + 2, DMA Start Address of the data, SP1DT_SRA */
DMADescriptor = Nwords; /* Head + 3, DMA Word Count, SP1DT_CNT */
DMADescriptor = &DMADescriptor; /* Head + 4, Next Chain Pointer, points to location containing 0 to halt DMA */
SP1DT_CP = DMADescriptor; /* DMA Next Descriptor Pointer register */
SP1DT_CPR = 0x0001; /* Set the DMA descriptor ready */
SP1DT_CFG = 0x0001; /* Enable the DMA */
interrupt(SIG_INT11, SPORT1Tx_ISR); /* Unmask SPORT1 Tx interrupt */