1 /*!
2 \file gd32e50x_exmc.c
3 \brief EXMC driver
4
5 \version 2020-03-10, V1.0.0, firmware for GD32E50x
6 \version 2020-08-26, V1.1.0, firmware for GD32E50x
7 \version 2021-03-23, V1.2.0, firmware for GD32E50x
8 */
9
10 /*
11 Copyright (c) 2021, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 #include "gd32e50x_exmc.h"
38
39 /* EXMC bank0 register reset value */
40 #define BANK0_SNCTL_REGION0_RESET ((uint32_t)0x000030DBU)
41 #define BANK0_SNCTL_REGION1_2_3_RESET ((uint32_t)0x000030D2U)
42 #define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
43 #define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU)
44
45 /* EXMC bank1/2 register reset mask */
46 #define BANK1_2_NPCTL_RESET ((uint32_t)0x00000018U)
47 #define BANK1_2_NPINTEN_RESET ((uint32_t)0x00000042U)
48 #define BANK1_2_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU)
49 #define BANK1_2_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU)
50
51 /* EXMC bank3 register reset mask */
52 #define BANK3_NPCTL_RESET ((uint32_t)0x00000018U)
53 #define BANK3_NPINTEN_RESET ((uint32_t)0x00000043U)
54 #define BANK3_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU)
55 #define BANK3_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU)
56 #define BANK3_PIOTCFG3_RESET ((uint32_t)0xFCFCFCFCU)
57
58 /* EXMC register bit offset */
59 #define SNCTL_NRMUX_OFFSET ((uint32_t)1U)
60 #define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U)
61 #define SNCTL_WRAPEN_OFFSET ((uint32_t)10U)
62 #define SNCTL_WREN_OFFSET ((uint32_t)12U)
63 #define SNCTL_NRWTEN_OFFSET ((uint32_t)13U)
64 #define SNCTL_EXMODEN_OFFSET ((uint32_t)14U)
65 #define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U)
66
67 #define SNTCFG_AHLD_OFFSET ((uint32_t)4U)
68 #define SNTCFG_DSET_OFFSET ((uint32_t)8U)
69 #define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U)
70
71 #define SNWTCFG_WAHLD_OFFSET ((uint32_t)4U)
72 #define SNWTCFG_WDSET_OFFSET ((uint32_t)8U)
73 #define SNWTCFG_WBUSLAT_OFFSET ((uint32_t)16U)
74
75 #define NPCTL_NDWTEN_OFFSET ((uint32_t)1U)
76 #define NPCTL_ECCEN_OFFSET ((uint32_t)6U)
77
78 #define NPCTCFG_COMWAIT_OFFSET ((uint32_t)8U)
79 #define NPCTCFG_COMHLD_OFFSET ((uint32_t)16U)
80 #define NPCTCFG_COMHIZ_OFFSET ((uint32_t)24U)
81
82 #define NPATCFG_ATTWAIT_OFFSET ((uint32_t)8U)
83 #define NPATCFG_ATTHLD_OFFSET ((uint32_t)16U)
84 #define NPATCFG_ATTHIZ_OFFSET ((uint32_t)24U)
85
86 #define PIOTCFG_IOWAIT_OFFSET ((uint32_t)8U)
87 #define PIOTCFG_IOHLD_OFFSET ((uint32_t)16U)
88 #define PIOTCFG_IOHIZ_OFFSET ((uint32_t)24U)
89
90 #define INTEN_INTS_OFFSET ((uint32_t)3U)
91
92 /*!
93 \brief deinitialize EXMC NOR/SRAM region
94 \param[in] exmc_norsram_region: select the region of bank0
95 only one parameter can be selected which is shown as below:
96 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
97 \param[out] none
98 \retval none
99 */
exmc_norsram_deinit(uint32_t exmc_norsram_region)100 void exmc_norsram_deinit(uint32_t exmc_norsram_region)
101 {
102 /* reset the registers */
103 if(EXMC_BANK0_NORSRAM_REGION0 == exmc_norsram_region){
104 EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_REGION0_RESET;
105 }else{
106 EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_REGION1_2_3_RESET;
107 }
108 EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET;
109 EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET;
110 }
111
112 /*!
113 \brief initialize exmc_norsram_parameter_struct with the default values
114 \param[in] none
115 \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer
116 \retval none
117 */
exmc_norsram_struct_para_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)118 void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
119 {
120 /* configure the structure with default values */
121 exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0;
122 exmc_norsram_init_struct->address_data_mux = ENABLE;
123 exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM;
124 exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B;
125 exmc_norsram_init_struct->burst_mode = DISABLE;
126 exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
127 exmc_norsram_init_struct->wrap_burst_mode = DISABLE;
128 exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
129 exmc_norsram_init_struct->memory_write = ENABLE;
130 exmc_norsram_init_struct->nwait_signal = ENABLE;
131 exmc_norsram_init_struct->extended_mode = DISABLE;
132 exmc_norsram_init_struct->asyn_wait = DISABLE;
133 exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
134
135 /* read/write timing configure */
136 exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
137 exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
138 exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
139 exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
140 exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
141 exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK;
142 exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
143
144 /* write timing configure, when extended mode is used */
145 exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU;
146 exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU;
147 exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU;
148 exmc_norsram_init_struct->write_timing->bus_latency = 0xFU;
149 exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
150 }
151
152 /*!
153 \brief initialize EXMC NOR/SRAM region
154 \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
155 norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0..3
156 write_mode: EXMC_ASYN_WRITE,EXMC_SYN_WRITE
157 extended_mode: ENABLE or DISABLE
158 asyn_wait: ENABLE or DISABLE
159 nwait_signal: ENABLE or DISABLE
160 memory_write: ENABLE or DISABLE
161 nwait_config: EXMC_NWAIT_CONFIG_BEFORE,EXMC_NWAIT_CONFIG_DURING
162 wrap_burst_mode: ENABLE or DISABLE
163 nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH
164 burst_mode: ENABLE or DISABLE
165 databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B
166 memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR
167 address_data_mux: ENABLE or DISABLE
168 read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
169 asyn_access_mode: EXMC_ACCESS_MODE_A,EXMC_ACCESS_MODE_B,EXMC_ACCESS_MODE_C,EXMC_ACCESS_MODE_D
170 syn_data_latency: EXMC_DATALAT_n_CLK,(n=2,..,17)
171 syn_clk_division: EXMC_SYN_CLOCK_RATIO_DISABLE, EXMC_SYN_CLOCK_RATIO_n_CLK,(n=2,..,16)
172 bus_latency: 1,..,16
173 asyn_data_setuptime: 2,..,256
174 asyn_address_holdtime: 2,..,16
175 asyn_address_setuptime: 1,..,16
176 write_timing: struct exmc_norsram_timing_parameter_struct set the time
177 asyn_access_mode: EXMC_ACCESS_MODE_A,EXMC_ACCESS_MODE_B,EXMC_ACCESS_MODE_C,EXMC_ACCESS_MODE_D
178 syn_data_latency: EXMC_DATALAT_n_CLK,(n=2,..,17)
179 syn_clk_division: EXMC_SYN_CLOCK_RATIO_DISABLE, EXMC_SYN_CLOCK_RATIO_n_CLK,(n=2,..,16)
180 bus_latency: 1,..,16
181 asyn_data_setuptime: 2,..,256
182 asyn_address_holdtime: 2,..,16
183 asyn_address_setuptime: 1,..,16
184 \param[out] none
185 \retval none
186 */
exmc_norsram_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)187 void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
188 {
189 uint32_t snctl = 0x00000000U,sntcfg = 0x00000000U,snwtcfg = 0x00000000U;
190
191 /* get the register value */
192 snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
193
194 /* clear relative bits */
195 snctl &= ((uint32_t)~(EXMC_SNCTL_NRMUX | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
196 EXMC_SNCTL_NREN | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG |
197 EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT |
198 EXMC_SNCTL_SYNCWR ));
199
200 snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
201 exmc_norsram_init_struct->memory_type |
202 exmc_norsram_init_struct->databus_width |
203 (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
204 exmc_norsram_init_struct->nwait_polarity |
205 (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
206 exmc_norsram_init_struct->nwait_config |
207 (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
208 (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
209 (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
210 (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
211 exmc_norsram_init_struct->write_mode;
212
213 sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )|
214 (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) |
215 (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) |
216 (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT )|
217 exmc_norsram_init_struct->read_write_timing->syn_clk_division |
218 exmc_norsram_init_struct->read_write_timing->syn_data_latency |
219 exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
220
221 /* nor flash access enable */
222 if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){
223 snctl |= (uint32_t)EXMC_SNCTL_NREN;
224 }
225
226 /* extended mode configure */
227 if(ENABLE == exmc_norsram_init_struct->extended_mode){
228 snwtcfg = (uint32_t)((exmc_norsram_init_struct->write_timing->asyn_address_setuptime - 1U) & EXMC_SNWTCFG_WASET ) |
229 (((exmc_norsram_init_struct->write_timing->asyn_address_holdtime -1U ) << SNWTCFG_WAHLD_OFFSET ) & EXMC_SNWTCFG_WAHLD )|
230 (((exmc_norsram_init_struct->write_timing->asyn_data_setuptime -1U ) << SNWTCFG_WDSET_OFFSET ) & EXMC_SNWTCFG_WDSET )|
231 (((exmc_norsram_init_struct->write_timing->bus_latency - 1U ) << SNWTCFG_WBUSLAT_OFFSET ) & EXMC_SNWTCFG_WBUSLAT ) |
232 exmc_norsram_init_struct->write_timing->asyn_access_mode;
233 }else{
234 snwtcfg = BANK0_SNWTCFG_RESET;
235 }
236
237 /* configure the registers */
238 EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
239 EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
240 EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg;
241 }
242
243 /*!
244 \brief enable EXMC NOR/PSRAM bank region
245 \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank
246 only one parameter can be selected which is shown as below:
247 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
248 \param[out] none
249 \retval none
250 */
exmc_norsram_enable(uint32_t exmc_norsram_region)251 void exmc_norsram_enable(uint32_t exmc_norsram_region)
252 {
253 EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
254 }
255
256 /*!
257 \brief disable EXMC NOR/PSRAM bank region
258 \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM Bank
259 only one parameter can be selected which is shown as below:
260 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
261 \param[out] none
262 \retval none
263 */
exmc_norsram_disable(uint32_t exmc_norsram_region)264 void exmc_norsram_disable(uint32_t exmc_norsram_region)
265 {
266 EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
267 }
268
269 /*!
270 \brief configure CRAM page size
271 \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank
272 only one parameter can be selected which is shown as below:
273 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
274 \param[in] page_size: CRAM page size
275 only one parameter can be selected which is shown as below:
276 \arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
277 \arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
278 \arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
279 \arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
280 \arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
281 \param[out] none
282 \retval none
283 */
exmc_norsram_page_size_config(uint32_t exmc_norsram_region,uint32_t page_size)284 void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_size)
285 {
286 /* reset the bits */
287 EXMC_SNCTL(exmc_norsram_region) &= ~EXMC_SNCTL_CPS;
288
289 /* set the CPS bits */
290 EXMC_SNCTL(exmc_norsram_region) |= page_size;
291 }
292
293 /*!
294 \brief deinitialize EXMC NAND bank
295 \param[in] exmc_nand_bank: select the bank of NAND
296 only one parameter can be selected which is shown as below:
297 \arg EXMC_BANKx_NAND(x=1..2)
298 \param[out] none
299 \retval none
300 */
exmc_nand_deinit(uint32_t exmc_nand_bank)301 void exmc_nand_deinit(uint32_t exmc_nand_bank)
302 {
303 /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */
304 EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET;
305 EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET;
306 EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET;
307 EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET;
308 }
309
310 /*!
311 \brief initialize exmc_nand_parameter_struct with the default values
312 \param[in] none
313 \param[out] the initialized struct exmc_nand_parameter_struct pointer
314 \retval none
315 */
exmc_nand_struct_para_init(exmc_nand_parameter_struct * exmc_nand_init_struct)316 void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
317 {
318 /* configure the structure with default values */
319 exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND;
320 exmc_nand_init_struct->wait_feature = DISABLE;
321 exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
322 exmc_nand_init_struct->ecc_logic = DISABLE;
323 exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES;
324 exmc_nand_init_struct->ctr_latency = 0x0U;
325 exmc_nand_init_struct->atr_latency = 0x0U;
326 exmc_nand_init_struct->common_space_timing->setuptime = 0xFCU;
327 exmc_nand_init_struct->common_space_timing->waittime = 0xFCU;
328 exmc_nand_init_struct->common_space_timing->holdtime = 0xFCU;
329 exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xFCU;
330 exmc_nand_init_struct->attribute_space_timing->setuptime = 0xFCU;
331 exmc_nand_init_struct->attribute_space_timing->waittime = 0xFCU;
332 exmc_nand_init_struct->attribute_space_timing->holdtime = 0xFCU;
333 exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
334 }
335
336 /*!
337 \brief initialize EXMC NAND bank
338 \param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter
339 nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND
340 ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
341 atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
342 ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
343 ecc_logic: ENABLE or DISABLE
344 databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
345 wait_feature: ENABLE or DISABLE
346 common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
347 databus_hiztime: 1,..,255
348 holdtime: 1,..,254
349 waittime: 2,..,255
350 setuptime: 1,..,255
351 attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
352 databus_hiztime: 1,..,255
353 holdtime: 1,..,254
354 waittime: 2,..,255
355 setuptime: 1,..,255
356 \param[out] none
357 \retval none
358 */
exmc_nand_init(exmc_nand_parameter_struct * exmc_nand_init_struct)359 void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
360 {
361 uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U;
362
363 npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)|
364 EXMC_NPCTL_NDTP |
365 exmc_nand_init_struct->databus_width |
366 (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)|
367 exmc_nand_init_struct->ecc_size |
368 exmc_nand_init_struct->ctr_latency |
369 exmc_nand_init_struct->atr_latency;
370
371 npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET ) |
372 (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
373 ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
374 (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
375
376 npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
377 (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
378 ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD ) |
379 (((exmc_nand_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
380
381 /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */
382 EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl;
383 EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg;
384 EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg;
385 }
386
387 /*!
388 \brief enable NAND bank
389 \param[in] exmc_nand_bank: specifie the NAND bank
390 only one parameter can be selected which is shown as below:
391 \arg EXMC_BANKx_NAND(x=1,2)
392 \param[out] none
393 \retval none
394 */
exmc_nand_enable(uint32_t exmc_nand_bank)395 void exmc_nand_enable(uint32_t exmc_nand_bank)
396 {
397 EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN;
398 }
399
400 /*!
401 \brief disable NAND bank
402 \param[in] exmc_nand_bank: specifie the NAND bank
403 only one parameter can be selected which is shown as below:
404 \arg EXMC_BANKx_NAND(x=1,2)
405 \param[out] none
406 \retval none
407 */
exmc_nand_disable(uint32_t exmc_nand_bank)408 void exmc_nand_disable(uint32_t exmc_nand_bank)
409 {
410 EXMC_NPCTL(exmc_nand_bank) &= (~EXMC_NPCTL_NDBKEN);
411 }
412
413 /*!
414 \brief enable or disable the EXMC NAND ECC function
415 \param[in] exmc_nand_bank: specifie the NAND bank
416 only one parameter can be selected which is shown as below:
417 \arg EXMC_BANKx_NAND(x=1,2)
418 \param[in] newvalue: ENABLE or DISABLE
419 \param[out] none
420 \retval none
421 */
exmc_nand_ecc_config(uint32_t exmc_nand_bank,ControlStatus newvalue)422 void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue)
423 {
424 if (ENABLE == newvalue){
425 /* enable the selected NAND bank ECC function */
426 EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN;
427 }else{
428 /* disable the selected NAND bank ECC function */
429 EXMC_NPCTL(exmc_nand_bank) &= (~EXMC_NPCTL_ECCEN);
430 }
431 }
432
433 /*!
434 \brief get the EXMC ECC value
435 \param[in] exmc_nand_bank: specifie the NAND bank
436 only one parameter can be selected which is shown as below:
437 \arg EXMC_BANKx_NAND(x=1,2)
438 \param[out] none
439 \retval the error correction code(ECC) value
440 */
exmc_ecc_get(uint32_t exmc_nand_bank)441 uint32_t exmc_ecc_get(uint32_t exmc_nand_bank)
442 {
443 return (EXMC_NECC(exmc_nand_bank));
444 }
445
446 /*!
447 \brief deinitialize EXMC PC card bank
448 \param[in] none
449 \param[out] none
450 \retval none
451 */
exmc_pccard_deinit(void)452 void exmc_pccard_deinit(void)
453 {
454 /* EXMC_BANK3_PCCARD */
455 EXMC_NPCTL3 = BANK3_NPCTL_RESET;
456 EXMC_NPINTEN3 = BANK3_NPINTEN_RESET;
457 EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET;
458 EXMC_NPATCFG3 = BANK3_NPATCFG_RESET;
459 EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET;
460 }
461
462 /*!
463 \brief initialize exmc_pccard_parameter_struct parameter with the default values
464 \param[in] none
465 \param[out] the initialized struct exmc_pccard_parameter_struct pointer
466 \retval none
467 */
exmc_pccard_struct_para_init(exmc_pccard_parameter_struct * exmc_pccard_init_struct)468 void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
469 {
470 /* configure the structure with default values */
471 exmc_pccard_init_struct->wait_feature = DISABLE;
472 exmc_pccard_init_struct->ctr_latency = 0x0U;
473 exmc_pccard_init_struct->atr_latency = 0x0U;
474 exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU;
475 exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU;
476 exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU;
477 exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU;
478 exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU;
479 exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU;
480 exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU;
481 exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
482 exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU;
483 exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU;
484 exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU;
485 exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU;
486 }
487
488 /*!
489 \brief initialize EXMC PC card bank
490 \param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter
491 atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
492 ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
493 wait_feature: ENABLE or DISABLE
494 common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
495 databus_hiztime: 1,..,255
496 holdtime: 1,..,254
497 waittime: 2,..,255
498 setuptime: 1,..,255
499 attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
500 databus_hiztime: 1,..,255
501 holdtime: 1,..,254
502 waittime: 2,..,255
503 setuptime: 1,..,255
504 io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time
505 databus_hiztime: 0,..,255
506 holdtime: 1,..,255
507 waittime: 2,..,256
508 setuptime: 1,..,256
509 \param[out] none
510 \retval none
511 */
exmc_pccard_init(exmc_pccard_parameter_struct * exmc_pccard_init_struct)512 void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
513 {
514 /* configure the EXMC bank3 PC card control register */
515 EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
516 EXMC_NAND_DATABUS_WIDTH_16B |
517 exmc_pccard_init_struct->ctr_latency |
518 exmc_pccard_init_struct->atr_latency ;
519
520 /* configure the EXMC bank3 PC card common space timing configuration register */
521 EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U)& EXMC_NPCTCFG_COMSET ) |
522 (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
523 ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
524 (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
525
526 /* configure the EXMC bank3 PC card attribute space timing configuration register */
527 EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
528 (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
529 ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD )|
530 (((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
531
532 /* configure the EXMC bank3 PC card io space timing configuration register */
533 EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET ) |
534 (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT ) |
535 ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD )|
536 ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ );
537 }
538
539 /*!
540 \brief enable PC Card Bank
541 \param[in] none
542 \param[out] none
543 \retval none
544 */
exmc_pccard_enable(void)545 void exmc_pccard_enable(void)
546 {
547 EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN;
548 }
549
550 /*!
551 \brief disable PC Card Bank
552 \param[in] none
553 \param[out] none
554 \retval none
555 */
exmc_pccard_disable(void)556 void exmc_pccard_disable(void)
557 {
558 EXMC_NPCTL3 &= (~EXMC_NPCTL_NDBKEN);
559 }
560
561 /*!
562 \brief enable EXMC interrupt
563 \param[in] exmc_bank: specifies the NAND bank,PC card bank
564 only one parameter can be selected which is shown as below:
565 \arg EXMC_BANK1_NAND: the NAND bank1
566 \arg EXMC_BANK2_NAND: the NAND bank2
567 \arg EXMC_BANK3_PCCARD: the PC card bank
568 \param[in] interrupt: EXMC interrupt flag
569 only one parameter can be selected which are shown as below:
570 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and corresponding flag
571 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and corresponding flag
572 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and corresponding flag
573 \param[out] none
574 \retval none
575 */
exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt)576 void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt)
577 {
578 /* NAND bank1,bank2 or PC card bank3 */
579 EXMC_NPINTEN(exmc_bank) |= interrupt;
580 }
581
582 /*!
583 \brief disable EXMC interrupt
584 \param[in] exmc_bank: specifies the NAND bank , PC card bank
585 only one parameter can be selected which is shown as below:
586 \arg EXMC_BANK1_NAND: the NAND bank1
587 \arg EXMC_BANK2_NAND: the NAND bank2
588 \arg EXMC_BANK3_PCCARD: the PC card bank
589 \param[in] interrupt: EXMC interrupt flag
590 only one parameter can be selected which are shown as below:
591 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and corresponding flag
592 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and corresponding flag
593 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and corresponding flag
594 \param[out] none
595 \retval none
596 */
exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt)597 void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt)
598 {
599 /* NAND bank1,bank2 or PC card bank3 */
600 EXMC_NPINTEN(exmc_bank) &= (~interrupt);
601 }
602
603 /*!
604 \brief get EXMC flag status
605 \param[in] exmc_bank: specifies the NAND bank , PC card bank
606 only one parameter can be selected which is shown as below:
607 \arg EXMC_BANK1_NAND: the NAND bank1
608 \arg EXMC_BANK2_NAND: the NAND bank2
609 \arg EXMC_BANK3_PCCARD: the PC Card bank
610 \param[in] flag: EXMC status and flag
611 only one parameter can be selected which are shown as below:
612 \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
613 \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
614 \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
615 \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
616 \param[out] none
617 \retval FlagStatus: SET or RESET
618 */
exmc_flag_get(uint32_t exmc_bank,uint32_t flag)619 FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag)
620 {
621 uint32_t status = 0x00000000U;
622
623 /* NAND bank1,bank2 or PC card bank3 */
624 status = EXMC_NPINTEN(exmc_bank);
625
626 if ((status & flag) != (uint32_t)flag ){
627 /* flag is reset */
628 return RESET;
629 }else{
630 /* flag is set */
631 return SET;
632 }
633 }
634
635 /*!
636 \brief clear EXMC flag status
637 \param[in] exmc_bank: specifie the NAND bank , PCCARD bank
638 only one parameter can be selected which is shown as below:
639 \arg EXMC_BANK1_NAND: the NAND bank1
640 \arg EXMC_BANK2_NAND: the NAND bank2
641 \arg EXMC_BANK3_PCCARD: the PC card bank
642 \param[in] flag: EXMC status and flag
643 only one parameter can be selected which are shown as below:
644 \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
645 \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
646 \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
647 \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
648 \param[out] none
649 \retval none
650 */
exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)651 void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)
652 {
653 /* NAND bank1,bank2 or PC card bank3 */
654 EXMC_NPINTEN(exmc_bank) &= (~flag);
655 }
656
657 /*!
658 \brief get EXMC interrupt flag
659 \param[in] exmc_bank: specifies the NAND bank , PC card bank
660 only one parameter can be selected which is shown as below:
661 \arg EXMC_BANK1_NAND: the NAND bank1
662 \arg EXMC_BANK2_NAND: the NAND bank2
663 \arg EXMC_BANK3_PCCARD: the PC card bank
664 \param[in] interrupt: EXMC interrupt flag
665 only one parameter can be selected which are shown as below:
666 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and corresponding flag
667 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and corresponding flag
668 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and corresponding flag
669 \param[out] none
670 \retval FlagStatus: SET or RESET
671 */
exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt)672 FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt)
673 {
674 uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U;
675
676 /* NAND bank1,bank2 or PC card bank3 */
677 status = EXMC_NPINTEN(exmc_bank);
678 interrupt_state = (status & (interrupt >> INTEN_INTS_OFFSET));
679
680 interrupt_enable = (status & interrupt);
681
682 if ((interrupt_enable) && (interrupt_state)){
683 /* interrupt flag is set */
684 return SET;
685 }else{
686 /* interrupt flag is reset */
687 return RESET;
688 }
689 }
690
691 /*!
692 \brief clear EXMC interrupt flag
693 \param[in] exmc_bank: specifies the NAND bank , PC card bank
694 only one parameter can be selected which is shown as below:
695 \arg EXMC_BANK1_NAND: the NAND bank1
696 \arg EXMC_BANK2_NAND: the NAND bank2
697 \arg EXMC_BANK3_PCCARD: the PC card bank
698 \param[in] interrupt: EXMC interrupt flag
699 only one parameter can be selected which are shown as below:
700 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and corresponding flag
701 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and corresponding flag
702 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and corresponding flag
703 \param[out] none
704 \retval none
705 */
exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt)706 void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt)
707 {
708 /* NAND bank1,bank2 or PC card bank3 */
709 EXMC_NPINTEN(exmc_bank) &= ~(interrupt >> INTEN_INTS_OFFSET);
710 }
711