2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
\r
3 * Copyright 2016-2019 NXP
\r
4 * All rights reserved.
\r
6 * SPDX-License-Identifier: BSD-3-Clause
\r
11 #include "fsl_common.h"
\r
18 /*******************************************************************************
\r
20 ******************************************************************************/
\r
22 /*! @name Driver version */
\r
24 /*! @brief EMC driver version. */
\r
25 #define FSL_EMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
\r
28 /*! @brief Define the chip numbers for dynamic and static memory devices. */
\r
29 #define EMC_STATIC_MEMDEV_NUM (4U)
\r
30 #define EMC_DYNAMIC_MEMDEV_NUM (4U)
\r
31 #define EMC_ADDRMAP_SHIFT EMC_DYNAMIC_DYNAMICCONFIG_AM0_SHIFT
\r
32 #define EMC_ADDRMAP_MASK (EMC_DYNAMIC_DYNAMICCONFIG_AM0_MASK | EMC_DYNAMIC_DYNAMICCONFIG_AM1_MASK)
\r
33 #define EMC_ADDRMAP(x) (((uint32_t)(((uint32_t)(x)) << EMC_ADDRMAP_SHIFT)) & EMC_ADDRMAP_MASK)
\r
34 #define EMC_HZ_ONEMHZ (1000000U)
\r
35 #define EMC_MILLISECS_ONESEC (1000U)
\r
36 #define EMC_SDRAM_MODE_CL_SHIFT (4U)
\r
37 #define EMC_SDRAM_MODE_CL_MASK (0x70U)
\r
38 /*! @brief EDMA_SDRAM NOP command wait us */
\r
39 #ifndef EMC_SDRAM_NOP_DELAY_US
\r
40 #define EMC_SDRAM_NOP_DELAY_US (100U)
\r
42 /*! @brief EDMA_SDRAM precharge command wait us */
\r
43 #ifndef EMC_SDRAM_PRECHARGE_DELAY_US
\r
44 #define EMC_SDRAM_PRECHARGE_DELAY_US (100U)
\r
46 /*! @brief EDMA_SDRAM auto refresh wait us */
\r
47 #ifndef EMC_SDRAM_AUTO_REFRESH_DELAY_US
\r
48 #define EMC_SDRAM_AUTO_REFRESH_DELAY_US (50U)
\r
51 * @brief Define EMC memory width for static memory device.
\r
53 typedef enum _emc_static_memwidth
\r
55 kEMC_8BitWidth = 0x0U, /*!< 8 bit memory width. */
\r
56 kEMC_16BitWidth, /*!< 16 bit memory width. */
\r
57 kEMC_32BitWidth /*!< 32 bit memory width. */
\r
58 } emc_static_memwidth_t;
\r
61 * @brief Define EMC static configuration.
\r
63 typedef enum _emc_static_special_config
\r
65 kEMC_AsynchronosPageEnable = 0x0008U, /*!< Enable the asynchronous page mode. page length four. */
\r
66 kEMC_ActiveHighChipSelect = 0x0040U, /*!< Chip select active high. */
\r
67 kEMC_ByteLaneStateAllLow = 0x0080U, /*!< Reads/writes the respective valuie bits in BLS3:0 are low. */
\r
68 kEMC_ExtWaitEnable = 0x0100U, /*!< Extended wait enable. */
\r
69 kEMC_BufferEnable = 0x80000U /*!< Buffer enable. */
\r
70 } emc_static_special_config_t;
\r
72 /*! @brief EMC dynamic memory device. */
\r
73 typedef enum _emc_dynamic_device
\r
75 kEMC_Sdram = 0x0U, /*!< Dynamic memory device: SDRAM. */
\r
76 kEMC_Lpsdram, /*!< Dynamic memory device: Low-power SDRAM. */
\r
77 } emc_dynamic_device_t;
\r
79 /*! @brief EMC dynamic read strategy. */
\r
80 typedef enum _emc_dynamic_read
\r
82 kEMC_NoDelay = 0x0U, /*!< No delay. */
\r
83 kEMC_Cmddelay, /*!< Command delayed strategy, using EMCCLKDELAY. */
\r
84 kEMC_CmdDelayPulseOneclk, /*!< Command delayed strategy pluse one clock cycle using EMCCLKDELAY. */
\r
85 kEMC_CmddelayPulsetwoclk, /*!< Command delayed strategy pulse two clock cycle using EMCCLKDELAY. */
\r
86 } emc_dynamic_read_t;
\r
88 /*! @brief EMC endian mode. */
\r
89 typedef enum _emc_endian_mode
\r
91 kEMC_LittleEndian = 0x0U, /*!< Little endian mode. */
\r
92 kEMC_BigEndian, /*!< Big endian mode. */
\r
93 } emc_endian_mode_t;
\r
95 /*! @brief EMC Feedback clock input source select. */
\r
96 typedef enum _emc_fbclk_src
\r
98 kEMC_IntloopbackEmcclk = 0U, /*!< Use the internal loop back from EMC_CLK output. */
\r
99 kEMC_EMCFbclkInput /*!< Use the external EMC_FBCLK input. */
\r
102 /*! @brief EMC dynamic timing/delay configure structure. */
\r
103 typedef struct _emc_dynamic_timing_config
\r
105 emc_dynamic_read_t readConfig; /* Dynamic read strategy. */
\r
106 uint32_t refreshPeriod_Nanosec; /*!< The refresh period in unit of nanosecond. */
\r
107 uint32_t tRp_Ns; /*!< Precharge command period in unit of nanosecond. */
\r
108 uint32_t tRas_Ns; /*!< Active to precharge command period in unit of nanosecond. */
\r
109 uint32_t tSrex_Ns; /*!< Self-refresh exit time in unit of nanosecond. */
\r
110 uint32_t tApr_Ns; /*!< Last data out to active command time in unit of nanosecond. */
\r
111 uint32_t tDal_Ns; /*!< Data-in to active command in unit of nanosecond. */
\r
112 uint32_t tWr_Ns; /*!< Write recovery time in unit of nanosecond. */
\r
113 uint32_t tRc_Ns; /*!< Active to active command period in unit of nanosecond. */
\r
114 uint32_t tRfc_Ns; /*!< Auto-refresh period and auto-refresh to active command period in unit of nanosecond. */
\r
115 uint32_t tXsr_Ns; /*!< Exit self-refresh to active command time in unit of nanosecond. */
\r
116 uint32_t tRrd_Ns; /*!< Active bank A to active bank B latency in unit of nanosecond. */
\r
117 uint8_t tMrd_Nclk; /*!< Load mode register to active command time in unit of EMCCLK cycles.*/
\r
118 } emc_dynamic_timing_config_t;
\r
121 * @brief EMC dynamic memory controller independent chip configuration structure.
\r
122 * Please take refer to the address mapping table in the RM in EMC chapter when you
\r
123 * set the "devAddrMap". Choose the right Bit 14 Bit12 ~ Bit 7 group in the table
\r
124 * according to the bus width/banks/row/colum length for you device.
\r
125 * Set devAddrMap with the value make up with the seven bits (bit14 bit12 ~ bit 7)
\r
126 * and inset the bit 13 with 0.
\r
127 * for example, if the bit 14 and bit12 ~ bit7 is 1000001 is choosen according to the
\r
128 * 32bit high-performance bus width with 2 banks, 11 row lwngth, 8 column length.
\r
129 * Set devAddrMap with 0x81.
\r
131 typedef struct _emc_dynamic_chip_config
\r
133 uint8_t chipIndex; /*!< Chip Index, range from 0 ~ EMC_DYNAMIC_MEMDEV_NUM - 1. */
\r
134 emc_dynamic_device_t
\r
135 dynamicDevice; /*!< All chips shall use the same device setting. mixed use are not supported. */
\r
136 uint8_t rAS_Nclk; /*!< Active to read/write delay tRCD. */
\r
137 uint16_t sdramModeReg; /*!< Sdram mode register setting. */
\r
138 uint16_t sdramExtModeReg; /*!< Used for low-power sdram device. The extended mode register. */
\r
139 uint8_t devAddrMap; /*!< dynamic device address mapping, choose the address mapping for your specific device. */
\r
140 } emc_dynamic_chip_config_t;
\r
143 * @brief EMC static memory controller independent chip configuration structure.
\r
145 typedef struct _emc_static_chip_config
\r
148 emc_static_memwidth_t memWidth; /*!< Memory width. */
\r
149 uint32_t specailConfig; /*!< Static configuration,a logical OR of "emc_static_special_config_t". */
\r
150 uint32_t tWaitWriteEn_Ns; /*!< The delay form chip select to write enable in unit of nanosecond. */
\r
151 uint32_t tWaitOutEn_Ns; /*!< The delay from chip selcet to output enable in unit of nanosecond. */
\r
153 tWaitReadNoPage_Ns; /*!< In No-page mode, the delay from chip select to read access in unit of nanosecond. */
\r
154 uint32_t tWaitReadPage_Ns; /*!< In page mode, the read after the first read wait states in unit of nanosecond. */
\r
155 uint32_t tWaitWrite_Ns; /*!< The delay from chip select to write access in unit of nanosecond. */
\r
156 uint32_t tWaitTurn_Ns; /*!< The Bus turn-around time in unit of nanosecond. */
\r
157 } emc_static_chip_config_t;
\r
160 * @brief EMC module basic configuration structure.
\r
162 * Defines the static memory controller configure structure and
\r
163 * uses the EMC_Init() function to make necessary initializations.
\r
166 typedef struct _emc_basic_config
\r
168 emc_endian_mode_t endian; /*!< Endian mode . */
\r
169 emc_fbclk_src_t fbClkSrc; /*!< The feedback clock source. */
\r
170 uint8_t emcClkDiv; /*!< EMC_CLK = AHB_CLK / (emc_clkDiv + 1). */
\r
171 } emc_basic_config_t;
\r
173 /*******************************************************************************
\r
175 ******************************************************************************/
\r
177 #if defined(__cplusplus)
\r
182 * @name EMC Initialize and de-initialize opeartion
\r
186 * @brief Initializes the basic for EMC.
\r
187 * This function ungates the EMC clock, initializes the emc system configure
\r
188 * and enable the EMC module. This function must be called in the first step to initialize
\r
189 * the external memory.
\r
191 * @param base EMC peripheral base address.
\r
192 * @param config The EMC basic configuration.
\r
194 void EMC_Init(EMC_Type *base, emc_basic_config_t *config);
\r
197 * @brief Initializes the dynamic memory controller.
\r
198 * This function initializes the dynamic memory controller in external memory controller.
\r
199 * This function must be called after EMC_Init and before accessing the external dynamic memory.
\r
201 * @param base EMC peripheral base address.
\r
202 * @param timing The timing and latency for dynamica memory controller setting. It shall
\r
203 * be used for all dynamica memory chips, threfore the worst timing value for all
\r
204 * used chips must be given.
\r
205 * @param configure The EMC dynamic memory controller chip independent configuration pointer.
\r
206 * This configuration pointer is actually pointer to a configration array. the array number
\r
207 * depends on the "totalChips".
\r
208 * @param totalChips The total dynamic memory chip numbers been used or the length of the
\r
209 * "emc_dynamic_chip_config_t" type memory.
\r
211 void EMC_DynamicMemInit(EMC_Type *base,
\r
212 emc_dynamic_timing_config_t *timing,
\r
213 emc_dynamic_chip_config_t *config,
\r
214 uint32_t totalChips);
\r
217 * @brief Initializes the static memory controller.
\r
218 * This function initializes the static memory controller in external memory controller.
\r
219 * This function must be called after EMC_Init and before accessing the external static memory.
\r
221 * @param base EMC peripheral base address.
\r
222 * @param extWait_Ns The extended wait timeout or the read/write transfer time.
\r
223 * This is common for all static memory chips and set with NULL if not required.
\r
224 * @param configure The EMC static memory controller chip independent configuration pointer.
\r
225 * This configuration pointer is actually pointer to a configration array. the array number
\r
226 * depends on the "totalChips".
\r
227 * @param totalChips The total static memory chip numbers been used or the length of the
\r
228 * "emc_static_chip_config_t" type memory.
\r
230 void EMC_StaticMemInit(EMC_Type *base, uint32_t *extWait_Ns, emc_static_chip_config_t *config, uint32_t totalChips);
\r
233 * @brief Deinitializes the EMC module and gates the clock.
\r
234 * This function gates the EMC controller clock. As a result, the EMC
\r
235 * module doesn't work after calling this function.
\r
237 * @param base EMC peripheral base address.
\r
239 void EMC_Deinit(EMC_Type *base);
\r
244 * @name EMC Basic Operation
\r
249 * @brief Enables/disables the EMC module.
\r
251 * @param base EMC peripheral base address.
\r
252 * @param enable True enable EMC module, false disable.
\r
254 static inline void EMC_Enable(EMC_Type *base, bool enable)
\r
258 base->CONTROL |= EMC_CONTROL_E_MASK;
\r
262 base->CONTROL &= ~EMC_CONTROL_E_MASK;
\r
267 * @brief Enables/disables the EMC Dynaimc memory controller.
\r
269 * @param base EMC peripheral base address.
\r
270 * @param enable True enable EMC dynamic memory controller, false disable.
\r
272 static inline void EMC_EnableDynamicMemControl(EMC_Type *base, bool enable)
\r
276 base->DYNAMICCONTROL |= (EMC_DYNAMICCONTROL_CE_MASK | EMC_DYNAMICCONTROL_CS_MASK);
\r
280 base->DYNAMICCONTROL &= ~(EMC_DYNAMICCONTROL_CE_MASK | EMC_DYNAMICCONTROL_CS_MASK);
\r
285 * @brief Enables/disables the EMC address mirror.
\r
286 * Enable the address mirror the EMC_CS1is mirrored to both EMC_CS0
\r
287 * and EMC_DYCS0 memory areas. Disable the address mirror enables
\r
288 * EMC_cS0 and EMC_DYCS0 memory to be accessed.
\r
290 * @param base EMC peripheral base address.
\r
291 * @param enable True enable the address mirror, false disable the address mirror.
\r
293 static inline void EMC_MirrorChipAddr(EMC_Type *base, bool enable)
\r
297 base->CONTROL |= EMC_CONTROL_M_MASK;
\r
301 base->CONTROL &= ~EMC_CONTROL_M_MASK;
\r
306 * @brief Enter the self-refresh mode for dynamic memory controller.
\r
307 * This function provided self-refresh mode enter or exit for application.
\r
309 * @param base EMC peripheral base address.
\r
310 * @param enable True enter the self-refresh mode, false to exit self-refresh
\r
311 * and enter the normal mode.
\r
313 static inline void EMC_EnterSelfRefreshCommand(EMC_Type *base, bool enable)
\r
317 base->DYNAMICCONTROL |= EMC_DYNAMICCONTROL_SR_MASK;
\r
321 base->DYNAMICCONTROL &= ~EMC_DYNAMICCONTROL_SR_MASK;
\r
326 * @brief Get the operating mode of the EMC.
\r
327 * This function can be used to get the operating mode of the EMC.
\r
329 * @param base EMC peripheral base address.
\r
330 * @return The EMC in self-refresh mode if true, else in normal mode.
\r
332 static inline bool EMC_IsInSelfrefreshMode(EMC_Type *base)
\r
334 return (0U != (base->STATUS & EMC_STATUS_SA_MASK));
\r
338 * @brief Enter/exit the low-power mode.
\r
340 * @param base EMC peripheral base address.
\r
341 * @param enable True Enter the low-power mode, false exit low-power mode
\r
342 * and return to normal mode.
\r
344 static inline void EMC_EnterLowPowerMode(EMC_Type *base, bool enable)
\r
348 base->CONTROL |= EMC_CONTROL_L_MASK;
\r
352 base->CONTROL &= ~EMC_CONTROL_L_MASK;
\r
358 #if defined(__cplusplus)
\r
364 #endif /* _FSL_EMC_H_*/
\r