Other Parts Discussed in Thread: C2000WARE
Hi,
I am interfacing a 16 bit SDRAM to the tms320f2837d and I am using DMA ch1 in order to write external ADC readings to it which is doing fine. After ADC sampling is stopped by the user I would like to read all the 16 bit values previously written using DMA ch2 and then transfer them using UART. However only the last 16 bit value written is being read repeatedly by DMA ch2. I am sure that there are no hardware issues as I have run the example program "emif1_32bit_sdram" and no errors were returned thus i know that reading/writing to memory is not a problem. It seems that the address from which DMA ch2 is reading is not starting from the initial memory location of the memory and then incrementing after each memory access. Is this supposed to do automatically or should I program something for it? I have looked at the code example provided on "emif1_16bit_sdram_dma" however this example only access the memory once unlike in my case which I want to do repeatedly as I will then want to transfer the data obtained using UART.
Here is some code snippets which I am implementing which I am using variable InitData as a dummy variable instead of ADC data for now...
Thanks for your help
Johann
--------------------------------------------------------
interrupt void xint1_isr(void) // interrupt that occurs when ADC has data ready
{
int a;
DMA_DstDataClear();
for(a=0;a<MEM_BUFFER_SIZE;a++)
{
g_ulSrcBuf0[a] = InitData;
}
InitData = InitData + 1;
//WRITE TO EXT MEM (16-bit)
//
EALLOW;
DmaRegs.CH1.CONTROL.bit.RUN = 1;
DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1;
while (DmaRegs.CH1.CONTROL.bit.TRANSFERSTS != 1){};
while (DmaRegs.CH1.CONTROL.bit.TRANSFERSTS != 0){};
EDIS;
for(i=0;i<123;i++) { } // delay
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to get more from group 1
}
Global variables:
//
// Globals
//
#pragma DATA_SECTION(g_ulSrcBuf0, "ramgs0"); //0
#pragma DATA_SECTION(g_ulDstBuf1, "ramgs1"); //1
Uint32 g_ulSrcBuf0[MEM_BUFFER_SIZE];
Uint32 g_ulDstBuf1[MEM_BUFFER_SIZE];
//Buffer in far memory
__attribute__((far)) volatile Uint32 g_ulSDRAMBuf[MEM_BUFFER_SIZE];
volatile Uint32 InitData = 0;
volatile Uint32 *DMADest;
volatile Uint32 *DMASource;
#define SDRAM_CS0_START_ADDR 0x80000000
#define SDRAM_CS0_SIZE 0x300000
#define MEM_BUFFER_SIZE 5 // 5 words sixteen bits each
My DMA buffers are 5 words long and using 16 bits length:
//
// Initialize DMA
//
DMAInitialize();
//
// Configure DMA Channel 1 (16-bit datasize)
//
DMADest = g_ulSDRAMBuf;
DMASource = (volatile Uint32 *)g_ulSrcBuf0; //
DMACH1AddrConfig32bit(DMADest,DMASource);
//
//Will set up to use 16-bit datasize, pointers are based on 16-bit words
//
DMACH1BurstConfig(4,1,1);
DMACH1TransferConfig(0,1,1); // 0 1 1
DMACH1WrapConfig(0xFFFF,0,0xFFFF,0);
//
//
//Also using 16-bit mode
//
DMACH1ModeConfig(0x0,PERINT_ENABLE,ONESHOT_ENABLE,
CONT_DISABLE,SYNC_DISABLE,SYNC_SRC,
OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
//
// Configure DMA Channel 2 (16-bit datasize)
//
DMADest = (volatile Uint32 *)g_ulDstBuf1; // !!!!!!!!!!!!!!!!!!!
DMASource = g_ulSDRAMBuf;
DMACH2AddrConfig32bit(DMADest,DMASource);
//
// Will set up to use 16-bit datasize, pointers are based on 16-bit words
//
DMACH2BurstConfig(4,1,1); // 4 1 1
DMACH2TransferConfig(0,1,1); // 0 1 1
DMACH2WrapConfig(0xFFFF,0,0xFFFF,0);
//
//Since this is a static copy use one shot mode, so only one trigger is needed
//Also using 16-bit mode
//
DMACH2ModeConfig(0x0,PERINT_ENABLE,ONESHOT_ENABLE,CONT_DISABLE,
SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,
SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
StartDMACH1();
StartDMACH2();
//
// READ FROM EXT MEM (16-bit)
//
EALLOW;
DmaRegs.CH2.CONTROL.bit.RUN = 1;
DmaRegs.CH2.CONTROL.bit.PERINTFRC = 1; // interrupt
while (DmaRegs.CH2.CONTROL.bit.TRANSFERSTS != 1){};
while (DmaRegs.CH2.CONTROL.bit.TRANSFERSTS != 0){};
EDIS;