void EMC_DynamicMemInit()

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++;
        }
    }
}