AnsweredAssumed Answered

Specific initalization parameters for the SDRAM chip on the rt1060-evk board

Question asked by Richard Tilson on Jul 31, 2020
Latest reply on Aug 3, 2020 by jeremyzhou

I am having an immense amount of trouble getting the SDRAM chip initialized on the rt1060-evk.

I went through the memory performance example found in an12437sw, however the exact values used to populate the SEMC registers are heavily obfuscated and finding those values is unclear/error prone. With the code I have below, I always have an IPCMDERR interrupt and I do not know why. I am running the SEMC at  132MHz and the processor core at 600MHz.

 

What am I missing?

 

The code I have for initializing the SDRAM is:

 

void SDRAM_Init(void) //Base regions start 8000_0000
{

     CCM->CBCDR &= ~(CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK | CCM_CBCDR_SEMC_CLK_SEL_MASK); //Primary clock comes from PLL2 - PFD2
     CCM->CBCDR |= (CCM_CBCDR_SEMC_ALT_CLK_SEL(0) | CCM_CBCDR_SEMC_CLK_SEL(1)); //Primary clock comes from CBCDR(SEMC_ALT_SEL)
     //clock is PFD2/3 = 396/3 = 132MHz
     CCM->CCGR3 |= CCM_CCGR3_CG2(3); //Enables the clock gate and is on in all cpu modes except for stop
     CCM->CCGR1 |= CCM_CCGR1_CG9(3);

     SEMC->MCR = SEMC_MCR_SWRST_MASK;//reset the peripheral
     while (SEMC->MCR & SEMC_MCR_SWRST_MASK);

     SEMC->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_BTO(0x1F) | SEMC_MCR_CTO(0) | SEMC_MCR_DQSMD(1);

     SEMC->IOCR |= (SEMC_IOCR_MUX_CLKX0(1) | SEMC_IOCR_MUX_CLKX1(1) |
                       SEMC_IOCR_MUX_RDY(1) | SEMC_IOCR_MUX_CSX0(0) | SEMC_IOCR_MUX_A8(0));

     SEMC->BMCR0 = SEMC_BMCR0_WAGE(8) | SEMC_BMCR0_WQOS(5) | SEMC_BMCR0_WSH(0x40) | SEMC_BMCR0_WRWS(0x10); //Needs more research - Default Operation
     SEMC->BMCR1 = SEMC_BMCR1_WAGE(8) | SEMC_BMCR1_WQOS(5) | SEMC_BMCR1_WPH(0x60) | SEMC_BMCR1_WBR(0x40) | SEMC_BMCR1_WRWS(0x24); //Needs more research - Default Operation
     SEMC->MCR &= ~SEMC_MCR_MDIS_MASK;

     SEMC->BR[0]= SEMC_BR_BA(0x90000) |SEMC_BR_MS(0xD) | SEMC_BR_VLD_MASK; // SDRAM_CS0 - Address of 9000_F000
     SEMC->BR[1] = 0;
     SEMC->BR[2] = 0;
     SEMC->BR[3] = 0;

     SEMC->INTEN = 0x0C; //bits 0-7 all AXI/IP error interrupts enabled, 8-9 Nand related
     SEMC->INTR = 0x1F; //Interrupt status register

     //SDRAM Configuration Registers in SEMC   values calculated go ("(DataSheet_NS * 1000) / (SEMC Clock Rate / 1000000) = (Value)" )
     SEMC->SDRAMCR0 = SEMC_SDRAMCR0_BANK2(0) | SEMC_SDRAMCR0_CL(3) |  SEMC_SDRAMCR0_COL(3) | SEMC_SDRAMCR0_COL8(0) | SEMC_SDRAMCR0_BL(3) | SEMC_SDRAMCR0_PS(1); //needs more research
     SEMC->SDRAMCR1 = SEMC_SDRAMCR1_PRE2ACT(1) | SEMC_SDRAMCR1_ACT2RW(1) | SEMC_SDRAMCR1_RFRC(7) | SEMC_SDRAMCR1_WRC(0) | SEMC_SDRAMCR1_CKEOFF(4) | SEMC_SDRAMCR1_ACT2PRE(4);
     SEMC->SDRAMCR2 = SEMC_SDRAMCR2_ACT2ACT(7) | SEMC_SDRAMCR2_REF2REF(7) | SEMC_SDRAMCR2_SRRC(7) | SEMC_SDRAMCR2_ITO(0);
     SEMC->SDRAMCR3 = SEMC_SDRAMCR3_UT(6)| SEMC_SDRAMCR3_RT(6) | SEMC_SDRAMCR3_PRESCALE(0) | SEMC_SDRAMCR3_REBL(0);


     //SDRAM Chip Init -------


     //wait atleast 100us, we'll do 1ms
     SysTick_Init(SYSTICK_SLOW); //Systick is running at 100KHz
     SysTick_Start(1000);
     while(SysTick_GetState() != STSTATE_STOP);

     //PreCharge
     SEMC->IPCR0 = 0x90000;
     SEMC->IPCR1 = 0x2;
     SEMC->IPCR2 = 0x0;
     SEMC->IPTXDAT = 0;

     SEMC->IPCMD = 0xA55A000F; //SEMC_IPCMD_KEY(0xA55A) | SEMC_IPCMD_CMD(0xF); //pre-charge all
     while((SEMC->INTR & SEMC_INTR_IPCMDDONE_MASK) == 0);
     SEMC->INTR = SEMC_INTR_IPCMDDONE_MASK;
     /*
     SEMC->INTR = SEMC_INTR_IPCMDDONE_MASK | SEMC_INTR_IPCMDERR_MASK;
     SEMC->IPCMD = SEMC_IPCMD_KEY(0xA55A) | SEMC_IPCMD_CMD(0xC); //auto-refresh
     while((SEMC->INTR & SEMC_INTR_IPCMDDONE_MASK) == 0);

     SEMC->INTR = SEMC_INTR_IPCMDDONE_MASK | SEMC_INTR_IPCMDERR_MASK;
     SEMC->IPCMD = SEMC_IPCMD_KEY(0xA55A) | SEMC_IPCMD_CMD(0xC); //auto-refresh
     while((SEMC->INTR & SEMC_INTR_IPCMDDONE_MASK) == 0);

     //Configure the RAM Chip though the IP Bus, AXI bus reads are done simply via accessing.
     //IP CMD Command Key ((0xA55A) << 16) | 0xA ( Mode Set for SDRAM ),
     SEMC->INTR = SEMC_INTR_IPCMDDONE_MASK | SEMC_INTR_IPCMDERR_MASK;
     SEMC->IPTXDAT = 0x033U;
     SEMC->IPCMD = SEMC_IPCMD_KEY(0xA55A) | SEMC_IPCMD_CMD(0xA); //mode set
     while((SEMC->INTR & SEMC_INTR_IPCMDDONE_MASK) == 0);
     SEMC->INTR = SEMC_INTR_IPCMDDONE_MASK;

     //Enable SEMC Clock
     SEMC->SDRAMCR3 |= SEMC_SDRAMCR3_REN_MASK;
     */
}

Outcomes