1 /*!
2     \file    gd32f3x0_fmc.h
3     \brief   definitions for the FMC
4 
5     \version 2017-06-06, V1.0.0, firmware for GD32F3x0
6     \version 2019-06-01, V2.0.0, firmware for GD32F3x0
7     \version 2020-09-30, V2.1.0, firmware for GD32F3x0
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 
38 #ifndef GD32F3X0_FMC_H
39 #define GD32F3X0_FMC_H
40 
41 #include "gd32f3x0.h"
42 
43 /* FMC and option byte definition */
44 #define FMC                     FMC_BASE                    /*!< FMC register base address */
45 #define OB                      OB_BASE                     /*!< option byte base address */
46 
47 /* registers definitions */
48 #define FMC_WS                  REG32(FMC + 0x00000000U)    /*!< FMC wait state register */
49 #define FMC_KEY                 REG32(FMC + 0x00000004U)    /*!< FMC unlock key register */
50 #define FMC_OBKEY               REG32(FMC + 0x00000008U)    /*!< FMC option bytes unlock key register */
51 #define FMC_STAT                REG32(FMC + 0x0000000CU)    /*!< FMC status register */
52 #define FMC_CTL                 REG32(FMC + 0x00000010U)    /*!< FMC control register */
53 #define FMC_ADDR                REG32(FMC + 0x00000014U)    /*!< FMC address register */
54 #define FMC_OBSTAT              REG32(FMC + 0x0000001CU)    /*!< FMC option bytes status register */
55 #define FMC_WP                  REG32(FMC + 0x00000020U)    /*!< FMC write protection register */
56 #define FMC_WSEN                REG32(FMC + 0x000000FCU)    /*!< FMC wait state enable register  */
57 #define FMC_PID                 REG32(FMC + 0x00000100U)    /*!< FMC product ID register */
58 
59 #define OB_SPC                  REG16(OB + 0x00000000U)     /*!< option byte security protection value */
60 #define OB_USER                 REG16(OB + 0x00000002U)     /*!< option byte user value*/
61 #define OB_DATA0                REG16(OB + 0x00000004U)     /*!< option byte data bit[7:0] value*/
62 #define OB_DATA1                REG16(OB + 0x00000006U)     /*!< option byte data bit[15:8] value*/
63 #define OB_WP0                  REG16(OB + 0x00000008U)     /*!< option byte write protection 0 */
64 #define OB_WP1                  REG16(OB + 0x0000000AU)     /*!< option byte write protection 1 */
65 
66 /* bits definitions */
67 /* FMC_WS */
68 #define FMC_WS_WSCNT            BITS(0,2)                   /*!< wait state counter */
69 
70 /* FMC_KEY */
71 #define FMC_KEY_KEY             BITS(0,31)                  /*!< FMC main flash unlock key bits */
72 
73 /* FMC_OBKEY */
74 #define FMC_OBKEY_OBKEY         BITS(0,31)                  /*!< option bytes unlock key bits */
75 
76 /* FMC_STAT */
77 #define FMC_STAT_BUSY           BIT(0)                      /*!< flash busy flag bit */
78 #define FMC_STAT_PGERR          BIT(2)                      /*!< flash program error flag bit */
79 #define FMC_STAT_WPERR          BIT(4)                      /*!< flash write protection error flag bit */
80 #define FMC_STAT_ENDF           BIT(5)                      /*!< end of operation flag bit */
81 
82 /* FMC_CTL */
83 #define FMC_CTL_PG              BIT(0)                      /*!< main flash program command bit */
84 #define FMC_CTL_PER             BIT(1)                      /*!< main flash page erase bit */
85 #define FMC_CTL_MER             BIT(2)                      /*!< main flash mass erase bit */
86 #define FMC_CTL_OBPG            BIT(4)                      /*!< option bytes program command bit */
87 #define FMC_CTL_OBER            BIT(5)                      /*!< option bytes erase command bit */
88 #define FMC_CTL_START           BIT(6)                      /*!< send erase command to FMC bit */
89 #define FMC_CTL_LK              BIT(7)                      /*!< flash lock bit */
90 #define FMC_CTL_OBWEN           BIT(9)                      /*!< option bytes erase/program enable bit */
91 #define FMC_CTL_ERRIE           BIT(10)                     /*!< error interrupt enable bit */
92 #define FMC_CTL_ENDIE           BIT(12)                     /*!< end of operation interrupt enable bit */
93 #define FMC_CTL_OBRLD           BIT(13)                     /*!< option bytes reload bit */
94 
95 /* FMC_ADDR */
96 #define FMC_ADDR_ADDR           BITS(0,31)                  /*!< flash command address bits */
97 
98 /* FMC_OBSTAT */
99 #define FMC_OBSTAT_OBERR        BIT(0)                      /*!< option bytes read error bit */
100 #define FMC_OBSTAT_PLEVEL_BIT0  BIT(1)                      /*!< protection level bit 0 */
101 #define FMC_OBSTAT_PLEVEL_BIT1  BIT(2)                      /*!< protection level bit 1 */
102 #define FMC_OBSTAT_USER         BITS(8,15)                  /*!< option bytes user bits */
103 #define FMC_OBSTAT_DATA         BITS(16,31)                 /*!< option byte data bits */
104 
105 /* FMC_WSEN */
106 #define FMC_WSEN_WSEN           BIT(0)                      /*!< FMC wait state enable bit */
107 #define FMC_WSEN_BPEN           BIT(1)                      /*!< FMC bit program enable bit */
108 
109 /* FMC_PID */
110 #define FMC_PID_PID             BITS(0,31)                  /*!< product ID bits */
111 
112 /* constants definitions */
113 /* fmc state */
114 typedef enum
115 {
116     FMC_READY,                                              /*!< the operation has been completed */
117     FMC_BUSY,                                               /*!< the operation is in progress */
118     FMC_PGERR,                                              /*!< program error */
119     FMC_WPERR,                                              /*!< erase/program protection error */
120     FMC_TOERR,                                              /*!< timeout error */
121     FMC_OB_HSPC                                             /*!< option byte security protection code high */
122 }fmc_state_enum;
123 
124 /* option byte parameter */
125 typedef struct
126 {
127     uint8_t spc;                                            /*!< option byte parameter spc */
128     uint8_t user;                                           /*!< option byte parameter user */
129     uint8_t data0;                                          /*!< option byte parameter data0 */
130     uint8_t data1;                                          /*!< option byte parameter data1 */
131     uint8_t wp0;                                            /*!< option byte parameter wp0 */
132     uint8_t wp1;                                            /*!< option byte parameter wp1 */
133 }ob_parm_struct;
134 
135 /* unlock key */
136 #define UNLOCK_KEY0             ((uint32_t)0x45670123U)     /*!< unlock key 0 */
137 #define UNLOCK_KEY1             ((uint32_t)0xCDEF89ABU)     /*!< unlock key 1 */
138 
139 /* wait state counter value */
140 #define WS_WSCNT_0              ((uint8_t)0x00U)            /*!< 0 wait state added */
141 #define WS_WSCNT_1              ((uint8_t)0x01U)            /*!< 1 wait state added */
142 #define WS_WSCNT_2              ((uint8_t)0x02U)            /*!< 2 wait state added */
143 
144 /* read protect configure */
145 #define FMC_NSPC                ((uint8_t)0xA5U)            /*!< no security protection */
146 #define FMC_LSPC                ((uint8_t)0xBBU)            /*!< low security protection, any value except 0xA5 or 0xCC */
147 #define FMC_HSPC                ((uint8_t)0xCCU)            /*!< high security protection */
148 
149 /* option byte write protection */
150 #define OB_LWP                  ((uint32_t)0x000000FFU)     /*!< write protection low bits */
151 #define OB_HWP                  ((uint32_t)0x0000FF00U)     /*!< write protection high bits */
152 
153 #define OB_FWDGT_HW             ((uint8_t)(~BIT(0)))        /*!< hardware free watchdog timer */
154 #define OB_DEEPSLEEP_RST        ((uint8_t)(~BIT(1)))        /*!< generate a reset instead of entering deepsleep mode */
155 #define OB_STDBY_RST            ((uint8_t)(~BIT(2)))        /*!< generate a reset instead of entering standby mode */
156 #define OB_BOOT1_SET_1          ((uint8_t)(~BIT(4)))        /*!< BOOT1 bit is 1 */
157 #define OB_VDDA_DISABLE         ((uint8_t)(~BIT(5)))        /*!< disable VDDA monitor */
158 #define OB_SRAM_PARITY_ENABLE   ((uint8_t)(~BIT(6)))        /*!< enable SRAM parity check */
159 
160 /* option byte security protection level in FMC_OBSTAT register */
161 #define OB_OBSTAT_PLEVEL_NO     ((uint32_t)0x00000000U)     /*!< no security protection */
162 #define OB_OBSTAT_PLEVEL_LOW    ((uint32_t)0x00000002U)     /*!< low security protection */
163 #define OB_OBSTAT_PLEVEL_HIGH   ((uint32_t)0x00000006U)     /*!< high security protection */
164 
165 #define OB_USER_DEFAULT         ((uint8_t)0xDFU)            /*!< OB_USER default value */
166 
167 /* option byte parameter address */
168 #define OB_SPC_ADDR             (uint32_t)(OB + 0x00000000U)/*!< option byte spc address */
169 #define OB_USER_ADDR            (uint32_t)(OB + 0x00000002U)/*!< option byte user address */
170 #define OB_DATA_ADDR0           (uint32_t)(OB + 0x00000004U)/*!< option byte data address 0 */
171 #define OB_DATA_ADDR1           (uint32_t)(OB + 0x00000006U)/*!< option byte data address 1 */
172 #define OB_WP_ADDR0             (uint32_t)(OB + 0x00000008U)/*!< option byte wp address 0 */
173 #define OB_WP_ADDR1             (uint32_t)(OB + 0x0000000AU)/*!< option byte wp address 1 */
174 
175 /* FMC flags */
176 #define FMC_FLAG_BUSY           FMC_STAT_BUSY               /*!< FMC busy flag */
177 #define FMC_FLAG_PGERR          FMC_STAT_PGERR              /*!< FMC programming error flag */
178 #define FMC_FLAG_WPERR          FMC_STAT_WPERR              /*!< FMC write protection error flag */
179 #define FMC_FLAG_END            FMC_STAT_ENDF               /*!< FMC end of programming flag */
180 
181 /* FMC interrupt enable */
182 #define FMC_INTEN_END           FMC_CTL_ENDIE               /*!< enable FMC end of operation interrupt */
183 #define FMC_INTEN_ERR           FMC_CTL_ERRIE               /*!< enable FMC error interrupt */
184 
185 /* FMC time out */
186 #define FMC_TIMEOUT_COUNT       ((uint32_t)0x000F0000U)     /*!< count to judge of FMC timeout */
187 
188 /* function declarations */
189 /* FMC main memory programming functions */
190 /* unlock the main FMC operation */
191 void fmc_unlock(void);
192 /* lock the main FMC operation */
193 void fmc_lock(void);
194 /* set the wait state counter value */
195 void fmc_wscnt_set(uint8_t wscnt);
196 /* fmc wait state enable */
197 void fmc_wait_state_enable(void);
198 /* fmc wait state disable */
199 void fmc_wait_state_disable(void);
200 /* FMC erase page */
201 fmc_state_enum fmc_page_erase(uint32_t page_address);
202 /* FMC erase whole chip */
203 fmc_state_enum fmc_mass_erase(void);
204 /* FMC program a word at the corresponding address */
205 fmc_state_enum fmc_word_program(uint32_t address, uint32_t data);
206 /* FMC program a half word at the corresponding address */
207 fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data);
208 /* FMC program a word at the corresponding address without erasing */
209 fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data);
210 
211 /* FMC option bytes programming functions */
212 /* unlock the option byte operation */
213 void ob_unlock(void);
214 /* lock the option byte operation */
215 void ob_lock(void);
216 /* reload the option byte and generate a system reset */
217 void ob_reset(void);
218 /* erase option byte */
219 fmc_state_enum ob_erase(void);
220 /* enable option byte write protection (OB_WP) */
221 fmc_state_enum ob_write_protection_enable(uint16_t ob_wp);
222 /* configure read out protect */
223 fmc_state_enum ob_security_protection_config(uint8_t ob_spc);
224 /* write the FMC option byte user */
225 fmc_state_enum ob_user_write(uint8_t ob_user);
226 /* write the FMC option byte data */
227 fmc_state_enum ob_data_program(uint32_t address, uint8_t data);
228 /* get the FMC option byte OB_USER */
229 uint8_t ob_user_get(void);
230 /* get the FMC option byte OB_DATA */
231 uint16_t ob_data_get(void);
232 /* get the FMC option byte write protection */
233 uint16_t ob_write_protection_get(void);
234 /* get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register */
235 uint32_t ob_obstat_plevel_get(void);
236 
237 /* FMC interrupts and flags management functions */
238 /* enable FMC interrupt */
239 void fmc_interrupt_enable(uint32_t interrupt);
240 /* disable FMC interrupt */
241 void fmc_interrupt_disable(uint32_t interrupt);
242 /* get flag set or reset */
243 FlagStatus fmc_flag_get(uint32_t flag);
244 /* clear the FMC pending flag */
245 void fmc_flag_clear(uint32_t flag);
246 /* get interrupt flag set or reset */
247 FlagStatus fmc_interrupt_flag_get(uint32_t flag);
248 /* clear the FMC interrupt pending flag */
249 void fmc_interrupt_flag_clear(uint32_t flag);
250 /* return the FMC state */
251 fmc_state_enum fmc_state_get(void);
252 /* check FMC ready or not */
253 fmc_state_enum fmc_ready_wait(uint32_t timeout);
254 /* get current option byte value */
255 void ob_parm_get(ob_parm_struct *ob_parm);
256 /* modify the target option byte depending on the original value */
257 void ob_value_modify(uint32_t address, uint16_t value,ob_parm_struct *ob_parm);
258 
259 #endif /* GD32F3X0_FMC_H */
260