rt-thread/bsp/nxp/imx/imxrt/libraries/drivers/drv_sdram.c

154 lines
4.7 KiB
C
Raw Normal View History

2019-06-12 15:01:12 +08:00
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <rtthread.h>
#ifdef BSP_USING_SDRAM
#include "sdram_port.h"
#include "board.h"
#include "fsl_semc.h"
#include "drv_sdram.h"
//#define DBG_COLOR
//#define DRV_DEBUG
//#define LOG_TAG "drv.sdram"
//#include <drv_log.h>
#define DBG_ENABLE
#define DBG_SECTION_NAME "[drv.sdram]"
#define DBG_COLOR
#define DBG_LEVEL DBG_INFO
#include <rtdbg.h>
2019-06-12 15:01:12 +08:00
#ifdef RT_USING_MEMHEAP
2019-06-12 15:01:12 +08:00
static struct rt_memheap system_heap;
#endif
2022-08-15 21:24:53 +08:00
int rt_hw_sdram_init(void)
2019-06-12 15:01:12 +08:00
{
int result = RT_EOK;
semc_config_t config;
semc_sdram_config_t sdramconfig;
#if defined(SOC_IMXRT1170_SERIES)
rt_uint32_t clockFrq = CLOCK_GetRootClockFreq(kCLOCK_Root_Semc);
#else
2019-06-12 15:01:12 +08:00
rt_uint32_t clockFrq = CLOCK_GetFreq(kCLOCK_SemcClk);
#endif
2019-06-12 15:01:12 +08:00
/* Initializes the MAC configure structure to zero. */
rt_memset(&config, 0, sizeof(semc_config_t));
rt_memset(&sdramconfig, 0, sizeof(semc_sdram_config_t));
2022-01-26 12:24:09 +08:00
2019-06-12 15:01:12 +08:00
/* Initialize SEMC. */
SEMC_GetDefaultConfig(&config);
config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
SEMC_Init(SEMC, &config);
/* Configure SDRAM. */
sdramconfig.csxPinMux = SDRAM_CS_PIN;
sdramconfig.address = SDRAM_BANK_ADDR;
sdramconfig.memsize_kbytes = SDRAM_SIZE;
sdramconfig.portSize = SDRAM_DATA_WIDTH;
sdramconfig.burstLen = kSEMC_Sdram_BurstLen8;
sdramconfig.columnAddrBitNum = SDRAM_COLUMN_BITS;
sdramconfig.casLatency = SDRAM_CAS_LATENCY;
sdramconfig.tPrecharge2Act_Ns = SDRAM_TRP;
sdramconfig.tAct2ReadWrite_Ns = SDRAM_TRCD;
sdramconfig.tRefreshRecovery_Ns = SDRAM_REFRESH_RECOVERY;
sdramconfig.tWriteRecovery_Ns = SDRAM_TWR;
sdramconfig.tCkeOff_Ns = 42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
sdramconfig.tAct2Prechage_Ns = SDRAM_TRAS;
sdramconfig.tSelfRefRecovery_Ns = 67;
sdramconfig.tRefresh2Refresh_Ns = SDRAM_TRC;
sdramconfig.tAct2Act_Ns = SDRAM_ACT2ACT;
sdramconfig.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq);
sdramconfig.refreshPeriod_nsPerRow = SDRAM_REFRESH_ROW;
sdramconfig.refreshUrgThreshold = sdramconfig.refreshPeriod_nsPerRow;
sdramconfig.refreshBurstLen = 1;
result = SEMC_ConfigureSDRAM(SEMC, SDRAM_REGION, &sdramconfig, clockFrq);
if(result != kStatus_Success)
{
LOG_E("SDRAM init failed!");
result = -RT_ERROR;
}
else
{
LOG_I("sdram init success, mapped at 0x%X, size is %d Kbytes.", SDRAM_BANK_ADDR, SDRAM_SIZE);
#ifdef RT_USING_MEMHEAP
2022-01-26 12:24:09 +08:00
/*
* If RT_USING_MEMHEAP is enabled, SDRAM is initialized to the heap.
2022-01-26 12:24:09 +08:00
* The heap start address is (base + half size), and the size is (half size - 2M).
* The reasons are:
* 1. Reserve the half space for SDRAM link case
* 2. Reserve the 2M for non-cache space
*/
rt_memheap_init(&system_heap, "sdram", (void *)(SDRAM_BANK_ADDR + (SDRAM_SIZE * 1024)/2),
2022-01-26 12:24:09 +08:00
(SDRAM_SIZE * 1024)/2 - (2 * 1024 * 1024));
2019-06-12 15:01:12 +08:00
#endif
}
2022-01-26 12:24:09 +08:00
2019-06-12 15:01:12 +08:00
return result;
}
INIT_PREV_EXPORT(rt_hw_sdram_init);
2019-06-12 15:01:12 +08:00
#ifdef DBG_ENABLE
2019-06-12 15:01:12 +08:00
#ifdef FINSH_USING_MSH
#define SEMC_DATALEN (0x1000U)
rt_uint32_t sdram_writeBuffer[SEMC_DATALEN];
rt_uint32_t sdram_readBuffer[SEMC_DATALEN];
/* read write 32bit test */
static void sdram_test(void)
2019-06-12 15:01:12 +08:00
{
rt_uint32_t index;
rt_uint32_t datalen = SEMC_DATALEN;
rt_uint32_t *sdram = (rt_uint32_t *)SDRAM_BANK_ADDR; /* SDRAM start address. */
bool result = true;
2022-08-15 21:24:53 +08:00
LOG_D("SEMC SDRAM Memory 32 bit Write Start, Start Address 0x%x, Data Length %d !", sdram, datalen);
2019-06-12 15:01:12 +08:00
/* Prepare data and write to SDRAM. */
for (index = 0; index < datalen; index++)
{
sdram_writeBuffer[index] = index;
sdram[index] = sdram_writeBuffer[index];
}
2022-08-15 21:24:53 +08:00
LOG_D("SEMC SDRAM Read 32 bit Data Start, Start Address 0x%x, Data Length %d !", sdram, datalen);
2019-06-12 15:01:12 +08:00
/* Read data from the SDRAM. */
for (index = 0; index < datalen; index++)
{
sdram_readBuffer[index] = sdram[index];
}
LOG_I("SEMC SDRAM 32 bit Data Write and Read Compare Start!");
2019-06-12 15:01:12 +08:00
/* Compare the two buffers. */
while (datalen--)
{
if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen])
{
result = false;
break;
}
}
if (!result)
{
2022-08-15 21:24:53 +08:00
LOG_E("SEMC SDRAM 32 bit Data Write and Read Compare Failed!");
2019-06-12 15:01:12 +08:00
}
else
{
LOG_I("SEMC SDRAM 32 bit Data Write and Read Compare Succeed!");
2019-06-12 15:01:12 +08:00
}
}
MSH_CMD_EXPORT(sdram_test, sdram test)
#endif /* DRV_DEBUG */
#endif /* FINSH_USING_MSH */
#endif /* BSP_USING_SDRAM */