Hi,
I'm using the TMX320F28377D development tools with an external SDRAM. I can write/read the SDRAM -- but a problem comes out:
The all values I read are same, example:I wrote 0x00@0x8000_0000, 0x01@0x8000_0000... and 0xff@0x8000_00ff; but when I read them back, I got 0xff@8000_0000, 0xff@8000_0001... and 0xff@0x8000_00ff. In another words, whatever the last data I wrote in, I can only read the last data back.
To me, I think the problem is the that when I change the address, the address didn't change in real. --- so every data wrote to one address, and read back from the same address.
I think the physical connection between the CPU to SDRAM should be good("The connection between
EMIF and the SDRAM is straightforward"), so there must be a problem about configuration.
I used two way to do such loopback reading -- DMA, and directly write/read function. Both have the same result.
I'm using 32bit mode to read/write.
The SDRAM is AS4C2M32S-5TCN (200MHz).
Thanks for anyone who can take a time to read this problem.
Regards,
King
Following is the code about the directly reading/writing by CPU:
#include "F28x_Project.h" // Device Headerfile and Examples Include File #include "F2837xD_Emif.h" #include "F2837xD_struct.h" #include <stdio.h> void Emif_sdram_config(void); void Emif_sdram_gpio(void); void error(void); // variables #define RESULTS_BUFFER_SIZE 256 // Attention! The DMA not access every memory. // It can access the GS(global shared memory). #pragma DATA_SECTION(DMABuf1,"SecureRam0"); volatile Uint32 DMABuf1[RESULTS_BUFFER_SIZE]; //DMA buffer to write to EMIF #pragma DATA_SECTION(DMABuf2,"SecureRam0"); volatile Uint32 DMABuf2[RESULTS_BUFFER_SIZE]; //DMA buffer for read back /********************************************************************************/ main() { InitSysCtrl(); EALLOW; ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; EDIS; InitGpio(); InitPieCtrl(); IER = 0x0000;// Disable CPU interrupts and clear all CPU interrupt flags: IFR = 0x0000; InitPieVectTable(); // Map ISR functions Emif_sdram_gpio(); Emif_sdram_config(); Uint32 i; // Initialize results buffer for(i = 0; i < RESULTS_BUFFER_SIZE; i++) { DMABuf1[i] = 0xffff0000+i; // write to external RAM using DMA DMABuf2[i] = 0x0000ffff; // read from external RAM using DMA } // write DMABuf1 to EMIF for(i = 0; i < RESULTS_BUFFER_SIZE; i++) { __addr32_write_uint32((unsigned long) (0x80000000+i), (unsigned long)DMABuf1[i]); } // read EMIF to DMABuf2 for(i = 0; i < RESULTS_BUFFER_SIZE; i++) { DMABuf2[i] = (unsigned long) __addr32_read_uint32((unsigned long) (i+0x80000000)); } ESTOP0; // compare results. for(i = 0; i < RESULTS_BUFFER_SIZE; i++) { if (DMABuf2[i] != DMABuf1[i]) error(); } ESTOP0; while(1); } /////////////////////////////////////////// void Emif_sdram_gpio(void) { EALLOW; GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 2;//GPIO29 EM1SDCKE GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 2;//CLK GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 2;//WE GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 2;//CS0 GPIO B Mux 1 Register (GPIO32 to 47) GpioCtrlRegs.GPBMUX1.bit.GPIO38 = 2;//A0 GpioCtrlRegs.GPBMUX1.bit.GPIO39 = 2;//A1 GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2;//A2 GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2;//A3 GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2;//A4 GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2;//A5 GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2;//A6 GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2;//A7 GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 2;//A8 GPIO B Mux 2 Register (GPIO48 to 63) GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 2;//A9 GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 2;//A10 GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 2;//D31 GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 2;//D30 GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 2;//D29 GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2;//D28 GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2;//D27 GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2;//D26 GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2;//D25 GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 2;//D24 GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 2;//D23 GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2;//D22 GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2;//D21 GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2;//D20 GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2;//D19 GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2;//D18 GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2;//D17 GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2;//D16 GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2;//D15 GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2;//D14 GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2;//D13 GpioCtrlRegs.GPCMUX1.bit.GPIO72 = 2;//D12 GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 2;//D11 GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 2;//D10 GpioCtrlRegs.GPCMUX1.bit.GPIO75 = 2;//D9 GpioCtrlRegs.GPCMUX1.bit.GPIO76 = 2;//D8 GpioCtrlRegs.GPCMUX1.bit.GPIO77 = 2;//D7 GpioCtrlRegs.GPCMUX1.bit.GPIO78 = 2;//D6 GpioCtrlRegs.GPCMUX1.bit.GPIO79 = 2;//D5 GpioCtrlRegs.GPCMUX2.bit.GPIO80 = 2;//D4 GpioCtrlRegs.GPCMUX2.bit.GPIO81 = 2;//D3 GpioCtrlRegs.GPCMUX2.bit.GPIO82 = 2;//D2 GpioCtrlRegs.GPCMUX2.bit.GPIO83 = 2;//D1 GpioCtrlRegs.GPCMUX2.bit.GPIO85 = 2;//D0 GpioCtrlRegs.GPCMUX2.bit.GPIO86 = 3;//CAS GpioCtrlRegs.GPCMUX2.bit.GPIO87 = 3;//RAS GpioCtrlRegs.GPCMUX2.bit.GPIO88 = 3;//DQM0 GpioCtrlRegs.GPCMUX2.bit.GPIO89 = 3;//DQM1 GpioCtrlRegs.GPCMUX2.bit.GPIO90 = 3;//DQM2 GpioCtrlRegs.GPCMUX2.bit.GPIO91 = 3;//DQM3 GpioCtrlRegs.GPCMUX2.bit.GPIO92 = 3;//BA1 GpioCtrlRegs.GPCMUX2.bit.GPIO93 = 3;//BA0 //set GPIO Direction as output EDIS; } void Emif_sdram_config(void) { //STEP 1 SDRAM should be placed in Self-Refresh Mode by setting the SR bit in //the SDRAM configuration register (SDCR). The SR bit should be set using a byte-write to the upper byte //of the SDCR to avoid triggering the SDRAM Initialization Sequence Emif1Regs.SDRAM_CR.bit.SR = 1; //STEP 2 The device global clock module (GCM) should first be programmed to select the desired EMIF_CLK frequency // EMIFx can be configured in SDRAM mode or ASRAM mode. // For SDRAM mode, max operational frq is 100MHz and for ASRAM 200 MHz. // http://e2e.ti.com/support/microcontrollers/c2000/f/171/p/328275/1143419.aspx#1143419 ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 1; // EMIF1CLK = PLLSYSCLK / (EMIF1CLKDIV+1) = PLLSYSCLK = 100MHz //STEP 3 selecting the appropriate clock source for the VCLK3 domain //STEP 4 remove the SDRAM from Self-Refresh by clearing the SR bit in SDCR, again with a byte-write. Emif1Regs.SDRAM_CR.bit.SR = 0; //STEP 5 Emif1Regs.SDRAM_TR.all = 0x5b338b20; //SDRAM Timing Register 0101-1 011 -0 011 -0 011 -1000 -1011 -0 010 -0000 // T_RFC >= (tRFC × fEM1CLK) - 1 ; tRC = 60ns, 60*(10^-9) x 0.2*(10^9) - 1 = 11 (27-31) // T_RP >= (tRP × fEM1CLK) - 1 ; tRP = 18ns, 18 x 0.2 - 1 = 2.6 = 3 (24-26) // T_RCD >= (tRCD × fEM1CLK) - 1 ; tRCD = 18ns, 18 x 0.2 -1 = 3 (20-22) // T_WR >= (tWR × fEM1CLK) - 1 ; tWR = 2tCK = 2 x 10ns(CL=2), 20 x 0.2 -1 = 3 (16-18) // T_RAS >= (tRAS × fEM1CLK) - 1 ; tRAS = 42ns, 42 x 0.2 -1 = 8 (12-15) // T_RC >= (tRC × fEM1CLK) - 1 ; tRC = 60ns, 60 x 0.2 -1 = 11 (8-11) // T_RRD >= (tRRD × fEM1CLK) - 1 ; tRRD = 12ns, 12 x 0.2 -1 = 2 (4-6) Emif1Regs.SDR_EXT_TMNG.all = 0x0c; //self refresh exit timing register // T_XS >= (tXSR × fEM1CLK) - 1 ; tXSR=tRC+tIS=60+1.5=61.5ns, 61.5 x 0.2 - 1 = 12 (0-4) Emif1Regs.SDRAM_RCR.all = 0x0c35; //Refresh Control Register // RR = fEM1CLK × tRefresh Period / ncycles ; tRefresh Period = 64 ms; ncycles = 4096; = 3125 (0-12) Emif1Regs.SDRAM_CR.all = 0x0520;// 0x0520; //configuration register // SR 0 To avoid placing the EMIF into the self-refresh state // NM 0 To configure the EMIF for a 32-bit data bus // CL 010b To select a CAS latency of 2 // BIT11_9LOCK 1 To allow the CL field to be written // IBANK 010b To select 4 internal SDRAM banks // PAGESIZE 0 To select a page size of 256 words // 000 00000 000000 0 0 0(15) 0(NM) 0 0 010 1(8) 0 010 0 000 // 0000 0000 0000 0000 0000 0101 0010 0000 // 00 00 0520 } void error(void) { asm(" ESTOP0"); // Test failed!! Stop! for (;;); }