in lib/nxp/drivers/fsl_emc.c [229:364]
void EMC_DynamicMemInit(EMC_Type *base,
emc_dynamic_timing_config_t *timing,
emc_dynamic_chip_config_t *config,
uint32_t totalChips)
{
assert(NULL != config);
assert(NULL != timing);
assert(totalChips <= EMC_DYNAMIC_MEMDEV_NUM);
uint32_t count;
uint32_t casLatency;
uint32_t addr;
uint32_t offset;
uint32_t data;
emc_dynamic_chip_config_t *dynamicConfig = config;
/* Setting for dynamic memory controller chip independent configuration. */
for (count = 0; (count < totalChips); count++)
{
if (NULL == dynamicConfig)
{
break;
}
else
{
base->DYNAMIC[dynamicConfig->chipIndex].DYNAMICCONFIG =
EMC_DYNAMIC_DYNAMICCONFIG_MD(dynamicConfig->dynamicDevice) | EMC_ADDRMAP(dynamicConfig->devAddrMap);
/* Abstract CAS latency from the sdram mode reigster setting values. */
casLatency = ((uint32_t)dynamicConfig->sdramModeReg & EMC_SDRAM_MODE_CL_MASK) >> EMC_SDRAM_MODE_CL_SHIFT;
base->DYNAMIC[dynamicConfig->chipIndex].DYNAMICRASCAS =
EMC_DYNAMIC_DYNAMICRASCAS_RAS(dynamicConfig->rAS_Nclk) | EMC_DYNAMIC_DYNAMICRASCAS_CAS(casLatency);
dynamicConfig++;
}
}
/* Configure the Dynamic Memory controller timing/latency for all chips. */
base->DYNAMICREADCONFIG = EMC_DYNAMICREADCONFIG_RD(timing->readConfig);
base->DYNAMICRP = EMC_CalculateTimerCycles(base, timing->tRp_Ns, 1) & EMC_DYNAMICRP_TRP_MASK;
base->DYNAMICRAS = EMC_CalculateTimerCycles(base, timing->tRas_Ns, 1) & EMC_DYNAMICRAS_TRAS_MASK;
base->DYNAMICSREX = EMC_CalculateTimerCycles(base, timing->tSrex_Ns, 1) & EMC_DYNAMICSREX_TSREX_MASK;
base->DYNAMICAPR = EMC_CalculateTimerCycles(base, timing->tApr_Ns, 1) & EMC_DYNAMICAPR_TAPR_MASK;
base->DYNAMICDAL = EMC_CalculateTimerCycles(base, timing->tDal_Ns, 0) & EMC_DYNAMICDAL_TDAL_MASK;
base->DYNAMICWR = EMC_CalculateTimerCycles(base, timing->tWr_Ns, 1) & EMC_DYNAMICWR_TWR_MASK;
base->DYNAMICRC = EMC_CalculateTimerCycles(base, timing->tRc_Ns, 1) & EMC_DYNAMICRC_TRC_MASK;
base->DYNAMICRFC = EMC_CalculateTimerCycles(base, timing->tRfc_Ns, 1) & EMC_DYNAMICRFC_TRFC_MASK;
base->DYNAMICXSR = EMC_CalculateTimerCycles(base, timing->tXsr_Ns, 1) & EMC_DYNAMICXSR_TXSR_MASK;
base->DYNAMICRRD = EMC_CalculateTimerCycles(base, timing->tRrd_Ns, 1) & EMC_DYNAMICRRD_TRRD_MASK;
base->DYNAMICMRD = EMC_DYNAMICMRD_TMRD((timing->tMrd_Nclk > 0U) ? timing->tMrd_Nclk - 1UL : 0UL);
SDK_DelayAtLeastUs(EMC_SDRAM_NOP_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
/* Step 2. issue nop command. */
base->DYNAMICCONTROL = 0x00000183;
SDK_DelayAtLeastUs(EMC_SDRAM_PRECHARGE_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
/* Step 3. issue precharge all command. */
base->DYNAMICCONTROL = 0x00000103;
/* Step 4. issue two auto-refresh command. */
base->DYNAMICREFRESH = 2;
SDK_DelayAtLeastUs(EMC_SDRAM_AUTO_REFRESH_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
base->DYNAMICREFRESH = EMC_CalculateTimerCycles(base, timing->refreshPeriod_Nanosec, 0) / EMC_REFRESH_CLOCK_PARAM;
/* Step 5. issue a mode command and set the mode value. */
base->DYNAMICCONTROL = 0x00000083;
/* Calculate the mode settings here and to reach the 8 auto-refresh time requirement. */
dynamicConfig = config;
for (count = 0; (count < totalChips); count++)
{
if (NULL == dynamicConfig)
{
break;
}
else
{
/* Get the shift value first. */
offset = EMC_ModeOffset(dynamicConfig->devAddrMap);
addr = (s_EMCDYCSBases[dynamicConfig->chipIndex] |
((uint32_t)(dynamicConfig->sdramModeReg & ~EMC_SDRAM_BANKCS_BA_MASK) << offset));
/* Set the right mode setting value. */
data = *(volatile uint32_t *)addr;
data = data;
dynamicConfig++;
}
}
if (kEMC_Sdram != config->dynamicDevice)
{
/* Add extended mode register if the low-power sdram is used. */
base->DYNAMICCONTROL = 0x00000083;
/* Calculate the mode settings for extended mode register. */
dynamicConfig = config;
for (count = 0; (count < totalChips); count++)
{
if (NULL == dynamicConfig)
{
break;
}
else
{
/* Get the shift value first. */
offset = EMC_ModeOffset(dynamicConfig->devAddrMap);
addr = (s_EMCDYCSBases[dynamicConfig->chipIndex] |
(((uint32_t)(dynamicConfig->sdramExtModeReg & ~EMC_SDRAM_BANKCS_BA_MASK) |
EMC_SDRAM_BANKCS_BA1_MASK)
<< offset));
/* Set the right mode setting value. */
data = *(volatile uint32_t *)addr;
data = data;
dynamicConfig++;
}
}
}
/* Step 6. issue normal operation command. */
base->DYNAMICCONTROL = 0x00000000; /* Issue NORMAL command */
/* The buffer shall be disabled when do the sdram initialization and
* enabled after the initialization during normal opeation.
*/
dynamicConfig = config;
for (count = 0; (count < totalChips); count++)
{
if (NULL == dynamicConfig)
{
break;
}
else
{
base->DYNAMIC[dynamicConfig->chipIndex].DYNAMICCONFIG |= EMC_DYNAMIC_DYNAMICCONFIG_B_MASK;
dynamicConfig++;
}
}
}