/** * \brief Initialize the SDRAM controller. * * \param p_sdram Pointer to the sdram memory structure. * \param ul_clk SDRAM clock frequency. */ void sdramc_init(sdramc_memory_dev_t *p_sdram, uint32_t ul_clk) { volatile uint32_t i; /* Prevent setting the SDRAMC entering to sleep mode */ sleepmgr_lock_mode(SLEEPMGR_ACTIVE); /* SDRAM device configuration */ /* Step 1. */ /* Set the features of SDRAM device into the Configuration Register */ SDRAMC->SDRAMC_CR = p_sdram->cr.ul_cfg; /* Step 2. */ /* For low-power SDRAM, Temperature-Compensated Self Refresh (TCSR), Drive Strength (DS) and Partial Array Self Refresh (PASR) must be set in the Low-power Register. */ SDRAMC->SDRAMC_LPR = 0; /* Step 3. */ /* Program the memory device type into the Memory Device Register */ SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM; /* Step 4. */ /* A minimum pause of 200 μs is provided to precede any signal toggle. (6 core cycles per iteration) */ for (i = 0; i < ((ul_clk / 1000000) * 200 / 6); i++) { ; } /* Step 5. */ /* A NOP command is issued to the SDR-SDRAM. Program NOP command into Mode Register, and the application must set Mode to 1 in the Mode Register. Perform a write access to any SDR-SDRAM address to acknowledge this command. Now the clock which drives SDR-SDRAM device is enabled. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP; *(uint16_t *)(BOARD_SDRAM_ADDR) = 0; /* Step 6. */ /* An all banks precharge command is issued to the SDR-SDRAM. Program all banks precharge command into Mode Register, and the application must set Mode to 2 in the Mode Register. Perform a write access to any SDRSDRAM address to acknowledge this command. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE; *(uint16_t *)(BOARD_SDRAM_ADDR) = 0x0; /* Add some delays after precharge */ for (i = 0; i < ((ul_clk / 1000000) * 200 / 6); i++) { ; } /* Step 7. */ /* Eight auto-refresh (CBR) cycles are provided. Program the auto refresh command (CBR) into Mode Register, and the application must set Mode to 4 in the Mode Register. Once in the idle state, eight AUTO REFRESH cycles must be performed. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x1; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x2; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x3; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x4; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x5; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x6; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x7; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(BOARD_SDRAM_ADDR + 0) = 0x8; /* Step 8. */ /* A Mode Register Set (MRS) cycle is issued to program the parameters of the SDRAM devices, in particular CAS latency and burst length. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG; *(uint16_t *)(BOARD_SDRAM_ADDR + p_sdram->ul_mode) = 0xcafe; /* Step 9. */ /* For low-power SDR-SDRAM initialization, an Extended Mode Register Set (EMRS) cycle is issued to program the SDR-SDRAM parameters (TCSR, PASR, DS). The write address must be chosen so that BA[1] is set to 1 and BA[0] is set to 0. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG; *((uint16_t *)(BOARD_SDRAM_ADDR + (1 << p_sdram->ul_bk1))) = 0; /* Step 10. */ /* The application must go into Normal Mode, setting Mode to 0 in the Mode Register and perform a write access at any location in the\ SDRAM to acknowledge this command. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL; *(uint16_t *)(BOARD_SDRAM_ADDR) = 0x0; /* Step 11. */ /* Write the refresh rate into the count field in the SDRAMC Refresh Timer register. Set Refresh timer to 15.625 us. */ i = ul_clk / 1000u; i *= 15625u; i /= 1000000u; SDRAMC->SDRAMC_TR = SDRAMC_TR_COUNT(i); }
/** * \brief Configure and initialize the SDRAM controller. * \param pMemory Pointer to the sdram structure. * \param dwClockFrequency SDRAM clock frequency. */ extern void SDRAMC_Configure( SSdramc_Memory* pMemory, uint32_t dwClockFrequency ) { volatile uint32_t dw ; /* SDRAM hardware init */ /* Enable peripheral clock */ PMC_EnablePeripheral( ID_SMC ) ; /* SDRAM device configure */ /* Step 1. */ /* Program the features of SDRAM device into the Configuration Register.*/ SDRAMC->SDRAMC_CR = SDRAMC_compute_CR_value( pMemory ) ; /* Step 2. */ /* For low-power SDRAM, temperature-compensated self refresh (TCSR), drive strength (DS) and partial array self refresh (PASR) must be set in the Low-power Register.*/ SDRAMC->SDRAMC_LPR = 0; /* Step 3. */ /* Program the memory device type into the Memory Device Register */ SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM; /* Step 4 */ /* A minimum pause of 200 ¦Ìs is provided to precede any signal toggle. (6 core cycles per iteration) */ for ( dw = 0; dw < ((dwClockFrequency/1000000)*200/6) ; dw++ ) ; /* Step 5. */ /* A NOP command is issued to the SDR-SDRAM. Program NOP command into Mode Register, the application must set Mode to 1 in the Mode Register. Perform a write access to any SDR-SDRAM address to acknowledge this command. Now the clock which drives SDR-SDRAM device is enabled.*/ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP; *(uint16_t *)(EBI_SDRAMC_ADDR) = 0; /* Step 6. */ /* An all banks precharge command is issued to the SDR-SDRAM. Program all banks precharge command into Mode Register, the application must set Mode to 2 in the Mode Register . Perform a write access to any SDRSDRAM address to acknowledge this command. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE; *(uint16_t *)(EBI_SDRAMC_ADDR) = 0x0; /* add some delays after precharge */ for ( dw = 0; dw < ((dwClockFrequency/1000000)*200/6) ; dw++ ); /* Step 7. */ /* Eight auto-refresh (CBR) cycles are provided. Program the auto refresh command (CBR) into Mode Register, the application must set Mode to 4 in the Mode Register. Once in the idle state, eight AUTO REFRESH cycles must be performed. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0 ) = 0x1; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x2; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0 ) = 0x3; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x4; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0 ) = 0x5; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x6; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0 ) = 0x7; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x8; /* Step 8. */ /* A Mode Register set (MRS) cycle is issued to program the parameters of the SDRAM devices, in particular CAS latency and burst length. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG; *(uint16_t *)(EBI_SDRAMC_ADDR + 0x22) = 0xcafe; /* Step 9. */ /* For low-power SDR-SDRAM initialization, an Extended Mode Register set (EMRS) cycle is issued to program the SDR-SDRAM parameters (TCSR, PASR, DS). The write address must be chosen so that BA[1] is set to 1 and BA[0] is set to 0 */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG; *((uint16_t *)(EBI_SDRAMC_ADDR + (1 << pMemory->cfg.dwBK1))) = 0; /* Step 10. */ /* The application must go into Normal Mode, setting Mode to 0 in the Mode Register and perform a write access at any location in the SDRAM to acknowledge this command. */ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL; *(uint16_t *)(EBI_SDRAMC_ADDR ) = 0x0; /* Step 11. */ /* Write the refresh rate into the count field in the SDRAMC Refresh Timer register. Set Refresh timer 15.625 us*/ dw=dwClockFrequency/1000u ; dw*=15625u ; dw/=1000000u ; SDRAMC->SDRAMC_TR = SDRAMC_TR_COUNT( dw ) ; }
void sdramInit(uint32_t coreClockFrequency) { uint32_t n; //Enable PIO peripheral clocks PMC->PMC_PCER0 = (1 << ID_PIOC) | (1 << ID_PIOD); //Enable SMC peripheral clock PMC->PMC_PCER0 = (1 << ID_SMC); //Assign SDRAM pins to Peripheral A function PIOC->PIO_ABSR &= ~SDRAM_PIOC_MASK; //Disable the PIO from controlling the corresponding pins PIOC->PIO_PDR = SDRAM_PIOC_MASK; //Enable pull-ups PIOC->PIO_PUER = SDRAM_PIOC_MASK; //Assign SDRAM pins to Peripheral A function PIOD->PIO_ABSR &= ~SDRAM_PIOD_MASK; //Disable the PIO from controlling the corresponding pins PIOD->PIO_PDR = SDRAM_PIOD_MASK; //Enable pull-ups PIOD->PIO_PUER = SDRAM_PIOD_MASK; //Configure SDRAM enable pin as an output PIOD->PIO_PER = PIO_PD18; PIOD->PIO_OER = PIO_PD18; PIOD->PIO_SODR = PIO_PD18; //SDRAM features must be set in the Configuration Register SDRAMC->SDRAMC_CR = SDRAMC_CR_NC_COL9 | //Number of columns (512) SDRAMC_CR_NR_ROW13 | //Number of rows (8192) SDRAMC_CR_NB_BANK4 | //Number of banks (4) SDRAMC_CR_CAS_LATENCY2 | //CAS latency (2 cycles) SDRAMC_CR_DBW | //Data bus width (16 bits) SDRAMC_CR_TWR(2) | //Write recovery delay (2 cycles) SDRAMC_CR_TRC_TRFC(9) | //Row cycle delay (9 cycles) SDRAMC_CR_TRP(3) | //Row precharge delay (3 cycles) SDRAMC_CR_TRCD(3) | //Row to column delay (3 cycles) SDRAMC_CR_TRAS(6) | //Active to precharge delay (6 cycles) SDRAMC_CR_TXSR(10); //Exit self refresh to active delay (10 cycles) //For mobile SDRAM, temperature-compensated self refresh (TCSR), drive strength (DS) //and partial array self refresh (PASR) must be set in the Low Power Register SDRAMC->SDRAMC_LPR = 0; //The SDRAM memory type must be set in the Memory Device Register SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM; //A minimum pause of 200 us is provided to precede any signal toggle sleep(1); //A NOP command is issued to the SDRAM device. The application must set Mode to 1 //in the Mode Register and perform a write access to any SDRAM address SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; //An All Banks Precharge command is issued to the SDRAM devices. The application must //set Mode to 2 in the Mode Register and perform a write access to any SDRAM address SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; //Eight auto-refresh (CBR) cycles are provided. The application must set the Mode to 4 //in the Mode Register and perform a write access to any SDRAM location eight times SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; //A Mode Register set (MRS) cycle is issued to program the parameters of the SDRAM device, //in particular CAS latency and burst length. The application must set Mode to 3 in the //Mode Register and perform a write access to the SDRAM. The write address must be chosen //so that BA[1:0] are set to 0 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; //For mobile SDRAM initialization, an Extended Mode Register set (EMRS) cycle is //issued to program the SDRAM parameters (TCSR, PASR, DS). The application must //set Mode to 5 in the Mode Register and perform a write access to the SDRAM. The //write address must be chosen so that BA[1] or BA[0] are set to 1 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG; *((uint16_t *)(SDRAM_BASE) + 0x01000000) = 0x00000000; //The application must go into Normal Mode, setting Mode to 0 in the Mode Register and //performing a write access at any location in the SDRAM SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL; *((uint16_t *)(SDRAM_BASE)) = 0x00000000; //Set refresh rate (15.625us) n = coreClockFrequency / 1000; n = (n * 15625) / 1000000; //Write the refresh rate into the count field in the SDRAMC Refresh Timer register SDRAMC->SDRAMC_TR = SDRAMC_TR_COUNT(n); }