Hello,
I am developing an audio application where I am using DMA to receive and transmit STEREO audio data. I have based my configuration in one of your examples for audio and aic23b. I am able to process and receive data correctly in that way, but I decided to change the interrupt transfer size for receiving, so I don´t need to wait for the whole reception in order to start procesing data. The resulting configuration of the DMA in that way is the following:
void dma_init(){
EALLOW;
DmaRegs.DMACTRL.bit.HARDRESET = 1;
asm(" NOP");
DmaRegs.PRIORITYCTRL1.bit.CH1PRIORITY = 0;
// DMA Channel 1 - McBSP-A Receive
DmaRegs.CH1.BURST_SIZE.all = 1; // 2 16-bit words/burst (1 32-bit word per RRDY) - memory address bumped up by 1 internally
DmaRegs.CH1.SRC_BURST_STEP = 1; // DRR2 must be read first & then DRR1. Increment by 1. Hence a value of +1. (This is a 2's C #)
DmaRegs.CH1.DST_BURST_STEP = -1; // Copy DRR2 data to address N+1 and DRR1 data to N. Hence -1 (32-bit read= read addr N+1 as MSB, then N as LSB)
DmaRegs.CH1.TRANSFER_SIZE = (BUFFER_SIZE>>1)-1; // HERE IS THE CHANGE!!! Interrupt every (n+1) bursts. McBSP handles 16-bit data only (DRR2 and DRR1 are 16-bit registers)
DmaRegs.CH1.SRC_TRANSFER_STEP = -1; // Decrement source address by 1 (from DRR1 back to DRR2) after processing a burst of data
DmaRegs.CH1.DST_TRANSFER_STEP = (BUFFER_SIZE+1); // After copying L-C data, move down (up más bien) to R-C data in a given buffer
DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all; // First read from DRR2
DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;
DmaRegs.CH1.DST_ADDR_SHADOW = ping_buff_offset; // First write to ping_buffer[1]
DmaRegs.CH1.DST_BEG_ADDR_SHADOW = ping_buff_offset;
DmaRegs.CH1.DST_WRAP_SIZE = 1; // After LEFT(1) and then RIGHT(2), go back to LEFT buffer
DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF; // Arbitary large value. We'll never hit this.....
DmaRegs.CH1.DST_WRAP_STEP = 2; // From starting address, move down (up más bien) 2 16-bit addresses to write nxt 32-bit word
DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clears peripheral interrupt, sync and sycn error flags
DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1;
DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;
DmaRegs.CH1.MODE.bit.CHINTE = 1; // Channel Interrupt Enable
DmaRegs.CH1.MODE.bit.CHINTMODE = 0; // Generates Interrupt at beginning of transfer
DmaRegs.CH1.MODE.bit.PERINTE = 1; // Peripheral Interrupt Enable
DmaRegs.CH1.MODE.bit.PERINTSEL = 15; // McBSP MREVTA
DmaRegs.CH1.MODE.bit.CONTINUOUS = 1; // Continuous mode
// DMA Channel 2 - McBSP-A Transmit
DmaRegs.CH2.BURST_SIZE.all = 1; // 2 16-bit words/burst (1 32-bit word per XRDY) - value bumped up by 1 internally
DmaRegs.CH2.SRC_BURST_STEP = -1; // Copy data at address N+1 to DXR2 first then data at N to DXR1. Hence -1
DmaRegs.CH2.DST_BURST_STEP = 1; // DXR2 must be written to first & then DXR1. Increment by 1. Hence a value of +1. (This is a 2's C #)
DmaRegs.CH2.TRANSFER_SIZE = (BUFFER_SIZE-1); // Interrupt every 1024 (n+1) 16-bit words. McBSP still handles 16-bit data only in registers
DmaRegs.CH2.SRC_TRANSFER_STEP = (BUFFER_SIZE+1); // After copying L-C data, move down to R-C data in a given buffer
DmaRegs.CH2.DST_TRANSFER_STEP = -1; // Decrement dest. address by 1 (DXR1 back to DXR2) after processing a burst of data
DmaRegs.CH2.SRC_ADDR_SHADOW = ping_buff_offset; // First read from ping_buffer[1]
DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = ping_buff_offset;
DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all; // First write to DXR2
DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all;
DmaRegs.CH2.SRC_WRAP_SIZE = 1; // After LEFT(1) and then RIGHT(2), go back to LEFT buffer
DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF; // Arbitary large value. We'll never hit this.....
DmaRegs.CH2.SRC_WRAP_STEP = 2; // From starting address, move down 2 16-bit addresses to read next 32-bit word
DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1; // Clears peripheral interrupt, sync and sync error flags
DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1;
DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;
DmaRegs.CH2.MODE.bit.CHINTE = 1; // Channel Interrupt Enable
DmaRegs.CH2.MODE.bit.CHINTMODE = 0; // Generates Interrupt at beginning of transfer
DmaRegs.CH2.MODE.bit.PERINTE = 1; // Peripheral Interrupt Enable
DmaRegs.CH2.MODE.bit.PERINTSEL = 14; // McBSP MXEVTA
DmaRegs.CH2.MODE.bit.CONTINUOUS = 1; // Continuous mode
EDIS;
EALLOW;
DmaRegs.CH1.CONTROL.bit.RUN = 1; // Starts up Channel 1
EDIS;
}
However, I am having a problem when receiving the second half of the buffer. So, is that configuration correct? Is it possible to have 2 interrupts for reception while having 1 for transmission? I hope it is.
Thanks in advance
Ignacio