Other Parts Discussed in Thread: C2000WARE
I am trying to set up a custom board with the TMS320F28379D and an external SDRAM memory (2M word x 32-bit x 4-bank - AS4C8M32S-6TIN) with EMIF1 set up EMIF1CLK = CPU1SYSCLK/2 with CPU1SYSCLK = 200MHz.
I also adapted the emif1_32bit_sdram_cpu01 example code to my custom application.
The problem I am seeing is that all data seems to be mirrored to all addresses of the external memory, instead of being incremented by 1 in each memory position as the sample code performs.
I can make the application run fine if I reduce the CPU1SYSCLK to 100MHz and the EMIF1 clock to 50MHz.
I adapted the code to perform both initialization methods suggested in the document (SPRUHM8I, 25.5.5.5 SDRAM Configuration Procedure), but both methods seem to have the same result.
Can anyone check if my setup for the external SDRAM is fine and help to make this interface work properly at EMIF1 at 100 MHz?
See below the code I am using for the procedure B. Also, I have attached the memory browser behavior to the code running at EMIF1 at 50MHz (working fine) and at 100MHz (with mirrored data).
// ------------------------------------------------------------------------ // Includes // ------------------------------------------------------------------------ #include "F2837xD_device.h" #include "F2837xD_Examples.h" #include "GPIO.h" #include "EMIF1.h" // Defines // #define TEST_PASS 0xABCDABCD #define TEST_FAIL 0xDEADDEAD #define SDRAM_CS0_START_ADDR 0x80000000 #define SDRAM_CS0_SIZE 0x00800000 // // Globals // Uint16 ErrCount = 0; Uint32 TEST_STATUS; Uint32 ii; void Emif1Config(void) { char ErrCount_local; TEST_STATUS = TEST_FAIL; EALLOW; // // Grab EMIF1 For CPU1 // Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE71; if(Emif1ConfigRegs.EMIF1MSEL.all != 0x1) { ErrCount++; } // //Disable Access Protection (CPU_FETCH/CPU_WR/DMA_WR) // Emif1ConfigRegs.EMIF1ACCPROT0.all = 0x0; if(Emif1ConfigRegs.EMIF1ACCPROT0.all != 0x0) { ErrCount++; } // // Commit the configuration related to protection. Till this bit remains // set content of EMIF1ACCPROT0 register can't be changed. // Emif1ConfigRegs.EMIF1COMMIT.all = 0x1; if(Emif1ConfigRegs.EMIF1COMMIT.all != 0x1) { ErrCount++; } // // Lock the configuration so that EMIF1COMMIT register can't be changed // any more. // Emif1ConfigRegs.EMIF1LOCK.all = 0x1; if(Emif1ConfigRegs.EMIF1LOCK.all != 1) { ErrCount++; } EDIS; InitEsaTrdEmif1Gpio();
// Put memory in self refresh mode to change frequency Emif1Regs.SDRAM_CR.bit.SR = 0x1; //Configure to run EMIF1 on half Rate (EMIF1CLK = CPU1SYSCLK/2) // EALLOW; ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 0x1; EDIS;
// Release self refresh mode Emif1Regs.SDRAM_CR.bit.SR = 0x0; //Configure SDRAM control registers // Need to be programmed based on SDRAM Data-Sheet. //T_RFC = 60ns = 0x6 //T_RP = 18ns = 0x1 //T_RCD = 18ns = 0x1 //T_WR = 12ns = 0x1 //T_RAS = 42ns = 0x4 //T_RC = 60ns = 0x6 //T_RRD = 12ns = 0x1 Emif1Regs.SDRAM_TR.bit.T_RFC = 0x6; Emif1Regs.SDRAM_TR.bit.T_RP = 0x1; Emif1Regs.SDRAM_TR.bit.T_RCD = 0x1; Emif1Regs.SDRAM_TR.bit.T_WR = 0x1; Emif1Regs.SDRAM_TR.bit.T_RAS = 0x4; Emif1Regs.SDRAM_TR.bit.T_RC = 0x6; Emif1Regs.SDRAM_TR.bit.T_RRD = 0x1; //Txsr = 61.5ns = 0x6 Emif1Regs.SDR_EXT_TMNG.bit.T_XS = 0x6; //Tref = 64ms (15.6us*4096) for 4096 ROW, RR = 64m*100M/4096 = 1562.5 (0x61B) //Emif1Regs.SDRAM_RCR.all = 0x61B;
//Procedure 2 configuration Emif1Regs.SDRAM_RCR.bit.REFRESH_RATE = 0x9C5; //PAGESIZE=1 (elements per ROW), IBANK = 2 (4 BANK), CL = 3, NM = 0 (32bit) //Emif1Regs.SDRAM_CR.all = 0x00000720; Emif1Regs.SDRAM_CR.bit.SR = 0x0; Emif1Regs.SDRAM_CR.bit.NM = 0; Emif1Regs.SDRAM_CR.bit.CL = 0x3; Emif1Regs.SDRAM_CR.bit.BIT_11_9_LOCK = 0x1; Emif1Regs.SDRAM_CR.bit.IBANK = 0x2; Emif1Regs.SDRAM_CR.bit.PAGESIGE = 0x3;
//Add delay to satisfy SDRAM power-up constraint DELAY_US(200);
//Config the SDRAM datasheet refresh rate Emif1Regs.SDRAM_RCR.bit.REFRESH_RATE = 0x61B; // //Add some extra delay // for(ii=0;ii<123;ii++) { } // Basic read/write check. ErrCount_local = sdram_read_write(SDRAM_CS0_START_ADDR, SDRAM_CS0_SIZE); ErrCount = ErrCount + ErrCount_local; //run different addr walk checks ErrCount_local = sdram_addr_walk(SDRAM_CS0_START_ADDR, 15); ErrCount = ErrCount + ErrCount_local; //run different data walk checks ErrCount_local = sdram_data_walk(SDRAM_CS0_START_ADDR, SDRAM_CS0_SIZE); ErrCount = ErrCount + ErrCount_local; //run different data size checks ErrCount_local = sdram_data_size(SDRAM_CS0_START_ADDR, 4); ErrCount = ErrCount + ErrCount_local; if (ErrCount == 0x0) { TEST_STATUS = TEST_PASS; } } // // sdram_data_walk - This function performs a walking 0 & 1 For SDRAM RD & WR // char sdram_data_walk(Uint32 start_addr, Uint32 mem_size) { Uint32 XM_p, XMEM_p; unsigned long sdram_rdl; unsigned long sdram_wdl; int i; int k; int m; XM_p = start_addr; for (i=0; i < mem_size; i=i+64) { for (m=0; m < 2; m++) { XMEM_p = XM_p; // //Write loop // sdram_wdl = 0x0001; for (k=0; k < 32; k++) { if(m==0) { __addr32_write_uint32(XMEM_p, sdram_wdl); } else { __addr32_write_uint32(XMEM_p, ~sdram_wdl); } XMEM_p = XMEM_p+2; sdram_wdl = sdram_wdl<<1; } // //Read loop // XMEM_p = XM_p; sdram_wdl = 0x0001; for (k=0; k < 32; k++) { sdram_rdl = __addr32_read_uint32(XMEM_p); if(m==1) { sdram_rdl = ~sdram_rdl; } if(sdram_rdl != sdram_wdl) { return(1); } XMEM_p = XMEM_p+2; sdram_wdl=sdram_wdl<<1; } } XM_p = XMEM_p; } return(0); } // // sdram_addr_walk - This function performs a toggle on each address bit. // In this case memory assumed is 4Mb. // MA = BA[1:0]ROW[11:0]COL[7:0] // char sdram_addr_walk(Uint32 start_addr, Uint32 addr_size) { Uint32 XMEM_p; unsigned long sdram_rdl; unsigned long sdram_wdl; int i; unsigned long xshift; unsigned long xshift2; // //Write loop // xshift = 0x00000001; sdram_wdl = 0x5678abcd; for (i=0; i < addr_size; i++) { xshift2 = ((xshift+1)<<1); XMEM_p = start_addr + xshift2; __addr32_write_uint32(XMEM_p, sdram_wdl); sdram_wdl = sdram_wdl+0x11111111; xshift = xshift<<1; } // //Read loop // xshift = 0x00000001; sdram_wdl = 0x5678abcd; for (i=0; i < addr_size; i++) { xshift2 = ((xshift+1)<<1); XMEM_p= start_addr + xshift2; sdram_rdl = __addr32_read_uint32(XMEM_p); if( sdram_rdl != sdram_wdl) { return(1); } xshift = xshift<<1; sdram_wdl = sdram_wdl + 0x11111111; } return(0); } // // sdram_data_size - This function performs different data type // (HALFWORD/WORD) access. // char sdram_data_size(Uint32 start_addr, Uint32 mem_size) { unsigned short sdram_rds; unsigned long sdram_rdl; unsigned short sdram_wds; unsigned long sdram_wdl; int i; Uint32 XMEM_p; // //Write data short // XMEM_p = start_addr; sdram_wds = 0x0605; for (i=0; i < 2; i++) { __addr32_write_uint16(XMEM_p, sdram_wds); XMEM_p++; sdram_wds += 0x0202; } // //Write data long // sdram_wdl = 0x0C0B0A09; for (i=0; i < 2; i++) { __addr32_write_uint32(XMEM_p, sdram_wdl); XMEM_p = XMEM_p+2; sdram_wdl += 0x04040404; } // //Read data short // XMEM_p = start_addr; sdram_wds=0x0605; for (i=0; i < 6; i++) { sdram_rds = __addr32_read_uint16(XMEM_p); if( sdram_rds != sdram_wds) { return(1); } XMEM_p++; sdram_wds += 0x0202; } // //Read data long // XMEM_p = start_addr; sdram_wdl=0x08070605; for (i=0; i < 3; i++) { sdram_rdl = __addr32_read_uint32(XMEM_p); if( sdram_rdl != sdram_wdl) { return(1); } XMEM_p = XMEM_p+2; sdram_wdl += 0x04040404; } return(0); } // // sdram_read_write - This function performs simple read/write accesses // to memory. // char sdram_read_write(Uint32 start_addr, Uint32 mem_size) { unsigned long mem_rdl; unsigned long mem_wdl; Uint32 XMEM_p; Uint32 i; // //Write data // XMEM_p = start_addr; // //Fill memory // mem_wdl = 0x01234567; for (i=0; i < mem_size; i++) { __addr32_write_uint32(XMEM_p, mem_wdl); XMEM_p = XMEM_p+2; mem_wdl += 0x11111111; } // //Verify memory // mem_wdl = 0x01234567; XMEM_p = start_addr; for (i=0; i < mem_size; i++) { mem_rdl = __addr32_read_uint32(XMEM_p); if( mem_rdl != mem_wdl) { return(1); } XMEM_p = XMEM_p+2; mem_wdl += 0x11111111; } return(0); }