/** * \brief Calculate the sdram controller config register value. * \param pMemory Pointer to the sdram structure. * \return Configure register value. */ static uint32_t SDRAMC_compute_CR_value( SSdramc_Memory* pMemory ) { uint32_t dw=0 ; dw |= pMemory->cfg.dwColumnBits ; dw |= pMemory->cfg.dwRowBits ; dw |= pMemory->cfg.dwBanks ; //NB, number of banks dw |= pMemory->cfg.dwCAS ; //CAS, CAS latency dw |= pMemory->cfg.dwDataBusWidth ; //DBW, data bus width dw |= SDRAMC_CR_TWR( pMemory->cfg.dwWriteRecoveryDelay ) ; //TWR, Write Recovery Delay dw |= SDRAMC_CR_TRC_TRFC( pMemory->cfg.dwRowCycleDelay_RowRefreshCycle ) ; //TRC_TRFC,Row Cycle Delay and Row Refresh Cycle dw |= SDRAMC_CR_TRP( pMemory->cfg.dwRowPrechargeDelay ) ; //TRP, Row Precharge Delay dw |= SDRAMC_CR_TRCD( pMemory->cfg.dwRowColumnDelay ) ; //TRCD, Row to Column Delay dw |= SDRAMC_CR_TRAS( pMemory->cfg.dwActivePrechargeDelay ) ; //TRAS, Active to Precharge Delay dw |= SDRAMC_CR_TXSR( pMemory->cfg.dwExitSelfRefreshActiveDelay ) ; //TXSR, Exit Self Refresh to Active Delay return dw ; }
void BOARD_ConfigureSdram(void) { #ifndef __rtems__ const Pin pinsSdram[] = {BOARD_SDRAM_PINS}; #endif /* __rtems__ */ volatile uint32_t i; volatile uint8_t *pSdram = (uint8_t *) SDRAM_CS_ADDR; /* Configure PIO */ #ifndef __rtems__ PIO_Configure(pinsSdram, PIO_LISTSIZE(pinsSdram)); #endif /* __rtems__ */ PMC_EnablePeripheral(ID_SDRAMC); MATRIX->CCFG_SMCNFCS = CCFG_SMCNFCS_SDRAMEN; /* 1. SDRAM features must be set in the configuration register: asynchronous timings (TRC, TRAS, etc.), number of columns, rows, CAS latency, and the data bus width. */ SDRAMC->SDRAMC_CR = SDRAMC_CR_NC_COL8 // 8 column bits | SDRAMC_CR_NR_ROW11 // 12 row bits (4K) | SDRAMC_CR_CAS_LATENCY3 // CAS Latency 3 | SDRAMC_CR_NB_BANK2 // 2 banks | SDRAMC_CR_DBW // 16 bit | SDRAMC_CR_TWR(5) | SDRAMC_CR_TRC_TRFC(13) // 63ns min | SDRAMC_CR_TRP(5) // Command period (PRE to ACT) 21 ns min | SDRAMC_CR_TRCD( 5) // Active Command to read/Write Command delay time 21ns min | SDRAMC_CR_TRAS(9) // Command period (ACT to PRE) 42ns min | SDRAMC_CR_TXSR(15U); // Exit self-refresh to active time 70ns Min /* 2. 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. */ /* 3. The SDRAM memory type must be set in the Memory Device Register.*/ SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM; /* 4. A minimum pause of 200 ¦Ìs is provided to precede any signal toggle.*/ for (i = 0; i < 100000; i++); /* 5. (1)A NOP command is issued to the SDRAM devices. 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; *pSdram = 0; for (i = 0; i < 100000; i++); /* 6. 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; *pSdram = 0; for (i = 0; i < 100000; i++); /* 7. 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.*/ for (i = 0; i < 8; i++) { SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; *pSdram = 0; } for (i = 0; i < 100000; i++); /*8. A Mode Register set (MRS) cycle is issued to program the parameters of the SDRAM devices, 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. For example, with a 16-bit 128 MB SDRAM (12 rows, 9 columns, 4 banks) bank address, the SDRAM write access should be done at the address 0x70000000.*/ SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG; *pSdram = 0; for (i = 0; i < 100000; i++); /*9. 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. For example, with a 16-bit 128 MB SDRAM, (12 rows, 9 columns, 4 banks) bank address the SDRAM write access should be done at the address 0x70800000 or 0x70400000. */ //SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG; // *((uint8_t *)(pSdram + SDRAM_BA0)) = 0; /* 10. 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; *pSdram = 0; for (i = 0; i < 100000; i++); /* 11. Write the refresh rate into the count field in the SDRAMC Refresh Timer register. (Refresh rate = delay between refresh cycles). The SDRAM device requires a refresh every 15.625 ¦Ìs or 7.81 ¦Ìs. With a 100 MHz frequency, the Refresh Timer Counter Register must be set with the value 1562(15.625 ¦Ìs x 100 MHz) or 781(7.81 ¦Ìs x 100 MHz). */ // For IS42S16100E, 2048 refresh cycle every 32ms, every 15.625 ¦Ìs /* ((32 x 10(^-3))/2048) x150 x (10^6) */ SDRAMC->SDRAMC_TR = 1562; SDRAMC->SDRAMC_CFR1 |= SDRAMC_CFR1_UNAL; /* After initialization, the SDRAM devices are fully functional. */ }
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); }
#error Please check SDRAM settings for this clock frequency. #endif const struct BOARD_Sdram_Config BOARD_Sdram_Config = { /* FIXME: a lot of these values should be calculated using CPU frequency */ .sdramc_tr = 1562, .sdramc_cr = SDRAMC_CR_NC_COL8 /* 8 column bits */ | SDRAMC_CR_NR_ROW11 /* 12 row bits (4K) */ | SDRAMC_CR_CAS_LATENCY3 /* CAS Latency 3 */ | SDRAMC_CR_NB_BANK2 /* 2 banks */ | SDRAMC_CR_DBW /* 16 bit */ | SDRAMC_CR_TWR(5) | SDRAMC_CR_TRC_TRFC(13) /* 63ns min */ | SDRAMC_CR_TRP(5) /* Command period (PRE to ACT) 21 ns min */ | SDRAMC_CR_TRCD(5) /* Active Command to R/W Cmd delay time 21ns min */ | SDRAMC_CR_TRAS(9) /* Command period (ACT to PRE) 42ns min */ | SDRAMC_CR_TXSR(15U), /* Exit self-refresh to active time 70ns Min */ .sdramc_mdr = SDRAMC_MDR_MD_SDRAM, .sdramc_cfr1 = SDRAMC_CFR1_UNAL_SUPPORTED | SDRAMC_CFR1_TMRD(2) }; #elif defined ATSAM_SDRAM_IS42S16320F_7BL #if ATSAM_MCK != 123000000 #error Please check SDRAM settings for this clock frequency. #endif #define CLOCK_CYCLES_FROM_NS_MAX(ns) \ (((ns) * (ATSAM_MCK / 1000ul / 1000ul)) / 1000ul) #define CLOCK_CYCLES_FROM_NS_MIN(ns) (CLOCK_CYCLES_FROM_NS_MAX(ns) + 1)