1 /*!
2 \file gd32e10x_exmc.c
3 \brief EXMC driver
4
5 \version 2017-12-26, V1.0.0, firmware for GD32E10x
6 \version 2020-09-30, V1.1.0, firmware for GD32E10x
7 \version 2020-12-31, V1.2.0, firmware for GD32E10x
8 \version 2022-06-30, V1.3.0, firmware for GD32E10x
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 "gd32e10x_exmc.h"
39
40 /* EXMC bank0 register reset value */
41 #define BANK0_SNCTL_RESET ((uint32_t)0x000030DBU)
42 #define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
43 #define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU)
44
45 /* EXMC register bit offset */
46 #define SNCTL_NRMUX_OFFSET ((uint32_t)1U)
47 #define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U)
48 #define SNCTL_WRAPEN_OFFSET ((uint32_t)10U)
49 #define SNCTL_WREN_OFFSET ((uint32_t)12U)
50 #define SNCTL_NRWTEN_OFFSET ((uint32_t)13U)
51 #define SNCTL_EXMODEN_OFFSET ((uint32_t)14U)
52 #define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U)
53
54 #define SNTCFG_AHLD_OFFSET ((uint32_t)4U)
55 #define SNTCFG_DSET_OFFSET ((uint32_t)8U)
56 #define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U)
57
58 #define SNWTCFG_WAHLD_OFFSET ((uint32_t)4U)
59 #define SNWTCFG_WDSET_OFFSET ((uint32_t)8U)
60 #define SNWTCFG_WBUSLAT_OFFSET ((uint32_t)16U)
61
62 /*!
63 \brief deinitialize EXMC NOR/SRAM bank
64 \param[in] none
65 \param[out] none
66 \retval none
67 */
exmc_norsram_deinit(void)68 void exmc_norsram_deinit(void)
69 {
70 /* reset the registers */
71 EXMC_SNCTL = BANK0_SNCTL_RESET;
72
73 EXMC_SNTCFG = BANK0_SNTCFG_RESET;
74 EXMC_SNWTCFG = BANK0_SNWTCFG_RESET;
75 }
76
77 /*!
78 \brief initialize the struct exmc_norsram_parameter_struct
79 \param[in] none
80 \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer
81 \retval none
82 */
exmc_norsram_struct_para_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)83 void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
84 {
85 /* configure the structure with default value */
86 exmc_norsram_init_struct->address_data_mux = ENABLE;
87 exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_NOR;
88 exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
89 exmc_norsram_init_struct->burst_mode = DISABLE;
90 exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
91 exmc_norsram_init_struct->wrap_burst_mode = DISABLE;
92 exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
93 exmc_norsram_init_struct->memory_write = ENABLE;
94 exmc_norsram_init_struct->nwait_signal = ENABLE;
95 exmc_norsram_init_struct->extended_mode = DISABLE;
96 exmc_norsram_init_struct->asyn_wait = DISABLE;
97 exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
98
99 /* read/write timing configure */
100 exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
101 exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
102 exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
103 exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
104 exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
105 exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK;
106 exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
107
108 /* write timing configure, when extended mode is used */
109 exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU;
110 exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU;
111 exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU;
112 exmc_norsram_init_struct->write_timing->bus_latency = 0xFU;
113 exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
114 }
115
116 /*!
117 \brief initialize EXMC NOR/SRAM bank
118 \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
119 write_mode: EXMC_ASYN_WRITE,EXMC_SYN_WRITE
120 extended_mode: ENABLE or DISABLE
121 asyn_wait: ENABLE or DISABLE
122 nwait_signal: ENABLE or DISABLE
123 memory_write: ENABLE or DISABLE
124 nwait_config: EXMC_NWAIT_CONFIG_BEFORE,EXMC_NWAIT_CONFIG_DURING
125 wrap_burst_mode: ENABLE or DISABLE
126 nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH
127 burst_mode: ENABLE or DISABLE
128 databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B
129 memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR
130 address_data_mux: ENABLE or DISABLE
131 read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
132 write_timing: struct exmc_norsram_timing_parameter_struct set the time
133 \param[out] none
134 \retval none
135 */
exmc_norsram_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)136 void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
137 {
138 uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U, snwtcfg = 0x00000000U;
139
140 /* get the register value */
141 snctl = EXMC_SNCTL;
142
143 /* clear relative bits */
144 snctl &= ((uint32_t)~(EXMC_SNCTL_NRMUX | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
145 EXMC_SNCTL_NREN | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG |
146 EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT |
147 EXMC_SNCTL_SYNCWR ));
148
149 snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
150 exmc_norsram_init_struct->memory_type |
151 exmc_norsram_init_struct->databus_width |
152 (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
153 exmc_norsram_init_struct->nwait_polarity |
154 (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
155 exmc_norsram_init_struct->nwait_config |
156 (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
157 (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
158 (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
159 (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
160 exmc_norsram_init_struct->write_mode;
161
162 sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )|
163 (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) |
164 (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) |
165 (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT )|
166 exmc_norsram_init_struct->read_write_timing->syn_clk_division |
167 exmc_norsram_init_struct->read_write_timing->syn_data_latency |
168 exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
169
170 /* nor flash access enable */
171 if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){
172 snctl |= (uint32_t)EXMC_SNCTL_NREN;
173 }
174
175 /* extended mode configure */
176 if(ENABLE == exmc_norsram_init_struct->extended_mode){
177 snwtcfg = (uint32_t)((exmc_norsram_init_struct->write_timing->asyn_address_setuptime - 1U) & EXMC_SNWTCFG_WASET ) |
178 (((exmc_norsram_init_struct->write_timing->asyn_address_holdtime -1U ) << SNWTCFG_WAHLD_OFFSET ) & EXMC_SNWTCFG_WAHLD )|
179 (((exmc_norsram_init_struct->write_timing->asyn_data_setuptime -1U ) << SNWTCFG_WDSET_OFFSET ) & EXMC_SNWTCFG_WDSET )|
180 (((exmc_norsram_init_struct->write_timing->bus_latency - 1U ) << SNWTCFG_WBUSLAT_OFFSET ) & EXMC_SNWTCFG_WBUSLAT ) |
181 exmc_norsram_init_struct->write_timing->asyn_access_mode;
182 }else{
183 snwtcfg = BANK0_SNWTCFG_RESET;
184 }
185
186 /* configure the registers */
187 EXMC_SNCTL = snctl;
188 EXMC_SNTCFG = sntcfg;
189 EXMC_SNWTCFG = snwtcfg;
190 }
191
192 /*!
193 \brief enable EXMC NOR/PSRAM bank
194 \param[in] none
195 \param[out] none
196 \retval none
197 */
exmc_norsram_enable(void)198 void exmc_norsram_enable(void)
199 {
200 EXMC_SNCTL |= (uint32_t)EXMC_SNCTL_NRBKEN;
201 }
202
203 /*!
204 \brief disable EXMC NOR/PSRAM bank
205 \param[in] none
206 \param[out] none
207 \retval none
208 */
exmc_norsram_disable(void)209 void exmc_norsram_disable(void)
210 {
211 EXMC_SNCTL &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
212 }
213
214 /*!
215 \brief configure CRAM page size
216 \param[in] page_size: CRAM page size
217 only one parameter can be selected which is shown as below:
218 \arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
219 \arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
220 \arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
221 \arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
222 \arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
223 \param[out] none
224 \retval none
225 */
exmc_norsram_page_size_config(uint32_t page_size)226 void exmc_norsram_page_size_config(uint32_t page_size)
227 {
228 /* reset the bits */
229 EXMC_SNCTL &= ~EXMC_SNCTL_CPS;
230 /* set the CPS bits */
231 EXMC_SNCTL |= page_size;
232 }
233