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 (;;);
}