00001 /* ---------------------------------------------------------------------------- */ 00002 /* Atmel Microcontroller Software Support */ 00003 /* SAM Software Package License */ 00004 /* ---------------------------------------------------------------------------- */ 00005 /* Copyright (c) 2015, Atmel Corporation */ 00006 /* */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without */ 00010 /* modification, are permitted provided that the following condition is met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, */ 00013 /* this list of conditions and the disclaimer below. */ 00014 /* */ 00015 /* Atmel's name may not be used to endorse or promote products derived from */ 00016 /* this software without specific prior written permission. */ 00017 /* */ 00018 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ 00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ 00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ 00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ 00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ 00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ 00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00028 /* ---------------------------------------------------------------------------- */ 00029 00030 /** \addtogroup sdram_module 00031 * The SDRAMC driver provides the Interface to configure the SDRAM Controller 00032 * (SDRAMC). 00033 * \section Usage 00034 * <ul> 00035 * <li> Configure SDRAM using SDRAMC_Configure().</li> 00036 00037 * </ul> 00038 * For more accurate information, please look at the SDRAMC section of the 00039 * Datasheet. 00040 * Related files :\n 00041 * \ref sdramc.c\n 00042 * \ref sdramc.h.\n 00043 */ 00044 00045 /** 00046 * \file 00047 * 00048 * \section Purpose 00049 * 00050 * Interface for configuring and using SDRAM Controller (SDRAMC). 00051 * 00052 */ 00053 00054 /** 00055 * \file 00056 * 00057 * Implementation of memories configuration on board. 00058 * 00059 */ 00060 /*---------------------------------------------------------------------------- 00061 * Headers 00062 *----------------------------------------------------------------------------*/ 00063 #include "chip.h" 00064 #include "sdramc.h" 00065 00066 /*---------------------------------------------------------------------------- 00067 * Local functions 00068 *----------------------------------------------------------------------------*/ 00069 /** 00070 * \brief Calculate the sdram controller config register value. 00071 * \param pMemory Pointer to the sdram structure. 00072 * \return Configure register value. 00073 */ 00074 static uint32_t SDRAMC_compute_CR_value(SSdramc_Memory *pMemory) 00075 { 00076 uint32_t dw = 0; 00077 00078 dw |= pMemory->cfg.dwColumnBits; 00079 dw |= pMemory->cfg.dwRowBits; 00080 dw |= pMemory->cfg.dwBanks; //NB, number of banks 00081 dw |= pMemory->cfg.dwCAS; //CAS, CAS latency 00082 dw |= pMemory->cfg.dwDataBusWidth; //DBW, data bus width 00083 dw |= SDRAMC_CR_TWR(pMemory->cfg.dwWriteRecoveryDelay); 00084 //TWR, Write Recovery Delay 00085 dw |= SDRAMC_CR_TRC_TRFC(pMemory->cfg.dwRowCycleDelay_RowRefreshCycle); 00086 //TRC_TRFC,Row Cycle Delay and Row Refresh Cycle 00087 dw |= SDRAMC_CR_TRP(pMemory->cfg.dwRowPrechargeDelay); 00088 //TRP, Row Precharge Delay 00089 dw |= SDRAMC_CR_TRCD(pMemory->cfg.dwRowColumnDelay); 00090 //TRCD, Row to Column Delay 00091 dw |= SDRAMC_CR_TRAS(pMemory->cfg.dwActivePrechargeDelay); 00092 //TRAS, Active to Precharge Delay 00093 dw |= SDRAMC_CR_TXSR(pMemory->cfg.dwExitSelfRefreshActiveDelay); 00094 //TXSR, Exit Self Refresh to Active Delay 00095 return dw; 00096 } 00097 00098 /*---------------------------------------------------------------------------- 00099 * Exported functions 00100 *----------------------------------------------------------------------------*/ 00101 /** 00102 * \brief Configure and initialize the SDRAM controller. 00103 * \param pMemory Pointer to the sdram structure. 00104 * \param dwClockFrequency SDRAM clock frequency. 00105 */ 00106 extern void SDRAMC_Configure(SSdramc_Memory *pMemory, 00107 uint32_t dwClockFrequency) 00108 { 00109 volatile uint32_t dw; 00110 00111 /* SDRAM hardware init */ 00112 /* Enable peripheral clock */ 00113 PMC_EnablePeripheral(ID_SMC); 00114 00115 /* SDRAM device configure */ 00116 /* Step 1. */ 00117 /* Program the features of SDRAM device into the Configuration Register.*/ 00118 SDRAMC->SDRAMC_CR = SDRAMC_compute_CR_value(pMemory); 00119 00120 /* Step 2. */ 00121 /* For low-power SDRAM, temperature-compensated self refresh (TCSR), 00122 drive strength (DS) and partial array self refresh (PASR) must be set 00123 in the Low-power Register.*/ 00124 SDRAMC->SDRAMC_LPR = 0; 00125 00126 /* Step 3. */ 00127 /* Program the memory device type into the Memory Device Register */ 00128 SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM; 00129 00130 /* Step 4 */ 00131 /* A minimum pause of 200 ¦Ěs is provided to precede any signal toggle. 00132 (6 core cycles per iteration) */ 00133 for (dw = 0; dw < ((dwClockFrequency / 1000000) * 200 / 6); dw++); 00134 00135 /* Step 5. */ 00136 /* A NOP command is issued to the SDR-SDRAM. Program NOP command into 00137 Mode Register, the application must set Mode to 1 in the Mode Register. 00138 Perform a write access to any SDR-SDRAM address to acknowledge this command. 00139 Now the clock which drives SDR-SDRAM device is enabled.*/ 00140 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP; 00141 *(uint16_t *)(EBI_SDRAMC_ADDR) = 0; 00142 00143 /* Step 6. */ 00144 /* An all banks precharge command is issued to the SDR-SDRAM. Program all 00145 banks precharge command into Mode Register, the application must set Mode to 00146 2 in the Mode Register . Perform a write access to any SDRSDRAM address to 00147 acknowledge this command. */ 00148 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE; 00149 *(uint16_t *)(EBI_SDRAMC_ADDR) = 0x0; 00150 00151 /* add some delays after precharge */ 00152 for (dw = 0; dw < ((dwClockFrequency / 1000000) * 200 / 6); dw++); 00153 00154 /* Step 7. */ 00155 /* Eight auto-refresh (CBR) cycles are provided. Program the auto refresh 00156 command (CBR) into Mode Register, the application must set Mode to 4 in 00157 the Mode Register. Once in the idle state, eight AUTO REFRESH cycles must 00158 be performed. */ 00159 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00160 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x1; 00161 00162 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00163 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x2; 00164 00165 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00166 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x3; 00167 00168 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00169 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x4; 00170 00171 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00172 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x5; 00173 00174 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00175 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x6; 00176 00177 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00178 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x7; 00179 00180 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH; 00181 *(uint16_t *)(EBI_SDRAMC_ADDR + 0) = 0x8; 00182 00183 /* Step 8. */ 00184 /* A Mode Register set (MRS) cycle is issued to program the parameters of 00185 the SDRAM devices, in particular CAS latency and burst length. */ 00186 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG; 00187 *(uint16_t *)(EBI_SDRAMC_ADDR + 0x22) = 0xcafe; 00188 00189 /* Step 9. */ 00190 /* For low-power SDR-SDRAM initialization, an Extended Mode Register set 00191 (EMRS) cycle is issued to program the SDR-SDRAM parameters (TCSR, PASR, DS). 00192 The write address must be chosen so that BA[1] is set to 1 and BA[0] is set 00193 to 0 */ 00194 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG; 00195 *((uint16_t *)(EBI_SDRAMC_ADDR + (1 << pMemory->cfg.dwBK1))) = 0; 00196 00197 /* Step 10. */ 00198 /* The application must go into Normal Mode, setting Mode to 0 in the Mode 00199 Register and perform a write access at any location in the SDRAM to 00200 acknowledge this command. */ 00201 SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL; 00202 *(uint16_t *)(EBI_SDRAMC_ADDR) = 0x0; 00203 00204 /* Step 11. */ 00205 /* Write the refresh rate into the count field in the SDRAMC Refresh 00206 Timer register. Set Refresh timer 15.625 us*/ 00207 dw = dwClockFrequency / 1000u; 00208 dw *= 15625u; 00209 dw /= 1000000u; 00210 SDRAMC->SDRAMC_TR = SDRAMC_TR_COUNT(dw); 00211 } 00212