1 /*!
2 \file gd32vf103_exmc.c
3 \brief EXMC driver
4
5 \version 2019-06-05, V1.0.0, firmware for GD32VF103
6 \version 2020-08-04, V1.1.0, firmware for GD32VF103
7 */
8
9 /*
10 Copyright (c) 2020, GigaDevice Semiconductor Inc.
11
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14
15 1. Redistributions of source code must retain the above copyright notice, this
16 list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright notice,
18 this list of conditions and the following disclaimer in the documentation
19 and/or other materials provided with the distribution.
20 3. Neither the name of the copyright holder nor the names of its contributors
21 may be used to endorse or promote products derived from this software without
22 specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGE.
34 */
35
36 #include "gd32vf103_exmc.h"
37
38 /* EXMC bank0 register reset value */
39 #define BANK0_SNCTL0_REGION_RESET ((uint32_t)0x000030DAU)
40 #define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
41
42 /* EXMC register bit offset */
43 #define SNCTL_NRMUX_OFFSET ((uint32_t)1U)
44 #define SNCTL_WREN_OFFSET ((uint32_t)12U)
45 #define SNCTL_NRWTEN_OFFSET ((uint32_t)13U)
46 #define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U)
47
48 #define SNTCFG_AHLD_OFFSET ((uint32_t)4U)
49 #define SNTCFG_DSET_OFFSET ((uint32_t)8U)
50 #define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U)
51
52 /*!
53 \brief deinitialize EXMC NOR/SRAM region
54 \param[in] norsram_region: select the region of bank0
55 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0)
56 \param[out] none
57 \retval none
58 */
exmc_norsram_deinit(uint32_t norsram_region)59 void exmc_norsram_deinit(uint32_t norsram_region)
60 {
61 /* reset the registers */
62 if(EXMC_BANK0_NORSRAM_REGION0 == norsram_region){
63 EXMC_SNCTL(norsram_region) = BANK0_SNCTL0_REGION_RESET;
64 }
65
66 EXMC_SNTCFG(norsram_region) = BANK0_SNTCFG_RESET;
67 }
68
69 /*!
70 \brief initialize the structure exmc_norsram_parameter_struct
71 \param[in] none
72 \param[out] exmc_norsram_init_struct: the initialized structure exmc_norsram_parameter_struct pointer
73 \retval none
74 */
exmc_norsram_struct_para_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)75 void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
76 {
77 /* configure the structure with default value */
78 exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0;
79 exmc_norsram_init_struct->address_data_mux = ENABLE;
80 exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM;
81 exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
82 exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
83 exmc_norsram_init_struct->memory_write = ENABLE;
84 exmc_norsram_init_struct->nwait_signal = ENABLE;
85 exmc_norsram_init_struct->asyn_wait = DISABLE;
86
87 /* read/write timing configure */
88 exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
89 exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
90 exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
91 exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
92 }
93
94 /*!
95 \brief initialize EXMC NOR/SRAM region
96 \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
97 norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0
98 asyn_wait: ENABLE or DISABLE
99 nwait_signal: ENABLE or DISABLE
100 memory_write: ENABLE or DISABLE
101 nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH
102 databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B
103 memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR
104 address_data_mux: ENABLE
105 read_write_timing: structure exmc_norsram_timing_parameter_struct set the time
106 \param[out] none
107 \retval none
108 */
exmc_norsram_init(exmc_norsram_parameter_struct * exmc_norsram_init_struct)109 void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
110 {
111 uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U;
112
113 /* get the register value */
114 snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
115
116 /* clear relative bits */
117 snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_NRWTPOL |
118 EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_NRMUX));
119
120 snctl |= (uint32_t)((uint32_t)exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
121 exmc_norsram_init_struct->memory_type |
122 exmc_norsram_init_struct->databus_width |
123 exmc_norsram_init_struct->nwait_polarity |
124 ((uint32_t)exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
125 ((uint32_t)exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
126 ((uint32_t)exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET);
127
128 sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )|
129 (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) |
130 (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) |
131 (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT );
132
133 /* nor flash access enable */
134 if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){
135 snctl |= (uint32_t)EXMC_SNCTL_NREN;
136 }
137
138 /* configure the registers */
139 EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
140 EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
141 }
142
143 /*!
144 \brief enable EXMC NOR/PSRAM bank region
145 \param[in] norsram_region: specify the region of NOR/PSRAM bank
146 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0)
147 \param[out] none
148 \retval none
149 */
exmc_norsram_enable(uint32_t norsram_region)150 void exmc_norsram_enable(uint32_t norsram_region)
151 {
152 EXMC_SNCTL(norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
153 }
154
155 /*!
156 \brief disable EXMC NOR/PSRAM bank region
157 \param[in] norsram_region: specify the region of NOR/PSRAM bank
158 \arg EXMC_BANK0_NORSRAM_REGIONx(x=0)
159 \param[out] none
160 \retval none
161 */
exmc_norsram_disable(uint32_t norsram_region)162 void exmc_norsram_disable(uint32_t norsram_region)
163 {
164 EXMC_SNCTL(norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
165 }
166