1 /*!
2     \file    gd32f4xx_exmc.c
3     \brief   EXMC driver
4 
5     \version 2016-08-15, V1.0.0, firmware for GD32F4xx
6     \version 2018-12-12, V2.0.0, firmware for GD32F4xx
7     \version 2020-09-30, V2.1.0, firmware for GD32F4xx
8     \version 2022-03-09, V3.0.0, firmware for GD32F4xx
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32f4xx_exmc.h"
39 
40 /* EXMC bank0 register reset value */
41 #define BANK0_SNCTL_RESET                 ((uint32_t)0x000030DAU)
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)0x00000008U)
47 #define BANK1_2_NPINTEN_RESET             ((uint32_t)0x00000042U)
48 #define BANK1_2_NPCTCFG_RESET             ((uint32_t)0xFFFFFFFFU)
49 #define BANK1_2_NPATCFG_RESET             ((uint32_t)0xFFFFFFFFU)
50 
51 /* EXMC bank3 register reset mask */
52 #define BANK3_NPCTL_RESET                 ((uint32_t)0x00000008U)
53 #define BANK3_NPINTEN_RESET               ((uint32_t)0x00000040U)
54 #define BANK3_NPCTCFG_RESET               ((uint32_t)0xFFFFFFFFU)
55 #define BANK3_NPATCFG_RESET               ((uint32_t)0xFFFFFFFFU)
56 #define BANK3_PIOTCFG3_RESET              ((uint32_t)0xFFFFFFFFU)
57 
58 /* EXMC SDRAM device register reset mask */
59 #define SDRAM_DEVICE_SDCTL_RESET          ((uint32_t)0x000002D0U)
60 #define SDRAM_DEVICE_SDTCFG_RESET         ((uint32_t)0x0FFFFFFFU)
61 #define SDRAM_DEVICE_SDCMD_RESET          ((uint32_t)0x00000000U)
62 #define SDRAM_DEVICE_SDARI_RESET          ((uint32_t)0x00000000U)
63 #define SDRAM_DEVICE_SDSTAT_RESET         ((uint32_t)0x00000000U)
64 #define SDRAM_DEVICE_SDRSCTL_RESET        ((uint32_t)0x00000000U)
65 
66 /* EXMC bank0 SQPI-PSRAM register reset mask */
67 #define BANK0_SQPI_SINIT_RESET            ((uint32_t)0x18010000U)
68 #define BANK0_SQPI_SRCMD_RESET            ((uint32_t)0x00000000U)
69 #define BANK0_SQPI_SWCMD_RESET            ((uint32_t)0x00000000U)
70 #define BANK0_SQPI_SIDL_RESET             ((uint32_t)0x00000000U)
71 #define BANK0_SQPI_SIDH_RESET             ((uint32_t)0x00000000U)
72 
73 /* EXMC register bit offset */
74 #define SNCTL_NRMUX_OFFSET                ((uint32_t)1U)
75 #define SNCTL_SBRSTEN_OFFSET              ((uint32_t)8U)
76 #define SNCTL_WRAPEN_OFFSET               ((uint32_t)10U)
77 #define SNCTL_WREN_OFFSET                 ((uint32_t)12U)
78 #define SNCTL_NRWTEN_OFFSET               ((uint32_t)13U)
79 #define SNCTL_EXMODEN_OFFSET              ((uint32_t)14U)
80 #define SNCTL_ASYNCWAIT_OFFSET            ((uint32_t)15U)
81 
82 #define SNTCFG_AHLD_OFFSET                ((uint32_t)4U)
83 #define SNTCFG_DSET_OFFSET                ((uint32_t)8U)
84 #define SNTCFG_BUSLAT_OFFSET              ((uint32_t)16U)
85 
86 #define NPCTL_NDWTEN_OFFSET               ((uint32_t)1U)
87 #define NPCTL_ECCEN_OFFSET                ((uint32_t)6U)
88 
89 #define NPCTCFG_COMWAIT_OFFSET            ((uint32_t)8U)
90 #define NPCTCFG_COMHLD_OFFSET             ((uint32_t)16U)
91 #define NPCTCFG_COMHIZ_OFFSET             ((uint32_t)24U)
92 
93 #define NPATCFG_ATTWAIT_OFFSET            ((uint32_t)8U)
94 #define NPATCFG_ATTHLD_OFFSET             ((uint32_t)16U)
95 #define NPATCFG_ATTHIZ_OFFSET             ((uint32_t)24U)
96 
97 #define PIOTCFG_IOWAIT_OFFSET             ((uint32_t)8U)
98 #define PIOTCFG_IOHLD_OFFSET              ((uint32_t)16U)
99 #define PIOTCFG_IOHIZ_OFFSET              ((uint32_t)24U)
100 
101 #define SDCTL_WPEN_OFFSET                 ((uint32_t)9U)
102 #define SDCTL_BRSTRD_OFFSET               ((uint32_t)12U)
103 
104 #define SDTCFG_XSRD_OFFSET                ((uint32_t)4U)
105 #define SDTCFG_RASD_OFFSET                ((uint32_t)8U)
106 #define SDTCFG_ARFD_OFFSET                ((uint32_t)12U)
107 #define SDTCFG_WRD_OFFSET                 ((uint32_t)16U)
108 #define SDTCFG_RPD_OFFSET                 ((uint32_t)20U)
109 #define SDTCFG_RCD_OFFSET                 ((uint32_t)24U)
110 
111 #define SDCMD_NARF_OFFSET                 ((uint32_t)5U)
112 #define SDCMD_MRC_OFFSET                  ((uint32_t)9U)
113 
114 #define SDARI_ARINTV_OFFSET               ((uint32_t)1U)
115 
116 #define SDSTAT_STA0_OFFSET                ((uint32_t)1U)
117 #define SDSTAT_STA1_OFFSET                ((uint32_t)3U)
118 
119 #define SRCMD_RWAITCYCLE_OFFSET           ((uint32_t)16U)
120 #define SWCMD_WWAITCYCLE_OFFSET           ((uint32_t)16U)
121 
122 #define INTEN_INTS_OFFSET                 ((uint32_t)3U)
123 
124 /*!
125     \brief    deinitialize EXMC NOR/SRAM region
126     \param[in]  exmc_norsram_region: select the region of bank0
127                 only one parameter can be selected which is shown as below:
128       \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
129     \param[out] none
130     \retval     none
131 */
exmc_norsram_deinit(uint32_t exmc_norsram_region)132 void exmc_norsram_deinit(uint32_t exmc_norsram_region)
133 {
134     /* reset the registers */
135     EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_RESET;
136     EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET;
137     EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET;
138 }
139 
140 /*!
141     \brief    initialize exmc_norsram_parameter_struct with the default values
142     \param[in]  none
143     \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer
144     \retval     none
145 */
exmc_norsram_struct_para_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)146 void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct)
147 {
148     /* configure the structure with default values */
149     exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0;
150     exmc_norsram_init_struct->address_data_mux = ENABLE;
151     exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM;
152     exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B;
153     exmc_norsram_init_struct->burst_mode = DISABLE;
154     exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
155     exmc_norsram_init_struct->wrap_burst_mode = DISABLE;
156     exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
157     exmc_norsram_init_struct->memory_write = ENABLE;
158     exmc_norsram_init_struct->nwait_signal = ENABLE;
159     exmc_norsram_init_struct->extended_mode = DISABLE;
160     exmc_norsram_init_struct->asyn_wait = DISABLE;
161     exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
162 
163     /* configure read/write timing */
164     exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
165     exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
166     exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
167     exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
168     exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
169     exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK;
170     exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
171 
172     /* write timing configure, when extended mode is used */
173     exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU;
174     exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU;
175     exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU;
176     exmc_norsram_init_struct->write_timing->bus_latency = 0xFU;
177     exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
178 }
179 
180 /*!
181     \brief    initialize EXMC NOR/SRAM region
182     \param[in]  exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
183                   norsram_region: EXMC_BANK0_NORSRAM_REGIONx, x=0..3
184                   write_mode: EXMC_ASYN_WRITE, EXMC_SYN_WRITE
185                   extended_mode: ENABLE or DISABLE
186                   asyn_wait: ENABLE or DISABLE
187                   nwait_signal: ENABLE or DISABLE
188                   memory_write: ENABLE or DISABLE
189                   nwait_config: EXMC_NWAIT_CONFIG_BEFORE, EXMC_NWAIT_CONFIG_DURING
190                   wrap_burst_mode: ENABLE or DISABLE
191                   nwait_polarity: EXMC_NWAIT_POLARITY_LOW, EXMC_NWAIT_POLARITY_HIGH
192                   burst_mode: ENABLE or DISABLE
193                   databus_width: EXMC_NOR_DATABUS_WIDTH_8B, EXMC_NOR_DATABUS_WIDTH_16B
194                   memory_type: EXMC_MEMORY_TYPE_SRAM, EXMC_MEMORY_TYPE_PSRAM, EXMC_MEMORY_TYPE_NOR
195                   address_data_mux: ENABLE or DISABLE
196                   read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
197                     asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D
198                     syn_data_latency: EXMC_DATALAT_x_CLK, x=2..17
199                     syn_clk_division: EXMC_SYN_CLOCK_RATIO_DISABLE, EXMC_SYN_CLOCK_RATIO_x_CLK, x=2..16
200                     bus_latency: 0x0U~0xFU
201                     asyn_data_setuptime: 0x01U~0xFFU
202                     asyn_address_holdtime: 0x1U~0xFU
203                     asyn_address_setuptime: 0x0U~0xFU
204                   write_timing: struct exmc_norsram_timing_parameter_struct set the time
205                     asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D
206                     syn_data_latency: EXMC_DATALAT_x_CLK, x=2..17
207                     syn_clk_division: EXMC_SYN_CLOCK_RATIO_x_CLK, x=2..16
208                     bus_latency: 0x0U~0xFU
209                     asyn_data_setuptime: 0x01U~0xFFU
210                     asyn_address_holdtime: 0x1U~0xFU
211                     asyn_address_setuptime: 0x0U~0xFU
212     \param[out] none
213     \retval     none
214 */
exmc_norsram_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)215 void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct)
216 {
217     uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U, snwtcfg = 0x00000000U;
218 
219     /* get the register value */
220     snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
221 
222     /* clear relative bits */
223     snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
224                           EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WEN |
225                           EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWTEN | EXMC_SNCTL_SYNCWR |
226                           EXMC_SNCTL_NRMUX));
227 
228     snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
229              exmc_norsram_init_struct->memory_type |
230              exmc_norsram_init_struct->databus_width |
231              (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
232              exmc_norsram_init_struct->nwait_polarity |
233              (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
234              exmc_norsram_init_struct->nwait_config |
235              (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
236              (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
237              (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
238              (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
239              exmc_norsram_init_struct->write_mode;
240 
241     sntcfg = (uint32_t)exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime |
242              (exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) |
243              (exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) |
244              (exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) |
245              exmc_norsram_init_struct->read_write_timing->syn_clk_division |
246              exmc_norsram_init_struct->read_write_timing->syn_data_latency |
247              exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
248 
249     /* nor flash access enable */
250     if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) {
251         snctl |= (uint32_t)EXMC_SNCTL_NREN;
252     }
253 
254     /* extended mode configure */
255     if(ENABLE == exmc_norsram_init_struct->extended_mode) {
256         snwtcfg = (uint32_t)exmc_norsram_init_struct->write_timing->asyn_address_setuptime |
257                   (exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) |
258                   (exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) |
259                   (exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) |
260                   exmc_norsram_init_struct->write_timing->asyn_access_mode;
261     } else {
262         snwtcfg = BANK0_SNWTCFG_RESET;
263     }
264 
265     /* configure the registers */
266     EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
267     EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
268     EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg;
269 }
270 
271 /*!
272     \brief    enable EXMC NOR/PSRAM bank region
273     \param[in]  exmc_norsram_region: specify the region of NOR/PSRAM bank
274                 only one parameter can be selected which is shown as below:
275       \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
276     \param[out] none
277     \retval     none
278 */
exmc_norsram_enable(uint32_t exmc_norsram_region)279 void exmc_norsram_enable(uint32_t exmc_norsram_region)
280 {
281     EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
282 }
283 
284 /*!
285     \brief    disable EXMC NOR/PSRAM bank region
286     \param[in]  exmc_norsram_region: specify the region of NOR/PSRAM Bank
287                 only one parameter can be selected which is shown as below:
288       \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
289     \param[out] none
290     \retval     none
291 */
exmc_norsram_disable(uint32_t exmc_norsram_region)292 void exmc_norsram_disable(uint32_t exmc_norsram_region)
293 {
294     EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
295 }
296 
297 /*!
298     \brief    deinitialize EXMC NAND bank
299     \param[in]  exmc_nand_bank: select the bank of NAND
300                 only one parameter can be selected which is shown as below:
301       \arg        EXMC_BANKx_NAND(x=1..2)
302     \param[out] none
303     \retval     none
304 */
exmc_nand_deinit(uint32_t exmc_nand_bank)305 void exmc_nand_deinit(uint32_t exmc_nand_bank)
306 {
307     /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */
308     EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET;
309     EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET;
310     EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET;
311     EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET;
312 }
313 
314 /*!
315     \brief    initialize exmc_norsram_parameter_struct with the default values
316     \param[in]  none
317     \param[out] the initialized struct exmc_norsram_parameter_struct pointer
318     \retval     none
319 */
exmc_nand_struct_para_init(exmc_nand_parameter_struct * exmc_nand_init_struct)320 void exmc_nand_struct_para_init(exmc_nand_parameter_struct *exmc_nand_init_struct)
321 {
322     /* configure the structure with default values */
323     exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND;
324     exmc_nand_init_struct->wait_feature = DISABLE;
325     exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
326     exmc_nand_init_struct->ecc_logic = DISABLE;
327     exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES;
328     exmc_nand_init_struct->ctr_latency = 0x0U;
329     exmc_nand_init_struct->atr_latency = 0x0U;
330     exmc_nand_init_struct->common_space_timing->setuptime = 0xFCU;
331     exmc_nand_init_struct->common_space_timing->waittime = 0xFCU;
332     exmc_nand_init_struct->common_space_timing->holdtime = 0xFCU;
333     exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xFCU;
334     exmc_nand_init_struct->attribute_space_timing->setuptime = 0xFCU;
335     exmc_nand_init_struct->attribute_space_timing->waittime = 0xFCU;
336     exmc_nand_init_struct->attribute_space_timing->holdtime = 0xFCU;
337     exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
338 }
339 
340 /*!
341     \brief    initialize EXMC NAND bank
342     \param[in]  exmc_nand_parameter_struct: configure the EXMC NAND parameter
343                   nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND
344                   ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
345                   atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
346                   ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
347                   ecc_logic: ENABLE or DISABLE
348                   databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
349                   wait_feature: ENABLE or DISABLE
350                   common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
351                     databus_hiztime: 0x01U~0xFFU
352                     holdtime: 0x01U~0xFEU
353                     waittime: 0x02U~0xFFU
354                     setuptime: 0x01U~0xFFU
355                   attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
356                     databus_hiztime: 0x00U~0xFEU
357                     holdtime: 0x01U~0xFEU
358                     waittime: 0x02U~0xFFU
359                     setuptime: 0x01U~0xFFU
360     \param[out] none
361     \retval     none
362 */
exmc_nand_init(exmc_nand_parameter_struct * exmc_nand_init_struct)363 void exmc_nand_init(exmc_nand_parameter_struct *exmc_nand_init_struct)
364 {
365     uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U;
366 
367     npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
368             EXMC_NPCTL_NDTP |
369             exmc_nand_init_struct->databus_width |
370             (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET) |
371             exmc_nand_init_struct->ecc_size |
372             exmc_nand_init_struct->ctr_latency |
373             exmc_nand_init_struct->atr_latency;
374 
375     npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET) |
376               (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT) |
377               ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD) |
378               (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ);
379 
380     npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET) |
381               (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT) |
382               ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD) |
383               ((exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ);
384 
385     /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */
386     EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl;
387     EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg;
388     EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg;
389 }
390 
391 /*!
392     \brief    enable NAND bank
393     \param[in]  exmc_nand_bank: specify the NAND bank
394                 only one parameter can be selected which is shown as below:
395       \arg        EXMC_BANKx_NAND(x=1,2)
396     \param[out] none
397     \retval     none
398 */
exmc_nand_enable(uint32_t exmc_nand_bank)399 void exmc_nand_enable(uint32_t exmc_nand_bank)
400 {
401     EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN;
402 }
403 
404 /*!
405     \brief    disable NAND bank
406     \param[in]  exmc_nand_bank: specify the NAND bank
407                 only one parameter can be selected which is shown as below:
408       \arg        EXMC_BANKx_NAND(x=1,2)
409     \param[out] none
410     \retval     none
411 */
exmc_nand_disable(uint32_t exmc_nand_bank)412 void exmc_nand_disable(uint32_t exmc_nand_bank)
413 {
414     EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_NDBKEN;
415 }
416 
417 /*!
418     \brief    deinitialize EXMC PC card bank
419     \param[in]  none
420     \param[out] none
421     \retval     none
422 */
exmc_pccard_deinit(void)423 void exmc_pccard_deinit(void)
424 {
425     /* EXMC_BANK3_PCCARD */
426     EXMC_NPCTL3 = BANK3_NPCTL_RESET;
427     EXMC_NPINTEN3 = BANK3_NPINTEN_RESET;
428     EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET;
429     EXMC_NPATCFG3 = BANK3_NPATCFG_RESET;
430     EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET;
431 }
432 
433 /*!
434     \brief    initialize exmc_pccard_parameter_struct with the default values
435     \param[in]  none
436     \param[out] the initialized struct exmc_pccard_parameter_struct pointer
437     \retval     none
438 */
exmc_pccard_struct_para_init(exmc_pccard_parameter_struct * exmc_pccard_init_struct)439 void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct *exmc_pccard_init_struct)
440 {
441     /* configure the structure with default values */
442     exmc_pccard_init_struct->wait_feature = DISABLE;
443     exmc_pccard_init_struct->ctr_latency = 0x0U;
444     exmc_pccard_init_struct->atr_latency = 0x0U;
445     exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU;
446     exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU;
447     exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU;
448     exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU;
449     exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU;
450     exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU;
451     exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU;
452     exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
453     exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU;
454     exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU;
455     exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU;
456     exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU;
457 }
458 
459 /*!
460     \brief    initialize EXMC PC card bank
461     \param[in]  exmc_pccard_parameter_struct: configure the EXMC NAND parameter
462                   atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
463                   ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
464                   wait_feature: ENABLE or DISABLE
465                   common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
466                     databus_hiztime: 0x01U~0xFFU
467                     holdtime: 0x01U~0xFEU
468                     waittime: 0x02U~0xFFU
469                     setuptime: 0x01U~0xFFU
470                   attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
471                     databus_hiztime: 0x00U~0xFEU
472                     holdtime: 0x01U~0xFEU
473                     waittime: 0x02U~0xFFU
474                     setuptime: 0x01U~0xFFU
475                   io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time
476                     databus_hiztime: 0x00U~0xFFU
477                     holdtime: 0x01U~0xFFU
478                     waittime: 0x02U~0x100U
479                     setuptime: 0x01U~0x100U
480     \param[out] none
481     \retval     none
482 */
exmc_pccard_init(exmc_pccard_parameter_struct * exmc_pccard_init_struct)483 void exmc_pccard_init(exmc_pccard_parameter_struct *exmc_pccard_init_struct)
484 {
485     /* configure the EXMC bank3 PC card control register */
486     EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
487                   EXMC_NAND_DATABUS_WIDTH_16B |
488                   exmc_pccard_init_struct->ctr_latency |
489                   exmc_pccard_init_struct->atr_latency ;
490 
491     /* configure the EXMC bank3 PC card common space timing configuration register */
492     EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET) |
493                     (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT) |
494                     ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD) |
495                     (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ);
496 
497     /* configure the EXMC bank3 PC card attribute space timing configuration register */
498     EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET) |
499                     (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT) |
500                     ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD) |
501                     ((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ);
502 
503     /* configure the EXMC bank3 PC card io space timing configuration register */
504     EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET) |
505                     (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT) |
506                     ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD) |
507                     ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ);
508 }
509 
510 /*!
511     \brief    enable PC Card Bank
512     \param[in]  none
513     \param[out] none
514     \retval     none
515 */
exmc_pccard_enable(void)516 void exmc_pccard_enable(void)
517 {
518     EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN;
519 }
520 
521 /*!
522     \brief    disable PC Card Bank
523     \param[in]  none
524     \param[out] none
525     \retval     none
526 */
exmc_pccard_disable(void)527 void exmc_pccard_disable(void)
528 {
529     EXMC_NPCTL3 &= ~EXMC_NPCTL_NDBKEN;
530 }
531 
532 /*!
533     \brief    deinitialize EXMC SDRAM device
534    \param[in]   exmc_sdram_device: select the SRAM device
535                 only one parameter can be selected which is shown as below:
536       \arg        EXMC_SDRAM_DEVICEx(x=0, 1)
537     \param[in]  none
538     \param[out] none
539     \retval     none
540 */
exmc_sdram_deinit(uint32_t exmc_sdram_device)541 void exmc_sdram_deinit(uint32_t exmc_sdram_device)
542 {
543     /* reset SDRAM registers */
544     EXMC_SDCTL(exmc_sdram_device) = SDRAM_DEVICE_SDCTL_RESET;
545     EXMC_SDTCFG(exmc_sdram_device) = SDRAM_DEVICE_SDTCFG_RESET;
546     EXMC_SDCMD = SDRAM_DEVICE_SDCMD_RESET;
547     EXMC_SDARI = SDRAM_DEVICE_SDARI_RESET;
548     EXMC_SDRSCTL = SDRAM_DEVICE_SDRSCTL_RESET;
549 }
550 
551 /*!
552     \brief    initialize exmc_sdram_parameter_struct with the default values
553     \param[in]  none
554     \param[out] the initialized struct exmc_pccard_parameter_struct pointer
555     \retval     none
556 */
exmc_sdram_struct_para_init(exmc_sdram_parameter_struct * exmc_sdram_init_struct)557 void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct)
558 {
559     /* configure the structure with default values */
560     exmc_sdram_init_struct->sdram_device = EXMC_SDRAM_DEVICE0;
561     exmc_sdram_init_struct->column_address_width = EXMC_SDRAM_COW_ADDRESS_8;
562     exmc_sdram_init_struct->row_address_width = EXMC_SDRAM_ROW_ADDRESS_11;
563     exmc_sdram_init_struct->data_width = EXMC_SDRAM_DATABUS_WIDTH_16B;
564     exmc_sdram_init_struct->internal_bank_number = EXMC_SDRAM_4_INTER_BANK;
565     exmc_sdram_init_struct->cas_latency = EXMC_CAS_LATENCY_1_SDCLK;
566     exmc_sdram_init_struct->write_protection = ENABLE;
567     exmc_sdram_init_struct->sdclock_config = EXMC_SDCLK_DISABLE;
568     exmc_sdram_init_struct->brust_read_switch = DISABLE;
569     exmc_sdram_init_struct->pipeline_read_delay = EXMC_PIPELINE_DELAY_0_HCLK;
570 
571     exmc_sdram_init_struct->timing->load_mode_register_delay = 16U;
572     exmc_sdram_init_struct->timing->exit_selfrefresh_delay = 16U;
573     exmc_sdram_init_struct->timing->row_address_select_delay = 16U;
574     exmc_sdram_init_struct->timing->auto_refresh_delay = 16U;
575     exmc_sdram_init_struct->timing->write_recovery_delay = 16U;
576     exmc_sdram_init_struct->timing->row_precharge_delay = 16U;
577     exmc_sdram_init_struct->timing->row_to_column_delay = 16U;
578 }
579 
580 /*!
581     \brief    initialize EXMC SDRAM device
582     \param[in]  exmc_sdram_parameter_struct: configure the EXMC SDRAM parameter
583                   sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1
584                   pipeline_read_delay: EXMC_PIPELINE_DELAY_x_HCLK,x=0..2
585                   brust_read_switch: ENABLE or DISABLE
586                   sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_HCLK,EXMC_SDCLK_PERIODS_3_HCLK
587                   write_protection: ENABLE or DISABLE
588                   cas_latency: EXMC_CAS_LATENCY_x_SDCLK,x=1..3
589                   internal_bank_number: EXMC_SDRAM_2_INTER_BANK,EXMC_SDRAM_4_INTER_BANK
590                   data_width: EXMC_SDRAM_DATABUS_WIDTH_8B,EXMC_SDRAM_DATABUS_WIDTH_16B,EXMC_SDRAM_DATABUS_WIDTH_32B
591                   row_address_width: EXMC_SDRAM_ROW_ADDRESS_x,x=11..13
592                   column_address_width: EXMC_SDRAM_COW_ADDRESS_x,x=8..11
593                   timing: exmc_sdram_timing_parameter_struct set the time
594                     row_to_column_delay: 1U~16U
595                     row_precharge_delay: 1U~16U
596                     write_recovery_delay: 1U~16U
597                     auto_refresh_delay: 1U~16U
598                     row_address_select_delay: 1U~16U
599                     exit_selfrefresh_delay: 1U~16U
600                     load_mode_register_delay: 1U~16U
601     \param[out] none
602     \retval     none
603 */
exmc_sdram_init(exmc_sdram_parameter_struct * exmc_sdram_init_struct)604 void exmc_sdram_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct)
605 {
606     uint32_t sdctl0, sdctl1, sdtcfg0, sdtcfg1;
607 
608     /* configuration EXMC_SDCTL0 or EXMC_SDCTL1 */
609     if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device) {
610         /* configuration EXMC_SDCTL0 */
611         EXMC_SDCTL(EXMC_SDRAM_DEVICE0)  = (uint32_t)exmc_sdram_init_struct->column_address_width |
612                                           exmc_sdram_init_struct->row_address_width |
613                                           exmc_sdram_init_struct->data_width |
614                                           exmc_sdram_init_struct->internal_bank_number |
615                                           exmc_sdram_init_struct->cas_latency |
616                                           (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET) |
617                                           exmc_sdram_init_struct->sdclock_config |
618                                           (exmc_sdram_init_struct->brust_read_switch << SDCTL_BRSTRD_OFFSET) |
619                                           exmc_sdram_init_struct->pipeline_read_delay;
620 
621         /* configuration EXMC_SDTCFG0 */
622         EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) |
623                                           (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) |
624                                           (((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) |
625                                           (((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) |
626                                           (((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET) |
627                                           (((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) |
628                                           (((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET);
629     } else {
630         /* configuration EXMC_SDCTL0 and EXMC_SDCTL1 */
631         /* some bits in the EXMC_SDCTL1 register are reserved */
632         sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK));
633 
634         sdctl0 |= (uint32_t)exmc_sdram_init_struct->sdclock_config |
635                   exmc_sdram_init_struct->brust_read_switch |
636                   exmc_sdram_init_struct->pipeline_read_delay;
637 
638         sdctl1 = (uint32_t)exmc_sdram_init_struct->column_address_width |
639                  exmc_sdram_init_struct->row_address_width |
640                  exmc_sdram_init_struct->data_width |
641                  exmc_sdram_init_struct->internal_bank_number |
642                  exmc_sdram_init_struct->cas_latency |
643                  exmc_sdram_init_struct->write_protection ;
644 
645         EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0;
646         EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1;
647 
648         /* configuration EXMC_SDTCFG0 and EXMC_SDTCFG1 */
649         /* some bits in the EXMC_SDTCFG1 register are reserved */
650         sdtcfg0 = EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDTCFG_RPD | EXMC_SDTCFG_WRD | EXMC_SDTCFG_ARFD));
651 
652         sdtcfg0 |= (uint32_t)(((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) |
653                    (((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) |
654                    (((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET);
655 
656         sdtcfg1 = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) |
657                   (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) |
658                   (((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) |
659                   (((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET);
660 
661         EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = sdtcfg0;
662         EXMC_SDTCFG(EXMC_SDRAM_DEVICE1) = sdtcfg1;
663     }
664 }
665 
666 /*!
667     \brief    deinitialize exmc SQPIPSRAM
668     \param[in]  none
669     \param[out] none
670     \retval     none
671 */
exmc_sqpipsram_deinit(void)672 void exmc_sqpipsram_deinit(void)
673 {
674     /* reset the registers */
675     EXMC_SINIT = BANK0_SQPI_SINIT_RESET;
676     EXMC_SRCMD = BANK0_SQPI_SRCMD_RESET;
677     EXMC_SWCMD = BANK0_SQPI_SWCMD_RESET;
678     EXMC_SIDL = BANK0_SQPI_SIDL_RESET;
679     EXMC_SIDH = BANK0_SQPI_SIDH_RESET;
680 }
681 
682 /*!
683     \brief    initialize exmc_sqpipsram_parameter_struct with the default values
684     \param[in]  the struct exmc_sqpipsram_parameter_struct pointer
685     \param[out] none
686     \retval     none
687 */
exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct * exmc_sqpipsram_init_struct)688 void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct *exmc_sqpipsram_init_struct)
689 {
690     /* configure the structure with default values */
691     exmc_sqpipsram_init_struct->sample_polarity = EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE;
692     exmc_sqpipsram_init_struct->id_length = EXMC_SQPIPSRAM_ID_LENGTH_64B;
693     exmc_sqpipsram_init_struct->address_bits = EXMC_SQPIPSRAM_ADDR_LENGTH_24B;
694     exmc_sqpipsram_init_struct->command_bits = EXMC_SQPIPSRAM_COMMAND_LENGTH_8B;
695 }
696 
697 /*!
698     \brief    initialize EXMC SQPIPSRAM
699     \param[in]  exmc_sqpipsram_parameter_struct: configure the EXMC SQPIPSRAM parameter
700                   sample_polarity: EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE,EXMC_SQPIPSRAM_SAMPLE_FALLING_EDGE
701                   id_length: EXMC_SQPIPSRAM_ID_LENGTH_xB,x=8,16,32,64
702                   address_bits: EXMC_SQPIPSRAM_ADDR_LENGTH_xB,x=1..26
703                   command_bits: EXMC_SQPIPSRAM_COMMAND_LENGTH_xB,x=4,8,16
704     \param[out] none
705     \retval     none
706 */
exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct * exmc_sqpipsram_init_struct)707 void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct *exmc_sqpipsram_init_struct)
708 {
709     /* initialize SQPI controller */
710     EXMC_SINIT = (uint32_t)exmc_sqpipsram_init_struct->sample_polarity |
711                  exmc_sqpipsram_init_struct->id_length |
712                  exmc_sqpipsram_init_struct->address_bits |
713                  exmc_sqpipsram_init_struct->command_bits;
714 }
715 
716 /*!
717     \brief    configure consecutive clock
718     \param[in]  clock_mode: specify when the clock is generated
719                 only one parameter can be selected which is shown as below:
720       \arg        EXMC_CLOCK_SYN_MODE: the clock is generated only during synchronous access
721       \arg        EXMC_CLOCK_UNCONDITIONALLY: the clock is generated unconditionally
722     \param[out] none
723     \retval     none
724 */
exmc_norsram_consecutive_clock_config(uint32_t clock_mode)725 void exmc_norsram_consecutive_clock_config(uint32_t clock_mode)
726 {
727     if(EXMC_CLOCK_UNCONDITIONALLY == clock_mode) {
728         EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_CLOCK_UNCONDITIONALLY;
729     } else {
730         EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_CLOCK_UNCONDITIONALLY;
731     }
732 }
733 
734 /*!
735     \brief    configure CRAM page size
736     \param[in]  exmc_norsram_region: select the region of bank0
737                 only one parameter can be selected which is shown as below:
738       \arg        EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
739     \param[in]  page_size: CRAM page size
740                 only one parameter can be selected which is shown as below:
741       \arg        EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
742       \arg        EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
743       \arg        EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
744       \arg        EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
745       \arg        EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
746     \param[out] none
747     \retval     none
748 */
exmc_norsram_page_size_config(uint32_t exmc_norsram_region,uint32_t page_size)749 void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_size)
750 {
751     /* reset the bits */
752     EXMC_SNCTL(exmc_norsram_region) &= ~EXMC_SNCTL_CPS;
753 
754     /* set the CPS bits */
755     EXMC_SNCTL(exmc_norsram_region) |= page_size;
756 }
757 
758 /*!
759     \brief    enable or disable the EXMC NAND ECC function
760     \param[in]  exmc_nand_bank: specify the NAND bank
761                 only one parameter can be selected which is shown as below:
762       \arg        EXMC_BANKx_NAND(x=1,2)
763     \param[in]  newvalue: ENABLE or DISABLE
764     \param[out] none
765     \retval     none
766 */
exmc_nand_ecc_config(uint32_t exmc_nand_bank,ControlStatus newvalue)767 void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue)
768 {
769     if(ENABLE == newvalue) {
770         /* enable the selected NAND bank ECC function */
771         EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN;
772     } else {
773         /* disable the selected NAND bank ECC function */
774         EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_ECCEN;
775     }
776 }
777 
778 /*!
779     \brief    get the EXMC ECC value
780     \param[in]  exmc_nand_bank: specify the NAND bank
781                 only one parameter can be selected which is shown as below:
782       \arg        EXMC_BANKx_NAND(x=1,2)
783     \param[out] none
784     \retval     the error correction code(ECC) value
785 */
exmc_ecc_get(uint32_t exmc_nand_bank)786 uint32_t exmc_ecc_get(uint32_t exmc_nand_bank)
787 {
788     return(EXMC_NECC(exmc_nand_bank));
789 }
790 
791 /*!
792     \brief    enable or disable read sample
793     \param[in]  newvalue: ENABLE or DISABLE
794     \param[out] none
795     \retval     none
796 */
exmc_sdram_readsample_enable(ControlStatus newvalue)797 void exmc_sdram_readsample_enable(ControlStatus newvalue)
798 {
799     if(ENABLE == newvalue) {
800         EXMC_SDRSCTL |=  EXMC_SDRSCTL_RSEN;
801     } else {
802         EXMC_SDRSCTL &= (uint32_t)(~EXMC_SDRSCTL_RSEN);
803     }
804 }
805 
806 /*!
807     \brief    configure the delayed sample clock of read data
808     \param[in]  delay_cell: SDRAM the delayed sample clock of read data
809                 only one parameter can be selected which is shown as below:
810       \arg        EXMC_SDRAM_x_DELAY_CELL(x=0..15)
811     \param[in]  extra_hclk: sample cycle of read data
812                 only one parameter can be selected which is shown as below:
813       \arg        EXMC_SDRAM_READSAMPLE_x_EXTRAHCLK(x=0,1)
814     \param[out] none
815     \retval     none
816 */
exmc_sdram_readsample_config(uint32_t delay_cell,uint32_t extra_hclk)817 void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk)
818 {
819     uint32_t sdrsctl = 0U;
820 
821     /* reset the bits */
822     sdrsctl = EXMC_SDRSCTL & (~(EXMC_SDRSCTL_SDSC | EXMC_SDRSCTL_SSCR));
823     /* set the bits */
824     sdrsctl |= (uint32_t)(delay_cell | extra_hclk);
825     EXMC_SDRSCTL = sdrsctl;
826 }
827 
828 /*!
829     \brief    configure the SDRAM memory command
830     \param[in]  exmc_sdram_command_init_struct: initialize EXMC SDRAM command
831                   mode_register_content:
832                   auto_refresh_number: EXMC_SDRAM_AUTO_REFLESH_x_SDCLK, x=1..15
833                   bank_select: EXMC_SDRAM_DEVICE0_SELECT, EXMC_SDRAM_DEVICE1_SELECT, EXMC_SDRAM_DEVICE0_1_SELECT
834                   command: EXMC_SDRAM_NORMAL_OPERATION, EXMC_SDRAM_CLOCK_ENABLE, EXMC_SDRAM_PRECHARGE_ALL,
835                            EXMC_SDRAM_AUTO_REFRESH, EXMC_SDRAM_LOAD_MODE_REGISTER, EXMC_SDRAM_SELF_REFRESH,
836                            EXMC_SDRAM_POWERDOWN_ENTRY
837     \param[out] none
838     \retval     none
839 */
exmc_sdram_command_config(exmc_sdram_command_parameter_struct * exmc_sdram_command_init_struct)840 void exmc_sdram_command_config(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct)
841 {
842     /* configure command register */
843     EXMC_SDCMD = (uint32_t)((exmc_sdram_command_init_struct->command) |
844                             (exmc_sdram_command_init_struct->bank_select) |
845                             ((exmc_sdram_command_init_struct->auto_refresh_number)) |
846                             ((exmc_sdram_command_init_struct->mode_register_content) << SDCMD_MRC_OFFSET));
847 }
848 
849 /*!
850     \brief    set auto-refresh interval
851     \param[in]  exmc_count: the number SDRAM clock cycles unit between two successive auto-refresh commands, 0x0000~0x1FFF
852     \param[out] none
853     \retval     none
854 */
exmc_sdram_refresh_count_set(uint32_t exmc_count)855 void exmc_sdram_refresh_count_set(uint32_t exmc_count)
856 {
857     uint32_t sdari;
858     sdari = EXMC_SDARI & (~EXMC_SDARI_ARINTV);
859     EXMC_SDARI = sdari | (uint32_t)((exmc_count << SDARI_ARINTV_OFFSET) & EXMC_SDARI_ARINTV);
860 }
861 
862 /*!
863     \brief    set the number of successive auto-refresh command
864     \param[in]  exmc_number: the number of successive Auto-refresh cycles will be send, 1~15
865     \param[out] none
866     \retval     none
867 */
exmc_sdram_autorefresh_number_set(uint32_t exmc_number)868 void exmc_sdram_autorefresh_number_set(uint32_t exmc_number)
869 {
870     uint32_t sdcmd;
871     sdcmd = EXMC_SDCMD & (~EXMC_SDCMD_NARF);
872     EXMC_SDCMD = sdcmd | (uint32_t)((exmc_number << SDCMD_NARF_OFFSET) & EXMC_SDCMD_NARF) ;
873 }
874 
875 /*!
876     \brief    config the write protection function
877     \param[in]  exmc_sdram_device: specify the SDRAM device
878                 only one parameter can be selected which is shown as below:
879       \arg        EXMC_SDRAM_DEVICEx(x=0,1)
880     \param[in]  newvalue: ENABLE or DISABLE
881     \param[out] none
882     \retval     none
883 */
exmc_sdram_write_protection_config(uint32_t exmc_sdram_device,ControlStatus newvalue)884 void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue)
885 {
886     if(ENABLE == newvalue) {
887         EXMC_SDCTL(exmc_sdram_device) |= (uint32_t)EXMC_SDCTL_WPEN;
888     } else {
889         EXMC_SDCTL(exmc_sdram_device) &= ~((uint32_t)EXMC_SDCTL_WPEN);
890     }
891 
892 }
893 
894 /*!
895     \brief    get the status of SDRAM device0 or device1
896     \param[in]  exmc_sdram_device: specify the SDRAM device
897                 only one parameter can be selected which is shown as below:
898       \arg        EXMC_SDRAM_DEVICEx(x=0,1)
899     \param[out] none
900     \retval     the status of SDRAM device
901 */
exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device)902 uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device)
903 {
904     uint32_t sdstat = 0U;
905 
906     if(EXMC_SDRAM_DEVICE0 == exmc_sdram_device) {
907         sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA0) >> SDSTAT_STA0_OFFSET);
908     } else {
909         sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA1) >> SDSTAT_STA1_OFFSET);
910     }
911 
912     return sdstat;
913 }
914 
915 /*!
916     \brief    set the read command
917     \param[in]  read_command_mode: configure SPI PSRAM read command mode
918                 only one parameter can be selected which is shown as below:
919       \arg        EXMC_SQPIPSRAM_READ_MODE_DISABLE: not SPI mode
920       \arg        EXMC_SQPIPSRAM_READ_MODE_SPI: SPI mode
921       \arg        EXMC_SQPIPSRAM_READ_MODE_SQPI: SQPI mode
922       \arg        EXMC_SQPIPSRAM_READ_MODE_QPI: QPI mode
923     \param[in]  read_wait_cycle: wait cycle number after address phase,0..15
924     \param[in]  read_command_code: read command for AHB read transfer
925     \param[out] none
926     \retval     none
927 */
exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle,uint32_t read_command_code)928 void exmc_sqpipsram_read_command_set(uint32_t read_command_mode, uint32_t read_wait_cycle, uint32_t read_command_code)
929 {
930     uint32_t srcmd;
931 
932     srcmd = (uint32_t) read_command_mode |
933             ((read_wait_cycle << SRCMD_RWAITCYCLE_OFFSET) & EXMC_SRCMD_RWAITCYCLE) |
934             ((read_command_code & EXMC_SRCMD_RCMD));
935     EXMC_SRCMD = srcmd;
936 }
937 
938 /*!
939     \brief    set the write command
940     \param[in]  write_command_mode: configure SPI PSRAM write command mode
941                 only one parameter can be selected which is shown as below:
942       \arg        EXMC_SQPIPSRAM_WRITE_MODE_DISABLE: not SPI mode
943       \arg        EXMC_SQPIPSRAM_WRITE_MODE_SPI: SPI mode
944       \arg        EXMC_SQPIPSRAM_WRITE_MODE_SQPI: SQPI mode
945       \arg        EXMC_SQPIPSRAM_WRITE_MODE_QPI: QPI mode
946     \param[in]  write_wait_cycle: wait cycle number after address phase,0..15
947     \param[in]  write_command_code: read command for AHB read transfer
948     \param[out] none
949     \retval     none
950 */
exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle,uint32_t write_command_code)951 void exmc_sqpipsram_write_command_set(uint32_t write_command_mode, uint32_t write_wait_cycle, uint32_t write_command_code)
952 {
953     uint32_t swcmd;
954 
955     swcmd = (uint32_t) write_command_mode |
956             ((write_wait_cycle << SWCMD_WWAITCYCLE_OFFSET) & EXMC_SWCMD_WWAITCYCLE) |
957             ((write_command_code & EXMC_SWCMD_WCMD));
958     EXMC_SWCMD = swcmd;
959 }
960 
961 /*!
962     \brief    send SPI read ID command
963     \param[in]  none
964     \param[out] none
965     \retval     none
966 */
exmc_sqpipsram_read_id_command_send(void)967 void exmc_sqpipsram_read_id_command_send(void)
968 {
969     EXMC_SRCMD |= EXMC_SRCMD_RDID;
970 }
971 
972 /*!
973     \brief    send SPI special command which does not have address and data phase
974     \param[in]  none
975     \param[out] none
976     \retval     none
977 */
exmc_sqpipsram_write_cmd_send(void)978 void exmc_sqpipsram_write_cmd_send(void)
979 {
980     EXMC_SWCMD |= EXMC_SWCMD_SC;
981 }
982 
983 /*!
984     \brief    get the EXMC SPI ID low data
985     \param[in]  none
986     \param[out] none
987     \retval     the ID low data
988 */
exmc_sqpipsram_low_id_get(void)989 uint32_t exmc_sqpipsram_low_id_get(void)
990 {
991     return (EXMC_SIDL);
992 }
993 
994 /*!
995     \brief    get the EXMC SPI ID high data
996     \param[in]  none
997     \param[out] none
998     \retval     the ID high data
999 */
exmc_sqpipsram_high_id_get(void)1000 uint32_t exmc_sqpipsram_high_id_get(void)
1001 {
1002     return (EXMC_SIDH);
1003 }
1004 
1005 /*!
1006     \brief    get the bit value of EXMC send write command bit or read ID command
1007     \param[in]  send_command_flag: the send command flag
1008                 only one parameter can be selected which is shown as below:
1009       \arg        EXMC_SEND_COMMAND_FLAG_RDID: EXMC_SRCMD_RDID flag bit
1010       \arg        EXMC_SEND_COMMAND_FLAG_SC: EXMC_SWCMD_SC flag bit
1011     \param[out] none
1012     \retval     the new value of send command flag
1013 */
exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag)1014 FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag)
1015 {
1016     uint32_t flag = 0x00000000U;
1017 
1018     if(EXMC_SEND_COMMAND_FLAG_RDID == send_command_flag) {
1019         flag = EXMC_SRCMD;
1020     } else if(EXMC_SEND_COMMAND_FLAG_SC == send_command_flag) {
1021         flag = EXMC_SWCMD;
1022     } else {
1023     }
1024 
1025     if(flag & send_command_flag) {
1026         /* flag is set */
1027         return SET;
1028     } else {
1029         /* flag is reset */
1030         return RESET;
1031     }
1032 }
1033 
1034 /*!
1035     \brief    enable EXMC interrupt
1036     \param[in]  exmc_bank: specify the NAND bank,PC card bank or SDRAM device
1037                 only one parameter can be selected which is shown as below:
1038       \arg        EXMC_BANK1_NAND: the NAND bank1
1039       \arg        EXMC_BANK2_NAND: the NAND bank2
1040       \arg        EXMC_BANK3_PCCARD: the PC card bank
1041       \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
1042       \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
1043     \param[in]  interrupt: specify EXMC interrupt flag
1044                 only one parameter can be selected which is shown as below:
1045       \arg        EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
1046       \arg        EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
1047       \arg        EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
1048       \arg        EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag
1049     \param[out] none
1050     \retval     none
1051 */
exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt)1052 void exmc_interrupt_enable(uint32_t exmc_bank, uint32_t interrupt)
1053 {
1054     if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) {
1055         /* NAND bank1,bank2 or PC card bank3 */
1056         EXMC_NPINTEN(exmc_bank) |= interrupt;
1057     } else {
1058         /* SDRAM device0 or device1 */
1059         EXMC_SDARI |= EXMC_SDARI_REIE;
1060     }
1061 }
1062 
1063 /*!
1064     \brief    disable EXMC interrupt
1065     \param[in]  exmc_bank: specify the NAND bank , PC card bank or SDRAM device
1066                 only one parameter can be selected which is shown as below:
1067       \arg        EXMC_BANK1_NAND: the NAND bank1
1068       \arg        EXMC_BANK2_NAND: the NAND bank2
1069       \arg        EXMC_BANK3_PCCARD: the PC card bank
1070       \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
1071       \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
1072     \param[in]  interrupt: specify EXMC interrupt flag
1073                 only one parameter can be selected which is shown as below:
1074       \arg        EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
1075       \arg        EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
1076       \arg        EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
1077       \arg        EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag
1078     \param[out] none
1079     \retval     none
1080 */
exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt)1081 void exmc_interrupt_disable(uint32_t exmc_bank, uint32_t interrupt)
1082 {
1083     if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) {
1084         /* NAND bank1,bank2 or PC card bank3 */
1085         EXMC_NPINTEN(exmc_bank) &= ~interrupt;
1086     } else {
1087         /* SDRAM device0 or device1 */
1088         EXMC_SDARI &= ~EXMC_SDARI_REIE;
1089     }
1090 }
1091 
1092 /*!
1093     \brief    get EXMC flag status
1094     \param[in]  exmc_bank: specify the NAND bank , PC card bank or SDRAM device
1095                 only one parameter can be selected which is shown as below:
1096       \arg        EXMC_BANK1_NAND: the NAND bank1
1097       \arg        EXMC_BANK2_NAND: the NAND bank2
1098       \arg        EXMC_BANK3_PCCARD: the PC Card bank
1099       \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
1100       \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
1101     \param[in]  flag: EXMC status and flag
1102                 only one parameter can be selected which is shown as below:
1103       \arg        EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
1104       \arg        EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
1105       \arg        EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
1106       \arg        EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
1107       \arg        EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag
1108       \arg        EXMC_SDRAM_FLAG_NREADY: not ready status
1109     \param[out] none
1110     \retval     FlagStatus: SET or RESET
1111 */
exmc_flag_get(uint32_t exmc_bank,uint32_t flag)1112 FlagStatus exmc_flag_get(uint32_t exmc_bank, uint32_t flag)
1113 {
1114     uint32_t status = 0x00000000U;
1115 
1116     if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) {
1117         /* NAND bank1,bank2 or PC card bank3 */
1118         status = EXMC_NPINTEN(exmc_bank);
1119     } else {
1120         /* SDRAM device0 or device1 */
1121         status = EXMC_SDSTAT;
1122     }
1123 
1124     if((status & flag) != (uint32_t)flag) {
1125         /* flag is reset */
1126         return RESET;
1127     } else {
1128         /* flag is set */
1129         return SET;
1130     }
1131 }
1132 
1133 /*!
1134     \brief    clear EXMC flag status
1135     \param[in]  exmc_bank: specify the NAND bank , PCCARD bank or SDRAM device
1136                 only one parameter can be selected which is shown as below:
1137       \arg        EXMC_BANK1_NAND: the NAND bank1
1138       \arg        EXMC_BANK2_NAND: the NAND bank2
1139       \arg        EXMC_BANK3_PCCARD: the PC card bank
1140       \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
1141       \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
1142     \param[in]  flag: EXMC status and flag
1143                 only one parameter can be selected which is shown as below:
1144       \arg        EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
1145       \arg        EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
1146       \arg        EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
1147       \arg        EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
1148       \arg        EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag
1149       \arg        EXMC_SDRAM_FLAG_NREADY: not ready status
1150     \param[out] none
1151     \retval     none
1152 */
exmc_flag_clear(uint32_t exmc_bank,uint32_t flag)1153 void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag)
1154 {
1155     if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) {
1156         /* NAND bank1,bank2 or PC card bank3 */
1157         EXMC_NPINTEN(exmc_bank) &= ~flag;
1158     } else {
1159         /* SDRAM device0 or device1 */
1160         EXMC_SDSTAT &= ~flag;
1161     }
1162 }
1163 
1164 /*!
1165     \brief    get EXMC interrupt flag
1166     \param[in]  exmc_bank: specify the NAND bank , PC card bank or SDRAM device
1167                 only one parameter can be selected which is shown as below:
1168       \arg        EXMC_BANK1_NAND: the NAND bank1
1169       \arg        EXMC_BANK2_NAND: the NAND bank2
1170       \arg        EXMC_BANK3_PCCARD: the PC card bank
1171       \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
1172       \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
1173     \param[in]  interrupt: EXMC interrupt flag
1174                 only one parameter can be selected which is shown as below:
1175       \arg        EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
1176       \arg        EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
1177       \arg        EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
1178       \arg        EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag
1179     \param[out] none
1180     \retval     FlagStatus: SET or RESET
1181 */
exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt)1182 FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank, uint32_t interrupt)
1183 {
1184     uint32_t status = 0x00000000U, interrupt_enable = 0x00000000U, interrupt_state = 0x00000000U;
1185 
1186     if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) {
1187         /* NAND bank1,bank2 or PC card bank3 */
1188         status = EXMC_NPINTEN(exmc_bank);
1189         interrupt_state = (status & (interrupt >> INTEN_INTS_OFFSET));
1190     } else {
1191         /* SDRAM device0 or device1 */
1192         status = EXMC_SDARI;
1193         interrupt_state = (EXMC_SDSTAT & EXMC_SDSDAT_REIF);
1194     }
1195 
1196     interrupt_enable = (status & interrupt);
1197 
1198     if((interrupt_enable) && (interrupt_state)) {
1199         /* interrupt flag is set */
1200         return SET;
1201     } else {
1202         /* interrupt flag is reset */
1203         return RESET;
1204     }
1205 }
1206 
1207 /*!
1208     \brief    clear EXMC interrupt flag
1209     \param[in]  exmc_bank: specify the NAND bank , PC card bank or SDRAM device
1210                 only one parameter can be selected which is shown as below:
1211       \arg        EXMC_BANK1_NAND: the NAND bank1
1212       \arg        EXMC_BANK2_NAND: the NAND bank2
1213       \arg        EXMC_BANK3_PCCARD: the PC card bank
1214       \arg        EXMC_SDRAM_DEVICE0: the SDRAM device0
1215       \arg        EXMC_SDRAM_DEVICE1: the SDRAM device1
1216     \param[in]  interrupt: EXMC interrupt flag
1217                 only one parameter can be selected which is shown as below:
1218       \arg        EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag
1219       \arg        EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag
1220       \arg        EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and flag
1221       \arg        EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag
1222     \param[out] none
1223     \retval     none
1224 */
exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt)1225 void exmc_interrupt_flag_clear(uint32_t exmc_bank, uint32_t interrupt)
1226 {
1227     if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) {
1228         /* NAND bank1,bank2 or PC card bank3 */
1229         EXMC_NPINTEN(exmc_bank) &= ~(interrupt >> INTEN_INTS_OFFSET);
1230     } else {
1231         /* SDRAM device0 or device1 */
1232         EXMC_SDARI |= EXMC_SDARI_REC;
1233     }
1234 }
1235