diff --git a/arch/arm/src/lpc54xx/lpc54_emc.c b/arch/arm/src/lpc54xx/lpc54_emc.c index 98ccb49095..2b85d19a0c 100644 --- a/arch/arm/src/lpc54xx/lpc54_emc.c +++ b/arch/arm/src/lpc54xx/lpc54_emc.c @@ -46,6 +46,7 @@ #include #include +#include #include @@ -293,6 +294,8 @@ void lpc54_emc_sdram_initialize(FAR struct emc_dynamic_timing_config_s *timing, unsigned int i; volatile unsigned int j; + DEBUGASSERT(timing != NULL && chconfig != NULL && nchips > 0); + /* Setting for dynamic memory controller chip independent configuration */ for (i = 0, config = chconfig; @@ -457,4 +460,81 @@ void lpc54_emc_sdram_initialize(FAR struct emc_dynamic_timing_config_s *timing, } #endif /* CONFIG_LPC54_EMC_DYNAMIC */ +/**************************************************************************** + * Name: lpc54_emc_sram_initialize + * + * Description: + * This function initializes the static memory controller in external + * memory controller. This function must be called after lpc54_emc_initialize + * and before accessing the external dynamic memory. + * + * Input Parameters: + * extwait - The extended wait timeout or the read/write transfer time. + * This is common for all static memory chips and set with + * NULL if not required. + * statconfig - The EMC static memory controller chip independent + * configuration array. The dimension of the array is nchips. + * nchips - The total static memory chip numbers been used and the + * number of entries in the statconfig array. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC54_EMC_STATIC +void lpc54_emc_sram_initialize(FAR uint32_t *extwait, + FAR const struct emc_static_chip_config_s *statconfig, + uint32_t nchips) +{ + FAR const struct emc_static_chip_config_s *config; + uint32_t regval; + unsigned int i; + + /* Initialize extended wait. */ + + DEBUGASSERT(statconfig != NULL && nchips > 0); + + if (extwait) + { +#ifdef CONFIG_DEBUG_ASSERTIONS + for (i = 0, config = statconfig; + i < nchips && config != NULL; i++, + config++) + { + DEBUGASSERT(config->specconfig & EMC_ASYNCPAGEENABLE); + } +#endif + + regval = lpc54_emc_timercycles(*extwait, 1, 1024); + putreg32(EMC_STATEXTWAIT(regval), LPC54_EMC_STATEXTWAIT); + } + + /* Initialize the static memory chip specific configure. */ + + for (i = 0, config = statconfig; + i < nchips && config != NULL; i++, + config++) + { + regval = config->specconfig | config->memwidth; + putreg32(regval, LPC54_EMC_STATCONFIG(config->chndx)); + + regval = lpc54_emc_timercycles(config->waitwriteen, 1, 16); + putreg32(EMC_STATWAITWEN(regval), LPC54_EMC_STATWAITWEN(config->chndx)); + + regval = lpc54_emc_timercycles(config->waitouten, 0, 15); + putreg32(EMC_STATWAITOEN(regval), LPC54_EMC_STATWAITOEN(config->chndx)); + + regval = lpc54_emc_timercycles(config->waitread, 1, 32); + putreg32(EMC_STATWAITRD(regval), LPC54_EMC_STATWAITRD(config->chndx)); + + regval = lpc54_emc_timercycles(config->waitreadpage, 1, 32); + putreg32(EMC_STATWAITPAGE(regval), LPC54_EMC_STATWAITPAGE(config->chndx)); + + regval = lpc54_emc_timercycles(config->waitwrite, 2, 33); + putreg32(EMC_STATWAITWR(regval), LPC54_EMC_STATWAITWR(config->chndx)); + + regval = lpc54_emc_timercycles(config->waitturn, 1, 16); + putreg32(EMC_STATWAITTURN(regval), LPC54_EMC_STATWAITTURN(config->chndx)); + } +} +#endif /* CONFIG_LPC54_EMC_STATIC */ + #endif /* CONFIG_LPC54_EMC */ diff --git a/arch/arm/src/lpc54xx/lpc54_emc.h b/arch/arm/src/lpc54xx/lpc54_emc.h index 15d82ab7f2..cd17ac0b61 100644 --- a/arch/arm/src/lpc54xx/lpc54_emc.h +++ b/arch/arm/src/lpc54xx/lpc54_emc.h @@ -72,11 +72,11 @@ enum emc_fbclksrc_e struct emc_config_s { bool bigendian; /* True: Memory is big-endian */ - uint8_t clksrc; /* The feedback clock source. */ + uint8_t clksrc; /* The feedback clock source */ uint8_t clkdiv; /* EMC_CLK = AHB_CLK / (emc_clkDiv + 1). */ }; -/* EMC dynamic read strategy. */ +/* EMC dynamic read strategy */ enum emc_dynamic_read_e { @@ -88,7 +88,7 @@ enum emc_dynamic_read_e * using EMCCLKDELAY */ }; -/* EMC dynamic timing/delay configure structure. */ +/* EMC dynamic timing/delay configure structure */ struct emc_dynamic_timing_config_s { @@ -103,7 +103,7 @@ struct emc_dynamic_timing_config_s uint32_t dal; /* Data-in to active command in units of nanoseconds */ uint32_t wr; /* Write recovery time in unit of nanosecond */ uint32_t rc; /* Active to active command period in units of - * nanoseconds. */ + * nanoseconds */ uint32_t rfc; /* Auto-refresh period and auto-refresh to active * command period in unit of nanosecond */ uint32_t xsr; /* Exit self-refresh to active command time in units @@ -114,30 +114,74 @@ struct emc_dynamic_timing_config_s * of EMCCLK cycles */ }; -/* EMC dynamic memory device. */ +/* EMC dynamic memory device */ enum emc_dynamic_device_e { - EMC_SDRAM = 0, /* Dynamic memory device: SDRAM. */ - EMC_LPSDRAM /* Dynamic memory device: Low-power SDRAM. */ + EMC_SDRAM = 0, /* Dynamic memory device: SDRAM */ + EMC_LPSDRAM /* Dynamic memory device: Low-power SDRAM */ }; /* EMC dynamic memory controller independent chip configuration structure */ struct emc_dynamic_chip_config_s { - uint8_t chndx; /* Chip Index, range from 0 ~ EMC_DYNAMIC_MEMDEV_NUM - 1. */ + uint8_t chndx; /* Chip Index, range from 0 ~ EMC_DYNAMIC_MEMDEV_NUM - 1 */ uint8_t dyndev; /* All chips shall use the same device setting. mixed - * use are not supported. */ - uint8_t rasnclk; /* Active to read/write delay tRCD. */ - uint16_t mode; /* Sdram mode register setting. */ + * use are not supported */ + uint8_t rasnclk; /* Active to read/write delay tRCD */ + uint16_t mode; /* Sdram mode register setting */ uint16_t extmode; /* Used for low-power sdram device. The extended mode - * register. */ + * register */ uint8_t addrmap; /* Dynamic device address mapping, choose the address - * mapping for your specific device. */ + * mapping for your specific device */ }; -/**************************************************************************** +/* EMC memory width for static memory device */ + +enum emc_static_memwidth_e +{ + EMC_WIDTH_8BIT = 0, /* 8 bit memory width */ + EMC_WIDTH_16BIT, /* 16 bit memory width */ + EMC_WIDTH_32BIT /* 32 bit memory width */ +}; + +/* Define EMC static "special" configuration */ + +enum emc_static_special_config_e +{ + EMC_ASYNCPAGEENABLE = 0x00000008, /* Enable the asynchronous page mode. + * page length four */ + EMC_ACTIVEHIGHCS = 0x00000040, /* Chip select active high */ + EMC_BYTELANELOW = 0x00000080, /* Reads/writes the respective value + * bits in BLS3:0 are low */ + EMC_EXTWAITENABLE = 0x00000100, /* Extended wait enable */ + EMC_BUFFERENABLE = 0x00080000 /* Buffer enable */ +}; + +/* EMC static memory controller independent chip configuration structure */ + +struct emc_static_chip_config_s +{ + uint8_t chndx; + uint8_t memwidth; /* Memory width */ + uint32_t specconfig; /* Static configuration, OR of enum + * emc_static_special_config_e settings */ + uint32_t waitwriteen; /* The delay form chip select to write enable in + * units of nanoseconds */ + uint32_t waitouten; /* The delay from chip selcet to output enable in + * units of nanoseconds */ + uint32_t waitread; /* In No-page mode, the delay from chip select to + * read access in units of nanoseconds */ + uint32_t waitreadpage; /* In page mode, the read after the first read + * wait states in units of nanoseconds */ + uint32_t waitwrite; /* The delay from chip select to write access in + * units of nanoseconds */ + uint32_t waitturn; /* The Bus turn-around time in units of + * nanoseconds */ +}; + +/*************************************************************************** * Public Functions ****************************************************************************/ @@ -182,5 +226,30 @@ void lpc54_emc_sdram_initialize(FAR struct emc_dynamic_timing_config_s *timing, unsigned int nchips); #endif /* CONFIG_LPC54_EMC_DYNAMIC */ +/**************************************************************************** + * Name: lpc54_emc_sram_initialize + * + * Description: + * This function initializes the static memory controller in external + * memory controller. This function must be called after lpc54_emc_initialize + * and before accessing the external dynamic memory. + * + * Input Parameters: + * extwait - The extended wait timeout or the read/write transfer time. + * This is common for all static memory chips and set with + * NULL if not required. + * statconfig - The EMC static memory controller chip independent + * configuration array. The dimension of the array is nchips. + * nchips - The total static memory chip numbers been used and the + * number of entries in the statconfig array. + * + ****************************************************************************/ + +#ifdef CONFIG_LPC54_EMC_STATIC +void lpc54_emc_sram_initialize(FAR uint32_t *extwait, + FAR const struct emc_static_chip_config_s *statconfig, + uint32_t nchips); +#endif /* CONFIG_LPC54_EMC_STATIC */ + #endif /* CONFIG_LPC54_EMC */ #endif /* __ARCH_ARM_SRC_LPC54XX_LPC54_EMC_H */ diff --git a/configs/lpcxpresso-lpc54628/README.txt b/configs/lpcxpresso-lpc54628/README.txt index 78b30a20b3..6caaabc673 100644 --- a/configs/lpcxpresso-lpc54628/README.txt +++ b/configs/lpcxpresso-lpc54628/README.txt @@ -28,7 +28,8 @@ STATUS ====== 2017-12-10: The basic NSH configuration is functional at 220MHz with a - Serial console, timer and LED support. + Serial console, timer and LED support. Added support for the external + SDRAM and for the RAM test utility. Configurations ============== @@ -104,3 +105,7 @@ Configurations Application Configuration: CONFIG_NSH_BUILTIN_APPS=y : Enable starting apps from NSH command line + + 2. SDRAM support is enabled, but the SDRAM is *not* added to the system + heap. The apps/system/ramtest utility is include in the build as an + NSH builtin function that can be used to verify the SDRAM. diff --git a/configs/lpcxpresso-lpc54628/nsh/defconfig b/configs/lpcxpresso-lpc54628/nsh/defconfig index 47d9885229..934c536544 100644 --- a/configs/lpcxpresso-lpc54628/nsh/defconfig +++ b/configs/lpcxpresso-lpc54628/nsh/defconfig @@ -13,7 +13,6 @@ CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y -CONFIG_LPC54_EMC_DYNAMIC=y CONFIG_LPC54_EMC=y CONFIG_LPC54_USART0=y CONFIG_MAX_TASKS=16 @@ -38,6 +37,7 @@ CONFIG_SDCLONE_DISABLE=y CONFIG_START_DAY=2 CONFIG_START_MONTH=12 CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_RAMTEST=y CONFIG_TASK_NAME_SIZE=0 CONFIG_USART0_SERIAL_CONSOLE=y CONFIG_USER_ENTRYPOINT="nsh_main"