1 /*!
2 \file gd32f403_exmc.c
3 \brief EXMC driver
4
5 \version 2017-02-10, V1.0.0, firmware for GD32F403
6 \version 2018-12-25, V2.0.0, firmware for GD32F403
7 \version 2020-09-30, V2.1.0, firmware for GD32F403
8 */
9
10 /*
11 Copyright (c) 2020, 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 "gd32f403_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 write_timing: struct exmc_norsram_timing_parameter_struct set the time
170 \param[out] none
171 \retval none
172 */
exmc_norsram_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)173 void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
174 {
175 uint32_t snctl = 0x00000000U,sntcfg = 0x00000000U,snwtcfg = 0x00000000U;
176
177 /* get the register value */
178 snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
179
180 /* clear relative bits */
181 snctl &= ((uint32_t)~(EXMC_SNCTL_NRMUX | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
182 EXMC_SNCTL_NREN | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG |
183 EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT |
184 EXMC_SNCTL_SYNCWR ));
185
186 snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
187 exmc_norsram_init_struct->memory_type |
188 exmc_norsram_init_struct->databus_width |
189 (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
190 exmc_norsram_init_struct->nwait_polarity |
191 (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
192 exmc_norsram_init_struct->nwait_config |
193 (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
194 (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
195 (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
196 (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
197 exmc_norsram_init_struct->write_mode;
198
199 sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )|
200 (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) |
201 (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) |
202 (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT )|
203 exmc_norsram_init_struct->read_write_timing->syn_clk_division |
204 exmc_norsram_init_struct->read_write_timing->syn_data_latency |
205 exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
206
207 /* nor flash access enable */
208 if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){
209 snctl |= (uint32_t)EXMC_SNCTL_NREN;
210 }
211
212 /* extended mode configure */
213 if(ENABLE == exmc_norsram_init_struct->extended_mode){
214 snwtcfg = (uint32_t)((exmc_norsram_init_struct->write_timing->asyn_address_setuptime - 1U) & EXMC_SNWTCFG_WASET ) |
215 (((exmc_norsram_init_struct->write_timing->asyn_address_holdtime -1U ) << SNWTCFG_WAHLD_OFFSET ) & EXMC_SNWTCFG_WAHLD )|
216 (((exmc_norsram_init_struct->write_timing->asyn_data_setuptime -1U ) << SNWTCFG_WDSET_OFFSET ) & EXMC_SNWTCFG_WDSET )|
217 (((exmc_norsram_init_struct->write_timing->bus_latency - 1U ) << SNWTCFG_WBUSLAT_OFFSET ) & EXMC_SNWTCFG_WBUSLAT ) |
218 exmc_norsram_init_struct->write_timing->asyn_access_mode;
219 }else{
220 snwtcfg = BANK0_SNWTCFG_RESET;
221 }
222
223 /* configure the registers */
224 EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
225 EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
226 EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg;
227 }
228
229 /*!
230 \brief enable EXMC NOR/PSRAM bank region
231 \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank
232 only one parameter can be selected which is shown as below:
233 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
234 \param[out] none
235 \retval none
236 */
exmc_norsram_enable(uint32_t exmc_norsram_region)237 void exmc_norsram_enable(uint32_t exmc_norsram_region)
238 {
239 EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
240 }
241
242 /*!
243 \brief disable EXMC NOR/PSRAM bank region
244 \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM Bank
245 only one parameter can be selected which is shown as below:
246 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
247 \param[out] none
248 \retval none
249 */
exmc_norsram_disable(uint32_t exmc_norsram_region)250 void exmc_norsram_disable(uint32_t exmc_norsram_region)
251 {
252 EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
253 }
254
255 /*!
256 \brief deinitialize EXMC NAND bank
257 \param[in] exmc_nand_bank: select the bank of NAND
258 only one parameter can be selected which is shown as below:
259 \arg EXMC_BANKx_NAND(x=1..2)
260 \param[out] none
261 \retval none
262 */
exmc_nand_deinit(uint32_t exmc_nand_bank)263 void exmc_nand_deinit(uint32_t exmc_nand_bank)
264 {
265 /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */
266 EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET;
267 EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET;
268 EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET;
269 EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET;
270 }
271
272 /*!
273 \brief initialize exmc_norsram_parameter_struct with the default values
274 \param[in] none
275 \param[out] the initialized struct exmc_norsram_parameter_struct pointer
276 \retval none
277 */
exmc_nand_struct_para_init(exmc_nand_parameter_struct * exmc_nand_init_struct)278 void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
279 {
280 /* configure the structure with default values */
281 exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND;
282 exmc_nand_init_struct->wait_feature = DISABLE;
283 exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
284 exmc_nand_init_struct->ecc_logic = DISABLE;
285 exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES;
286 exmc_nand_init_struct->ctr_latency = 0x0U;
287 exmc_nand_init_struct->atr_latency = 0x0U;
288 exmc_nand_init_struct->common_space_timing->setuptime = 0xFCU;
289 exmc_nand_init_struct->common_space_timing->waittime = 0xFCU;
290 exmc_nand_init_struct->common_space_timing->holdtime = 0xFCU;
291 exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xFCU;
292 exmc_nand_init_struct->attribute_space_timing->setuptime = 0xFCU;
293 exmc_nand_init_struct->attribute_space_timing->waittime = 0xFCU;
294 exmc_nand_init_struct->attribute_space_timing->holdtime = 0xFCU;
295 exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
296 }
297
298 /*!
299 \brief initialize EXMC NAND bank
300 \param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter
301 nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND
302 ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
303 atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
304 ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
305 ecc_logic: ENABLE or DISABLE
306 databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
307 wait_feature: ENABLE or DISABLE
308 common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
309 attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
310 \param[out] none
311 \retval none
312 */
exmc_nand_init(exmc_nand_parameter_struct * exmc_nand_init_struct)313 void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
314 {
315 uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U;
316
317 npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)|
318 EXMC_NPCTL_NDTP |
319 exmc_nand_init_struct->databus_width |
320 (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)|
321 exmc_nand_init_struct->ecc_size |
322 exmc_nand_init_struct->ctr_latency |
323 exmc_nand_init_struct->atr_latency;
324
325 npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET ) |
326 (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
327 ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
328 (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
329
330 npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
331 (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
332 ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD ) |
333 (((exmc_nand_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
334
335 /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */
336 EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl;
337 EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg;
338 EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg;
339 }
340
341 /*!
342 \brief enable NAND bank
343 \param[in] exmc_nand_bank: specifie the NAND bank
344 only one parameter can be selected which is shown as below:
345 \arg EXMC_BANKx_NAND(x=1,2)
346 \param[out] none
347 \retval none
348 */
exmc_nand_enable(uint32_t exmc_nand_bank)349 void exmc_nand_enable(uint32_t exmc_nand_bank)
350 {
351 EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN;
352 }
353
354 /*!
355 \brief disable NAND bank
356 \param[in] exmc_nand_bank: specifie the NAND bank
357 only one parameter can be selected which is shown as below:
358 \arg EXMC_BANKx_NAND(x=1,2)
359 \param[out] none
360 \retval none
361 */
exmc_nand_disable(uint32_t exmc_nand_bank)362 void exmc_nand_disable(uint32_t exmc_nand_bank)
363 {
364 EXMC_NPCTL(exmc_nand_bank) &= (~EXMC_NPCTL_NDBKEN);
365 }
366
367 /*!
368 \brief deinitialize EXMC PC card bank
369 \param[in] none
370 \param[out] none
371 \retval none
372 */
exmc_pccard_deinit(void)373 void exmc_pccard_deinit(void)
374 {
375 /* EXMC_BANK3_PCCARD */
376 EXMC_NPCTL3 = BANK3_NPCTL_RESET;
377 EXMC_NPINTEN3 = BANK3_NPINTEN_RESET;
378 EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET;
379 EXMC_NPATCFG3 = BANK3_NPATCFG_RESET;
380 EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET;
381 }
382
383 /*!
384 \brief initialize exmc_pccard_parameter_struct parameter with the default values
385 \param[in] none
386 \param[out] the initialized struct exmc_pccard_parameter_struct pointer
387 \retval none
388 */
exmc_pccard_struct_para_init(exmc_pccard_parameter_struct * exmc_pccard_init_struct)389 void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
390 {
391 /* configure the structure with default values */
392 exmc_pccard_init_struct->wait_feature = DISABLE;
393 exmc_pccard_init_struct->ctr_latency = 0x0U;
394 exmc_pccard_init_struct->atr_latency = 0x0U;
395 exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU;
396 exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU;
397 exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU;
398 exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU;
399 exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU;
400 exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU;
401 exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU;
402 exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
403 exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU;
404 exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU;
405 exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU;
406 exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU;
407 }
408
409 /*!
410 \brief initialize EXMC PC card bank
411 \param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter
412 atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
413 ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
414 wait_feature: ENABLE or DISABLE
415 common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
416 attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
417 io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time
418 \param[out] none
419 \retval none
420 */
exmc_pccard_init(exmc_pccard_parameter_struct * exmc_pccard_init_struct)421 void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
422 {
423 /* configure the EXMC bank3 PC card control register */
424 EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
425 EXMC_NAND_DATABUS_WIDTH_16B |
426 exmc_pccard_init_struct->ctr_latency |
427 exmc_pccard_init_struct->atr_latency ;
428
429 /* configure the EXMC bank3 PC card common space timing configuration register */
430 EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U)& EXMC_NPCTCFG_COMSET ) |
431 (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
432 ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
433 (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
434
435 /* configure the EXMC bank3 PC card attribute space timing configuration register */
436 EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
437 (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
438 ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD )|
439 (((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
440
441 /* configure the EXMC bank3 PC card io space timing configuration register */
442 EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET ) |
443 (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT ) |
444 ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD )|
445 ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ );
446 }
447
448 /*!
449 \brief enable PC Card Bank
450 \param[in] none
451 \param[out] none
452 \retval none
453 */
exmc_pccard_enable(void)454 void exmc_pccard_enable(void)
455 {
456 EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN;
457 }
458
459 /*!
460 \brief disable PC Card Bank
461 \param[in] none
462 \param[out] none
463 \retval none
464 */
exmc_pccard_disable(void)465 void exmc_pccard_disable(void)
466 {
467 EXMC_NPCTL3 &= (~EXMC_NPCTL_NDBKEN);
468 }
469
470 /*!
471 \brief configure CRAM page size
472 \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank
473 only one parameter can be selected which is shown as below:
474 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
475 \param[in] page_size: CRAM page size
476 only one parameter can be selected which is shown as below:
477 \arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
478 \arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
479 \arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
480 \arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
481 \arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
482 \param[out] none
483 \retval none
484 */
exmc_norsram_page_size_config(uint32_t exmc_norsram_region,uint32_t page_size)485 void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_size)
486 {
487 /* reset the bits */
488 EXMC_SNCTL(exmc_norsram_region) &= ~EXMC_SNCTL_CPS;
489
490 /* set the CPS bits */
491 EXMC_SNCTL(exmc_norsram_region) |= page_size;
492 }
493
494 /*!
495 \brief enable or disable the EXMC NAND ECC function
496 \param[in] exmc_nand_bank: specifie the NAND bank
497 only one parameter can be selected which is shown as below:
498 \arg EXMC_BANKx_NAND(x=1,2)
499 \param[in] newvalue: ENABLE or DISABLE
500 \param[out] none
501 \retval none
502 */
exmc_nand_ecc_config(uint32_t exmc_nand_bank,ControlStatus newvalue)503 void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue)
504 {
505 if (ENABLE == newvalue){
506 /* enable the selected NAND bank ECC function */
507 EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN;
508 }else{
509 /* disable the selected NAND bank ECC function */
510 EXMC_NPCTL(exmc_nand_bank) &= (~EXMC_NPCTL_ECCEN);
511 }
512 }
513
514 /*!
515 \brief get the EXMC ECC value
516 \param[in] exmc_nand_bank: specifie the NAND bank
517 only one parameter can be selected which is shown as below:
518 \arg EXMC_BANKx_NAND(x=1,2)
519 \param[out] none
520 \retval the error correction code(ECC) value
521 */
exmc_ecc_get(uint32_t exmc_nand_bank)522 uint32_t exmc_ecc_get(uint32_t exmc_nand_bank)
523 {
524 return (EXMC_NECC(exmc_nand_bank));
525 }
526
527 /*!
528 \brief enable EXMC interrupt
529 \param[in] exmc_bank: specifies the NAND bank,PC card bank
530 only one parameter can be selected which is shown as below:
531 \arg EXMC_BANK1_NAND: the NAND bank1
532 \arg EXMC_BANK2_NAND: the NAND bank2
533 \arg EXMC_BANK3_PCCARD: the PC card bank
534 \param[in] interrupt: EXMC interrupt flag
535 only one parameter can be selected which are shown as below:
536 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
537 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
538 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
539 \param[out] none
540 \retval none
541 */
exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt)542 void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt)
543 {
544 /* NAND bank1,bank2 or PC card bank3 */
545 EXMC_NPINTEN(exmc_bank) |= interrupt;
546 }
547
548 /*!
549 \brief disable EXMC interrupt
550 \param[in] exmc_bank: specifies the NAND bank , PC card bank
551 only one parameter can be selected which is shown as below:
552 \arg EXMC_BANK1_NAND: the NAND bank1
553 \arg EXMC_BANK2_NAND: the NAND bank2
554 \arg EXMC_BANK3_PCCARD: the PC card bank
555 \param[in] interrupt: EXMC interrupt flag
556 only one parameter can be selected which are shown as below:
557 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
558 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
559 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
560 \param[out] none
561 \retval none
562 */
exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt)563 void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt)
564 {
565 /* NAND bank1,bank2 or PC card bank3 */
566 EXMC_NPINTEN(exmc_bank) &= (~interrupt);
567 }
568
569 /*!
570 \brief get EXMC flag status
571 \param[in] exmc_bank: specifies the NAND bank , PC card bank
572 only one parameter can be selected which is shown as below:
573 \arg EXMC_BANK1_NAND: the NAND bank1
574 \arg EXMC_BANK2_NAND: the NAND bank2
575 \arg EXMC_BANK3_PCCARD: the PC Card bank
576 \param[in] flag: EXMC status and flag
577 only one parameter can be selected which are shown as below:
578 \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
579 \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
580 \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
581 \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
582 \param[out] none
583 \retval FlagStatus: SET or RESET
584 */
exmc_flag_get(uint32_t exmc_bank,uint32_t flag)585 FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag)
586 {
587 uint32_t status = 0x00000000U;
588
589 /* NAND bank1,bank2 or PC card bank3 */
590 status = EXMC_NPINTEN(exmc_bank);
591
592 if ((status & flag) != (uint32_t)flag ){
593 /* flag is reset */
594 return RESET;
595 }else{
596 /* flag is set */
597 return SET;
598 }
599 }
600
601 /*!
602 \brief clear EXMC flag status
603 \param[in] exmc_bank: specifie the NAND bank , PCCARD bank
604 only one parameter can be selected which is shown as below:
605 \arg EXMC_BANK1_NAND: the NAND bank1
606 \arg EXMC_BANK2_NAND: the NAND bank2
607 \arg EXMC_BANK3_PCCARD: the PC card bank
608 \param[in] flag: EXMC status and flag
609 only one parameter can be selected which are shown as below:
610 \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
611 \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
612 \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
613 \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
614 \param[out] none
615 \retval none
616 */
exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)617 void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)
618 {
619 /* NAND bank1,bank2 or PC card bank3 */
620 EXMC_NPINTEN(exmc_bank) &= (~flag);
621 }
622
623 /*!
624 \brief get EXMC interrupt flag
625 \param[in] exmc_bank: specifies the NAND bank , PC card bank
626 only one parameter can be selected which is shown as below:
627 \arg EXMC_BANK1_NAND: the NAND bank1
628 \arg EXMC_BANK2_NAND: the NAND bank2
629 \arg EXMC_BANK3_PCCARD: the PC card bank
630 \param[in] interrupt: EXMC interrupt flag
631 only one parameter can be selected which are shown as below:
632 \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
633 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
634 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
635 \param[out] none
636 \retval FlagStatus: SET or RESET
637 */
exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt)638 FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt)
639 {
640 uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U;
641
642 /* NAND bank1,bank2 or PC card bank3 */
643 status = EXMC_NPINTEN(exmc_bank);
644 interrupt_state = (status & (interrupt >> INTEN_INTS_OFFSET));
645
646 interrupt_enable = (status & interrupt);
647
648 if ((interrupt_enable) && (interrupt_state)){
649 /* interrupt flag is set */
650 return SET;
651 }else{
652 /* interrupt flag is reset */
653 return RESET;
654 }
655 }
656
657 /*!
658 \brief clear 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 flag
667 \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
668 \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
669 \param[out] none
670 \retval none
671 */
exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt)672 void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt)
673 {
674 /* NAND bank1,bank2 or PC card bank3 */
675 EXMC_NPINTEN(exmc_bank) &= ~(interrupt >> INTEN_INTS_OFFSET);
676 }
677