1 /*!
2     \file    gd32a50x_fmc.h
3     \brief   definitions for the FMC
4 
5     \version 2022-01-30, V1.0.0, firmware for GD32A50x
6 */
7 
8 /*
9     Copyright (c) 2022, GigaDevice Semiconductor Inc.
10 
11     Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 
14     1. Redistributions of source code must retain the above copyright notice, this
15        list of conditions and the following disclaimer.
16     2. Redistributions in binary form must reproduce the above copyright notice,
17        this list of conditions and the following disclaimer in the documentation
18        and/or other materials provided with the distribution.
19     3. Neither the name of the copyright holder nor the names of its contributors
20        may be used to endorse or promote products derived from this software without
21        specific prior written permission.
22 
23     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34 
35 #ifndef GD32A50X_FMC_H
36 #define GD32A50X_FMC_H
37 
38 #include "gd32a50x.h"
39 
40 /* FMC and option bytes definition */
41 #define FMC                          FMC_BASE                                           /*!< FMC register base address */
42 #define OB                           OB_BASE                                            /*!< option bytes 0 base address */
43 
44 /* registers definitions */
45 #define FMC_WS                       REG32((FMC) + 0x00000000U)                         /*!< FMC wait state register */
46 #define FMC_ECCCS                    REG32((FMC) + 0x00000004U)                         /*!< FMC ECC control and status register */
47 #define FMC_KEY0                     REG32((FMC) + 0x00000008U)                         /*!< FMC unlock key register 0 */
48 #define FMC_STAT0                    REG32((FMC) + 0x0000000CU)                         /*!< FMC status register 0 */
49 #define FMC_CTL0                     REG32((FMC) + 0x00000010U)                         /*!< FMC control register 0 */
50 #define FMC_ADDR0                    REG32((FMC) + 0x00000014U)                         /*!< FMC address register 0 */
51 #define FMC_OBKEY                    REG32((FMC) + 0x00000044U)                         /*!< FMC option byte unlock key register */
52 #define FMC_KEY1                     REG32((FMC) + 0x00000048U)                         /*!< FMC unlock key register 1 */
53 #define FMC_STAT1                    REG32((FMC) + 0x0000004CU)                         /*!< FMC status register 1 */
54 #define FMC_CTL1                     REG32((FMC) + 0x00000050U)                         /*!< FMC control register 1 */
55 #define FMC_ADDR1                    REG32((FMC) + 0x00000054U)                         /*!< FMC address register 1 */
56 #define FMC_EPCNT                    REG32((FMC) + 0x00000058U)                         /*!< FMC EEPROM counter register */
57 #define FMC_OBSTAT                   REG32((FMC) + 0x0000005CU)                         /*!< FMC option byte status register */
58 #define FMC_WP0                      REG32((FMC) + 0x00000060U)                         /*!< FMC erase/program protection register 0 */
59 #define FMC_WP1                      REG32((FMC) + 0x00000064U)                         /*!< FMC erase/program protection register 1 */
60 #define FMC_OB1CS                    REG32((FMC) + 0x00000068U)                         /*!< FMC option byte 1 control and status register */
61 #define FMC_PID                      REG32((FMC) + 0x00000100U)                         /*!< FMC product ID register */
62 
63 #define OP_BYTE(x)                   REG32(OB + ((uint32_t)((uint32_t)0x04U * (x))))    /*!< option bytes 0 value */
64 #define OB_SPC                       REG16((OB) + 0x00000000U)                          /*!< option bytes 0 security protection value*/
65 #define OB_USER                      REG16((OB) + 0x00000002U)                          /*!< option bytes 0 user value*/
66 #define OB_SPC_USER                  REG32((OB) + 0x00000000U)                          /*!< option bytes 0 security protection value and user value */
67 #define OB_DATA                      REG32((OB) + 0x00000004U)                          /*!< option bytes 0 data value */
68 
69 /* bits definitions */
70 /* FMC_WS */
71 #define FMC_WS_WSCNT                 BITS(0,2)                                          /*!< wait state counter */
72 #define FMC_WS_PFEN                  BIT(4)                                             /*!< pre-fetch enable */
73 #define FMC_WS_IDCEN                 BIT(9)                                             /*!< cache enable */
74 #define FMC_WS_IDRST                 BIT(11)                                            /*!< cache reset */
75 #define FMC_WS_SLEEP_SLP             BIT(14)                                            /*!< flash goto sleep mode or power-down mode when MCU enters deepsleep mode */
76 #define FMC_WS_ERAMRDY               BIT(16)                                            /*!< EEPROM SRAM ready flag */
77 #define FMC_WS_BRAMRDY               BIT(17)                                            /*!< basic SRAM ready flag */
78 #define FMC_WS_PRAMRDY               BIT(18)                                            /*!< fast PG SRAM ready flag */
79 
80 /* FMC_ECCCS */
81 #define FMC_ECCCS_ECCADDR            BITS(0,14)                                         /*!< the offset address of double word where an ECC error is detected */
82 #define FMC_ECCCS_OB0_ECC            BIT(19)                                            /*!< option bytes 0 one bit error flag */
83 #define FMC_ECCCS_BK1_ECC            BIT(20)                                            /*!< bank1 one bit error flag */
84 #define FMC_ECCCS_SYS_ECC            BIT(21)                                            /*!< system memory one bit error flag */
85 #define FMC_ECCCS_DF_ECC             BIT(22)                                            /*!< data flash one bit error flag */
86 #define FMC_ECCCS_OTP_ECC            BIT(23)                                            /*!< OTP one bit error flag */
87 #define FMC_ECCCS_ECCCORIE           BIT(24)                                            /*!< one bit error correct interrupt enable */
88 #define FMC_ECCCS_ECCDETIE           BIT(25)                                            /*!< two bits error detect interrupt enable */
89 #define FMC_ECCCS_OB1ECCDET          BIT(26)                                            /*!< option bytes 1 two bits error detect flag */
90 #define FMC_ECCCS_OB0ECCDET          BIT(27)                                            /*!< option bytes 0 two bits error detect flag */
91 #define FMC_ECCCS_EPECCDET           BIT(29)                                            /*!< EEPROM two bits error detect flag */
92 #define FMC_ECCCS_ECCCOR             BIT(30)                                            /*!< one bit error detected and correct flag */
93 #define FMC_ECCCS_ECCDET             BIT(31)                                            /*!< two bits error detect flag */
94 
95 /* FMC_KEY0 */
96 #define FMC_KEY0_KEY                 BITS(0,31)                                         /*!< flash bank0 unlock key bits */
97 
98 /* FMC_STAT0 */
99 #define FMC_STAT0_BUSY               BIT(0)                                             /*!< flash bank0 busy flag */
100 #define FMC_STAT0_PGSERR             BIT(1)                                             /*!< flash bank0 program sequence error flag */
101 #define FMC_STAT0_PGERR              BIT(2)                                             /*!< flash bank0 program error flag */
102 #define FMC_STAT0_PGAERR             BIT(3)                                             /*!< flash bank0 program alignment error flag */
103 #define FMC_STAT0_WPERR              BIT(4)                                             /*!< flash bank0 erase/program protection error flag */
104 #define FMC_STAT0_ENDF               BIT(5)                                             /*!< flash bank0 end of operation flag */
105 #define FMC_STAT0_CBCMDERR           BIT(6)                                             /*!< flash bank0 checked area by the check blank command is all 0xFF or not */
106 #define FMC_STAT0_RSTERR             BIT(15)                                            /*!< flash bank0 BOR/POR or system reset during erase/program flag */
107 
108 /* FMC_CTL0 */
109 #define FMC_CTL0_PG                  BIT(0)                                             /*!< flash bank0 program command bit */
110 #define FMC_CTL0_PER                 BIT(1)                                             /*!< flash bank0 page erase bit */
111 #define FMC_CTL0_MER                 BIT(2)                                             /*!< flash bank0 mass erase bit */
112 #define FMC_CTL0_START               BIT(6)                                             /*!< send erase command to flash bank0 bit */
113 #define FMC_CTL0_LK                  BIT(7)                                             /*!< flash bank0 lock bit */
114 #define FMC_CTL0_FSTPG               BIT(8)                                             /*!< flash bank0 fast program command bit */
115 #define FMC_CTL0_ERRIE               BIT(10)                                            /*!< flash bank0 error interrupt enable bit */
116 #define FMC_CTL0_ENDIE               BIT(12)                                            /*!< flash bank0 end of operation interrupt enable bit */
117 #define FMC_CTL0_CBCMD               BIT(16)                                            /*!< send check blank command to flash bank0 bit */
118 #define FMC_CTL0_CBCMDLEN            BITS(29,31)                                        /*!< check blank command read length to flash bank0 */
119 
120 /* FMC_ADDR0 */
121 #define FMC_ADDR0_ADDR               BITS(0,31)                                         /*!< flash bank0 command address bits */
122 
123 /* FMC_OBKEY */
124 #define FMC_OBKEY_OBKEY              BITS(0,31)                                         /*!< option bytes unlock key bits */
125 
126 /* FMC_KEY1 */
127 #define FMC_KEY1_KEY                 BITS(0,31)                                         /*!< flash bank1 unlock key bits */
128 
129 /* FMC_STAT1 */
130 #define FMC_STAT1_BUSY               BIT(0)                                             /*!< flash bank1 busy flag */
131 #define FMC_STAT1_PGSERR             BIT(1)                                             /*!< flash bank1 program sequence error flag */
132 #define FMC_STAT1_PGERR              BIT(2)                                             /*!< flash bank1 program error flag */
133 #define FMC_STAT1_PGAERR             BIT(3)                                             /*!< flash bank1 program alignment error flag */
134 #define FMC_STAT1_WPERR              BIT(4)                                             /*!< flash bank1 erase/program protection error flag */
135 #define FMC_STAT1_ENDF               BIT(5)                                             /*!< flash bank1 end of operation flag */
136 #define FMC_STAT1_CBCMDERR           BIT(6)                                             /*!< flash bank1 checked area by the check blank command is all 0xFF or not */
137 #define FMC_STAT1_RSTERR             BIT(15)                                            /*!< flash bank1 BOR/POR or system reset during erase/program flag */
138 
139 /* FMC_CTL1 */
140 #define FMC_CTL1_PG                  BIT(0)                                             /*!< flash bank1 program command bit */
141 #define FMC_CTL1_PER                 BIT(1)                                             /*!< flash bank1 page erase bit */
142 #define FMC_CTL1_MER                 BIT(2)                                             /*!< flash bank1 mass erase bit */
143 #define FMC_CTL1_MERDF               BIT(3)                                             /*!< data flash mass erase bit */
144 #define FMC_CTL1_OB0PG               BIT(4)                                             /*!< option bytes 0 program command bit */
145 #define FMC_CTL1_OB0ER               BIT(5)                                             /*!< option bytes 0 erase command bit */
146 #define FMC_CTL1_START               BIT(6)                                             /*!< send erase command to FMC bit */
147 #define FMC_CTL1_LK                  BIT(7)                                             /*!< flash bank1 lock bit */
148 #define FMC_CTL1_FSTPG               BIT(8)                                             /*!< fast program command bit */
149 #define FMC_CTL1_OBWEN               BIT(9)                                             /*!< option bytes erase/program enable bit */
150 #define FMC_CTL1_ERRIE               BIT(10)                                            /*!< flash bank1 error interrupt enable bit */
151 #define FMC_CTL1_ENDIE               BIT(12)                                            /*!< flash bank1 end of operation interrupt enable bit */
152 #define FMC_CTL1_OBRLD               BIT(13)                                            /*!< option bytes reload bit */
153 #define FMC_CTL1_CBCMD               BIT(16)                                            /*!< send check blank command to flash bank1 bit */
154 #define FMC_CTL1_SRAMCMD             BITS(24,25)                                        /*!< send shared SRAM command */
155 #define FMC_CTL1_CBCMDLEN            BITS(29,31)                                        /*!< check blank command read length to flash bank1 */
156 
157 /* FMC_ADDR1 */
158 #define FMC_ADDR1_ADDR               BITS(0,31)                                         /*!< flash bank1 command address bits */
159 
160 /* FMC_EPCNT */
161 #define FMC_EPCNT_EPCNT              BITS(0,31)                                         /*!< EEPROM erase counter */
162 
163 /* FMC_OBSTAT */
164 #define FMC_OBSTAT_OBERR             BIT(0)                                             /*!< option bytes read error bit */
165 #define FMC_OBSTAT_PLEVEL            BITS(1,2)                                          /*!< protection level bits */
166 #define FMC_OBSTAT_USER              BITS(8,15)                                         /*!< option bytes user bits */
167 #define FMC_OBSTAT_DATA              BITS(16,31)                                        /*!< option bytes data bits */
168 
169 /* FMC_WP0 */
170 #define FMC_WP0_BK0WP                BITS(0,31)                                         /*!< store OB_BK0WP[31:0] of option bytes 0 block after system reset */
171 
172 /* FMC_WP1 */
173 #define FMC_WP1_BK1WP                BITS(0,7)                                          /*!< store OB_BK1WP[7:0] of option bytes 0 block after system reset */
174 #define FMC_WP1_DFWP                 BITS(8,15)                                         /*!< store OB_DFWP[7:0] of option bytes 0 block after system reset */
175 #define FMC_WP1_EPWP                 BITS(16,23)                                        /*!< store OB_EPWP[7:0] of option bytes 0 block after system reset */
176 
177 /* FMC_OB1CS */
178 #define FMC_OB1CS_OB1ERR             BIT(0)                                             /*!< option bytes 1 read error bit */
179 #define FMC_OB1CS_OB1START           BIT(1)                                             /*!< send option bytes 1 change command to FMC */
180 #define FMC_OB1CS_OB1LK              BIT(2)                                             /*!< option bytes 1 lock bit */
181 #define FMC_OB1CS_EFALC              BITS(4,7)                                          /*!< load EFALC of option bytes 1 after reset */
182 #define FMC_OB1CS_EPSIZE             BITS(8,11)                                         /*!< load EPSIZE of option bytes 1 after reset */
183 #define FMC_OB1CS_EPLOAD             BIT(15)                                            /*!< load EPLOAD of option bytes 1 after reset */
184 #define FMC_OB1CS_LKVAL              BITS(16,31)                                        /*!< load LKVAL of option bytes 1 after reset */
185 
186 /* FMC_PID */
187 #define FMC_PID_PID                  BITS(0,31)                                         /*!< product ID bits */
188 
189 /* constants definitions */
190 /* fmc state */
191 typedef enum {
192     FMC_READY,                                                                          /*!< the operation has been completed */
193     FMC_BUSY,                                                                           /*!< the operation is in progress */
194     FMC_PGSERR,                                                                         /*!< program sequence error */
195     FMC_PGERR,                                                                          /*!< program error */
196     FMC_PGAERR,                                                                         /*!< program alignment error */
197     FMC_WPERR,                                                                          /*!< erase/program protection error */
198     FMC_TOERR,                                                                          /*!< timeout error */
199     FMC_CBCMDERR,                                                                       /*!< the checked area not blank error */
200     FMC_RSTERR,                                                                         /*!< BOR/POR or system reset during flash erase/program error */
201     FMC_OB_HSPC,                                                                        /*!< FMC is under high security protection */
202     FMC_OB1_LK                                                                          /*!< option bytes 1 is locked */
203 } fmc_state_enum;
204 
205 /* shared SRAM mode */
206 typedef enum {
207     NO_SRAM_MODE = 0,                                                                   /*!< SRAM mode is not configured */
208     FASTPG_SRAM_MODE = 1,                                                               /*!< fast program SRAM mode */
209     BASIC_SRAM_MODE = 2,                                                                /*!< basic SRAM mode */
210     EEPROM_SRAM_MODE = 3                                                                /*!< EEPROM SRAM mode */
211 } fmc_sram_mode_enum;
212 
213 /* FMC area */
214 typedef enum {
215     BANK0_AREA = 0,                                                                     /*!< main flash bank0 area */
216     BANK1_AREA = 1,                                                                     /*!< main flash bank1 area */
217     DATA_FLASH_AREA = 2,                                                                /*!< data flash area */
218     EEPROM_AREA = 3                                                                     /*!< EEPROM area */
219 } fmc_area_enum;
220 
221 /* define the FMC bit position and its register index offset */
222 #define FMC_REGIDX_BIT(regidx, bitpos)  (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
223 #define FMC_REG_VAL(offset)             (REG32(FMC + (((uint32_t)(offset) & 0x0000FFFFU) >> 6)))
224 #define FMC_BIT_POS(val)                ((uint32_t)(val) & 0x0000001FU)
225 #define FMC_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2)   (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\
226                                                             | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)))
227 #define FMC_REG_VAL2(offset)            (REG32(FMC + ((uint32_t)(offset) >> 22)))
228 #define FMC_BIT_POS2(val)               (((uint32_t)(val) & 0x001F0000U) >> 16)
229 
230 /* register offset */
231 #define FMC_STAT0_REG_OFFSET            ((uint32_t)0x0000000CU)                         /*!< STAT0 register offset */
232 #define FMC_STAT1_REG_OFFSET            ((uint32_t)0x0000004CU)                         /*!< STAT1 register offset */
233 #define FMC_ECCCS_REG_OFFSET            ((uint32_t)0x00000004U)                         /*!< ECCCS register offset */
234 #define FMC_OB1CS_REG_OFFSET            ((uint32_t)0x00000068U)                         /*!< OB1CS register offset */
235 #define FMC_CTL0_REG_OFFSET             ((uint32_t)0x00000010U)                         /*!< CTL0 register offset */
236 #define FMC_CTL1_REG_OFFSET             ((uint32_t)0x00000050U)                         /*!< CTL1 register offset */
237 #define FMC_OBSTAT_REG_OFFSET           ((uint32_t)0x0000005CU)                         /*!< OBSTAT register offset */
238 
239 /* FMC flags */
240 typedef enum {
241     /* flags in STAT0 register */
242     FMC_BANK0_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 0U),                     /*!< flash bank0 busy flag */
243     FMC_BANK0_FLAG_PGSERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 1U),                   /*!< flash bank0 program sequence error flag */
244     FMC_BANK0_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 2U),                    /*!< flash bank0 program error flag */
245     FMC_BANK0_FLAG_PGAERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 3U),                   /*!< flash bank0 program alignment error flag */
246     FMC_BANK0_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 4U),                    /*!< flash bank0 erase/program protection error flag */
247     FMC_BANK0_FLAG_END = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 5U),                      /*!< flash bank0 end of operation flag */
248     FMC_BANK0_FLAG_CBCMDERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 6U),                 /*!< flash bank0 checked area by the check blank command is all 0xFF or not flag */
249     FMC_BANK0_FLAG_RSTERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 15U),                  /*!< flash bank0 BOR/POR or system reset during erase/program flag */
250     /* flags in STAT1 register */
251     FMC_BANK1_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 0U),                     /*!< flash bank1 busy flag */
252     FMC_BANK1_FLAG_PGSERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 1U),                   /*!< flash bank1 program sequence error flag */
253     FMC_BANK1_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 2U),                    /*!< flash bank1 program error flag */
254     FMC_BANK1_FLAG_PGAERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 3U),                   /*!< flash bank1 program alignment error flag */
255     FMC_BANK1_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 4U),                    /*!< flash bank1 erase/program protection error flag */
256     FMC_BANK1_FLAG_END = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 5U),                      /*!< flash bank1 end of operation flag */
257     FMC_BANK1_FLAG_CBCMDERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 6U),                 /*!< flash bank1 checked area by the check blank command is all 0xFF or not flag */
258     FMC_BANK1_FLAG_RSTERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 15U),                  /*!< flash bank1 BOR/POR or system reset during erase/program flag */
259     /* flags in ECCCS register */
260     FMC_FLAG_BK0ECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 28U),                        /*!< an ECC bit error is detected in bank 0 flag */
261     FMC_FLAG_OB0ECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 19U),                        /*!< an ECC bit error is detected in option byte 0 flag */
262     FMC_FLAG_BK1ECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 20U),                        /*!< an ECC bit error is detected in bank 1 flag */
263     FMC_FLAG_SYSECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 21U),                        /*!< an ECC bit error is detected in system memory flag */
264     FMC_FLAG_DFECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 22U),                         /*!< an ECC bit error is detected in data flash flag */
265     FMC_FLAG_OTPECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 23U),                        /*!< an ECC bit error is detected in OTP flag */
266     FMC_FLAG_OB1ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 26U),                     /*!< option bytes 1 two bit error detect flag */
267     FMC_FLAG_OB0ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 27U),                     /*!< option bytes 0 two bit error detect flag */
268     FMC_FLAG_EPECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 29U),                      /*!< EEPROM two bits error detect flag */
269     FMC_FLAG_ECCCOR = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 30U),                        /*!< one bit error detected and correct flag */
270     FMC_FLAG_ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 31U),                        /*!< OTP/data flash/system memory/bank1 two bit error detect flag */
271     /* flags in OBSTAT register */
272     FMC_FLAG_OBERR = FMC_REGIDX_BIT(FMC_OBSTAT_REG_OFFSET, 0U),                         /*!< option bytes 0 error flag */
273     /* flags in OB1CS register */
274     FMC_FLAG_OB1ERR = FMC_REGIDX_BIT(FMC_OB1CS_REG_OFFSET, 0U)                          /*!< option bytes 1 read error flag */
275 } fmc_flag_enum;
276 
277 /* FMC interrupt flags */
278 typedef enum {
279     /* interrupt flags in STAT0 register */
280     FMC_BANK0_INT_FLAG_PGSERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 1U),        /*!< flash bank0 program sequence error interrupt flag */
281     FMC_BANK0_INT_FLAG_PGERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 2U),         /*!< flash bank0 program error interrupt flag */
282     FMC_BANK0_INT_FLAG_PGAERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 3U),        /*!< flash bank0 program alignment error interrupt flag */
283     FMC_BANK0_INT_FLAG_WPERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 4U),         /*!< flash bank0 erase/program protection error interrupt flag */
284     FMC_BANK0_INT_FLAG_END = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 12U, FMC_STAT0_REG_OFFSET, 5U),           /*!< flash bank0 end of operation interrupt flag */
285     FMC_BANK0_INT_FLAG_CBCMDERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 6U),      /*!< flash bank0 checked area by the check blank command is all 0xFF or not interrupt flag */
286     FMC_BANK0_INT_FLAG_RSTERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 15U),       /*!< flash bank0 BOR/POR or system reset during erase/program interrupt flag */
287     /* interrupt flags in STAT1 register */
288     FMC_BANK1_INT_FLAG_PGSERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 1U),        /*!< flash bank1 program sequence error interrupt flag */
289     FMC_BANK1_INT_FLAG_PGERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 2U),         /*!< flash bank1 program error interrupt flag */
290     FMC_BANK1_INT_FLAG_PGAERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 3U),        /*!< flash bank1 program alignment error interrupt flag */
291     FMC_BANK1_INT_FLAG_WPERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 4U),         /*!< flash bank1 erase/program protection error interrupt flag */
292     FMC_BANK1_INT_FLAG_END = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 12U, FMC_STAT0_REG_OFFSET, 5U),           /*!< flash bank1 end of operation interrupt flag */
293     FMC_BANK1_INT_FLAG_CBCMDERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 6U),      /*!< flash bank1 checked area by the check blank command is all 0xFF or not interrupt flag */
294     FMC_BANK1_INT_FLAG_RSTERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 15U),       /*!< flash bank1 BOR/POR or system reset during erase/program interrupt flag */
295     /* interrupt flags in ECCCS register */
296     FMC_INT_FLAG_OB1ECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 26U),         /*!< option bytes 1 two bits error detect interrupt flag */
297     FMC_INT_FLAG_OB0ECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 27U),         /*!< option bytes 0 two bits error detect interrupt flag */
298     FMC_INT_FLAG_EPECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 29U),          /*!< EEPROM two bits error detect interrupt flag */
299     FMC_INT_FLAG_ECCCOR = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 24U, FMC_ECCCS_REG_OFFSET, 30U),            /*!< one bit error detected and correct interrupt flag */
300     FMC_INT_FLAG_ECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 31U)             /*!< two bits error detect interrupt flag */
301 } fmc_interrupt_flag_enum;
302 
303 /* FMC interrupt */
304 typedef enum {
305     /* interrupt in CTL0 register */
306     FMC_BANK0_INT_ERR = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 10U),                       /*!< FMC bank0 error interrupt */
307     FMC_BANK0_INT_END = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 12U),                       /*!< FMC bank0 end of operation interrupt */
308     /* interrupt in CTL1 register */
309     FMC_BANK1_INT_ERR = FMC_REGIDX_BIT(FMC_CTL1_REG_OFFSET, 10U),                       /*!< FMC bank1 error interrupt */
310     FMC_BANK1_INT_END = FMC_REGIDX_BIT(FMC_CTL1_REG_OFFSET, 12U),                       /*!< FMC bank1 end of operation interrupt */
311     /* interrupt in ECCCS register */
312     FMC_INT_ECCCOR = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 24U),                         /*!< FMC one bit error correct interrupt */
313     FMC_INT_ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 25U)                          /*!< FMC two bits error interrupt */
314 } fmc_interrupt_enum;
315 
316 /* unlock key */
317 #define UNLOCK_KEY0                  ((uint32_t)0x45670123U)                            /*!< unlock key 0 */
318 #define UNLOCK_KEY1                  ((uint32_t)0xCDEF89ABU)                            /*!< unlock key 1 */
319 
320 /* wait state counter value */
321 #define WS_WSCNT(regval)             (BITS(0,2) & ((uint32_t)(regval) << 0))
322 #define WS_WSCNT_0                   WS_WSCNT(0)                                        /*!< 0 wait state added */
323 #define WS_WSCNT_1                   WS_WSCNT(1)                                        /*!< 1 wait state added */
324 #define WS_WSCNT_2                   WS_WSCNT(2)                                        /*!< 2 wait state added */
325 #define WS_WSCNT_3                   WS_WSCNT(3)                                        /*!< 3 wait state added */
326 
327 /* shared SRAM command */
328 #define CTL1_SRAMCMD(regval)         (BITS(24,25) & ((uint32_t)(regval) << 24))
329 #define FASTPG_SRAM_CMD              CTL1_SRAMCMD(1)                                    /*!< set fast PG RAM mode */
330 #define BASIC_SRAM_CMD               CTL1_SRAMCMD(2)                                    /*!< set basic RAM mode */
331 #define EEPROM_SRAM_CMD              CTL1_SRAMCMD(3)                                    /*!< set EEPROM RAM mode */
332 
333 /* option bytes security protection level in FMC_OBSTAT register */
334 #define OB_OBSTAT_PLEVEL_NO          ((uint8_t)0x00U)                                   /*!< no security protection */
335 #define OB_OBSTAT_PLEVEL_LOW         ((uint8_t)0x01U)                                   /*!< low security protection */
336 #define OB_OBSTAT_PLEVEL_HIGH        ((uint8_t)0x03U)                                   /*!< high security protection */
337 
338 /* option bytes read protection configuration */
339 #define FMC_NSPC                     ((uint16_t)0x5AA5U)                                /*!< no security protection */
340 #define FMC_LSPC                     ((uint16_t)0x44BBU)                                /*!< low security protection, any value except 0xA5 or 0xCC */
341 #define FMC_HSPC                     ((uint16_t)0x33CCU)                                /*!< high security protection */
342 
343 /* option bytes software/hardware free watchdog timer */
344 #define OB_FWDGT_HW                  ((uint16_t)0x0100U)                                /*!< hardware free watchdog timer */
345 #define OB_FWDGT_SW                  ((uint16_t)0x0001U)                                /*!< software free watchdog timer */
346 
347 /* option bytes reset or not entering deep sleep mode */
348 #define OB_DEEPSLEEP_RST             ((uint16_t)0x0200U)                                /*!< generate a reset instead of entering deepsleep mode */
349 #define OB_DEEPSLEEP_NRST            ((uint16_t)0x0002U)                                /*!< no reset when entering deepsleep mode */
350 
351 /* option bytes reset or not entering standby mode */
352 #define OB_STDBY_RST                 ((uint16_t)0x0400U)                                /*!< generate a reset instead of entering standby mode */
353 #define OB_STDBY_NRST                ((uint16_t)0x0004U)                                /*!< no reset when entering deepsleep mode */
354 
355 /* option bytes boot from bank0 or bank1 when configured boot from main flash */
356 #define OB_BOOT_FROM_BANK1           ((uint16_t)0x0800U)                                /*!< boot from bank1 or bank0 if bank1 is void, when configured boot from main memory */
357 #define OB_BOOT_FROM_BANK0           ((uint16_t)0x0008U)                                /*!< boot from bank0, when configured boot from main memory */
358 
359 /* option bytes OTA configuration */
360 #define OB_BOOT_OTA_ENABLE           ((uint16_t)0x1000U)                                /*!< when configured boot from main memory, if the BB is 0, all data will be copied from bank1 to bank0 and then boot from bank0 */
361 #define OB_BOOT_OTA_DISABLE          ((uint16_t)0x0010U)                                /*!< no effect */
362 
363 /* option bytes brownout configuration */
364 #define OB_BOR_DISABLE               ((uint16_t)0x0080U)                                /*!< disable brown out */
365 #define OB_BOR_ENABLE                ((uint16_t)0x8000U)                                /*!< enable brown out, brownout threshold 2.6V */
366 
367 /* option bytes 1 lock value in FMC_OB1CS register */
368 #define OB1CS_OB1_LKVAL(regval)      (BITS(16,31) & ((uint32_t)(regval) << 16))
369 #define OB1CS_OB1_LK                 OB1CS_OB1_LKVAL((uint16_t)0x33CCU)                 /*!< option byte1 cannot be modified */
370 #define OB1CS_OB1_NOT_LK             OB1CS_OB1_LKVAL((uint16_t)0x00FFU)                 /*!< option byte1 is not locked */
371 
372 /* option bytes 1 shared RAM init mode in FMC_OB1CS register */
373 #define OB1CS_EPLOAD(regval)         (BIT(15) & ((uint32_t)(regval) << 15))
374 #define OB1CS_EPLOAD_NOT_LOAD_EPDATA OB1CS_EPLOAD((uint16_t)0x00U)                      /*!< shared SRAM is not loaded with valid EEPROM data during FMC reset */
375 #define OB1CS_EPLOAD_LOAD_EPDATA     OB1CS_EPLOAD((uint16_t)0x01U)                      /*!< shared SRAM is loaded with valid EEPROM data during FMC reset */
376 
377 /* option bytes 1 EEPROM size in FMC_OB1CS register */
378 #define OB1CS_EPSIZE(regval)         (BITS(8, 11) & ((uint32_t)(regval) << 8))
379 #define OB1CS_EPSIZE_NONE            OB1CS_EPSIZE((uint8_t)0x0FU)                      /*!< no EEPROM */
380 #define OB1CS_EPSIZE_4K              OB1CS_EPSIZE((uint8_t)0x08U)                      /*!< 4KB EEPROM, 384K flash or 256K flash */
381 #define OB1CS_EPSIZE_2K              OB1CS_EPSIZE((uint8_t)0x04U)                      /*!< 2KB EEPROM, 128K flash */
382 #define OB1CS_EPSIZE_1K              OB1CS_EPSIZE((uint8_t)0x02U)                      /*!< 1KB EEPROM, 64K flash */
383 
384 /* option bytes 1 extend flash block allocation in FMC_OB1CS register */
385 /* 384K flash or 256K flash */
386 #define OB1CS_EFALC(regval)          (BITS(4, 7) & ((uint32_t)(regval) << 4))
387 #define OB1CS_DF_64K_EF_0K           OB1CS_EFALC((uint8_t)0x00U)                        /*!< data flash size is 64KB, EEPROM backup size is 0KB */
388 #define OB1CS_DF_48K_EF_16K          OB1CS_EFALC((uint8_t)0x03U)                        /*!< data flash size is 48KB, EEPROM backup size is 16KB */
389 #define OB1CS_DF_32K_EF_32K          OB1CS_EFALC((uint8_t)0x04U)                        /*!< data flash size is 32KB, EEPROM backup size is 32KB */
390 #define OB1CS_DF_16K_EF_48K          OB1CS_EFALC((uint8_t)0x05U)                        /*!< data flash size is 16KB, EEPROM backup size is 48KB */
391 #define OB1CS_DF_0K_EF_64K           OB1CS_EFALC((uint8_t)0x08U)                        /*!< data flash size is 0KB, EEPROM backup size is 64KB */
392 #define OB1CS_DF_EF_INVALID          OB1CS_EFALC((uint8_t)0x0FU)                        /*!< data flash and EEPROM backup are invalid */
393 /* 128K flash */
394 #define OB1CS_DF_32K_EF_0K           OB1CS_EFALC((uint8_t)0x01U)                        /*!< data flash size is 64KB, EEPROM backup size is 0KB */
395 #define OB1CS_DF_8K_EF_24K           OB1CS_EFALC((uint8_t)0x06U)                        /*!< data flash size is 48KB, EEPROM backup size is 16KB */
396 #define OB1CS_DF_0K_EF_32K           OB1CS_EFALC((uint8_t)0x09U)                        /*!< data flash size is 32KB, EEPROM backup size is 32KB */
397 #define OB1CS_DF_16K_EF_16K          OB1CS_EFALC((uint8_t)0x0BU)                        /*!< data flash size is 16KB, EEPROM backup size is 48KB */
398 #define OB1CS_DF_24K_EF_8K           OB1CS_EFALC((uint8_t)0x0CU)                        /*!< data flash size is 0KB, EEPROM backup size is 64KB */
399 /* 64K flash */
400 #define OB1CS_DF_16K_EF_0K           OB1CS_EFALC((uint8_t)0x02U)                        /*!< data flash size is 64KB, EEPROM backup size is 0KB */
401 #define OB1CS_DF_4K_EF_12K           OB1CS_EFALC((uint8_t)0x07U)                        /*!< data flash size is 48KB, EEPROM backup size is 16KB */
402 #define OB1CS_DF_0K_EF_16K           OB1CS_EFALC((uint8_t)0x0AU)                        /*!< data flash size is 32KB, EEPROM backup size is 32KB */
403 #define OB1CS_DF_8K_EF_8K            OB1CS_EFALC((uint8_t)0x0DU)                        /*!< data flash size is 16KB, EEPROM backup size is 48KB */
404 #define OB1CS_DF_12K_EF_4K           OB1CS_EFALC((uint8_t)0x0EU)                        /*!< data flash size is 0KB, EEPROM backup size is 64KB */
405 
406 #define BANK0_BASE_ADDRESS           ((uint32_t)0x08000000U)                            /*!< FMC bank0 base address */
407 #define BANK0_SIZE                   ((uint32_t)0x00040000U)                            /*!< FMC bank0 size */
408 #define BANK1_BASE_ADDRESS           ((uint32_t)(BANK0_BASE_ADDRESS + BANK0_SIZE))      /*!< FMC bank1 base address */
409 #define OB_WORD_CNT                  ((uint8_t)0x06U)                                   /*!< word count of option bytes */
410 #define OB_DOUBLEWORD_CNT            ((uint8_t)0x03U)                                   /*!< double-word count of option bytes */
411 #define FMC_TIMEOUT_COUNT            ((uint32_t)0x00FF0000U)                            /*!< count to judge of FMC timeout */
412 #define DOUBLEWORD_CNT_IN_ROW        ((uint8_t)0x20U)                                   /*!< double-word count in one row data */
413 #define CBCMDLEN_OF_ONE_ROW          ((uint8_t)0x05U)                                   /*!< CBCMD read length of one row data */
414 
415 /* function declarations */
416 /* FMC programming functions */
417 /* unlock the main flash operation */
418 void fmc_unlock(void);
419 /* unlock the main flash bank0 operation */
420 void fmc_bank0_unlock(void);
421 /* unlock the main flash bank1 operation */
422 void fmc_bank1_unlock(void);
423 /* lock the main flash operation */
424 void fmc_lock(void);
425 /* lock the main flash bank0 operation */
426 void fmc_bank0_lock(void);
427 /* lock the main flash bank1 operation */
428 void fmc_bank1_lock(void);
429 
430 /* set the wait state counter value */
431 void fmc_wscnt_set(uint8_t wscnt);
432 /* enable pre-fetch */
433 void fmc_prefetch_enable(void);
434 /* disable pre-fetch */
435 void fmc_prefetch_disable(void);
436 /* enable cache */
437 void fmc_cache_enable(void);
438 /* disable cache */
439 void fmc_cache_disable(void);
440 /* enable cache reset if cache is disabled */
441 void fmc_cache_reset_enable(void);
442 /* disable cache reset */
443 void fmc_cache_reset_disable(void);
444 /* flash goto power-down mode when MCU enters deepsleep mode */
445 void fmc_powerdown_mode_set(void);
446 /* flash goto sleep mode when MCU enters deepsleep mode */
447 void fmc_sleep_mode_set(void);
448 /* configure shared SRAM mode */
449 void fmc_sram_mode_config(fmc_sram_mode_enum sram_mode);
450 /* get shared SRAM mode */
451 fmc_sram_mode_enum fmc_sram_mode_get(void);
452 
453 /* check whether flash page is blank or not by check blank command */
454 fmc_state_enum fmc_blank_check(uint32_t address, uint8_t length);
455 /* erase main flash page */
456 fmc_state_enum fmc_page_erase(uint32_t page_address);
457 /* erase flash bank0 */
458 fmc_state_enum fmc_bank0_mass_erase(void);
459 /* erase flash bank1 */
460 fmc_state_enum fmc_bank1_mass_erase(void);
461 /* erase the data flash */
462 fmc_state_enum fmc_dflash_mass_erase(void);
463 /* erase whole chip */
464 fmc_state_enum fmc_mass_erase(void);
465 
466 /* program a double word at the corresponding address in main flash */
467 fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data);
468 /* FMC fast program one row data (32 double-word) starting at the corresponding address */
469 fmc_state_enum fmc_fast_program(uint32_t address, uint64_t data[]);
470 /* program a double word at the corresponding address in OTP */
471 fmc_state_enum otp_doubleword_program(uint32_t address, uint64_t data);
472 /* program a word at the corresponding address in EEPROM */
473 fmc_state_enum eeprom_word_program(uint32_t address, uint32_t data);
474 /* read a word at the corresponding address in EEPROM */
475 uint32_t eeprom_word_read(uint32_t address);
476 
477 /* FMC option bytes 0 functions */
478 /* unlock the option bytes 0 operation */
479 void ob_unlock(void);
480 /* lock the option bytes 0 operation */
481 void ob_lock(void);
482 /* force to reload the option bytes 0 */
483 void ob_reset(void);
484 /* erase the option bytes 0 */
485 fmc_state_enum ob_erase(void);
486 /* enable option bytes 0 write protection */
487 fmc_state_enum ob_write_protection_enable(fmc_area_enum wp_area, uint32_t ob_wp);
488 /* configure security protection */
489 fmc_state_enum ob_security_protection_config(uint16_t ob_spc);
490 /* program the FMC user option bytes 0 */
491 fmc_state_enum ob_user_write(uint16_t ob_user);
492 /* program the FMC data option bytes 0 */
493 fmc_state_enum ob_data_program(uint16_t ob_data);
494 /* get the value of FMC option bytes OB_USER in FMC_OBSTAT register */
495 uint8_t ob_user_get(void);
496 /* get the value of FMC option bytes OB_DATA in FMC_OBSTAT register */
497 uint16_t ob_data_get(void);
498 /* get the value of FMC option bytes BK0WP in FMC_WP0 register */
499 uint32_t ob_write_protection_get(void);
500 /* get the value of FMC option bytes BK1WP in FMC_WP1 register */
501 uint8_t ob_bk1_write_protection_get(void);
502 /* get the value of FMC option bytes DFWP in FMC_WP1 register */
503 uint8_t ob_df_write_protection_get(void);
504 /* get the value of FMC option bytes EPWP in FMC_WP1 register */
505 uint8_t ob_ep_write_protection_get(void);
506 /* get the value of FMC option bytes 0 security protection level (PLEVEL) in FMC_OBSTAT register */
507 uint8_t ob_plevel_get(void);
508 
509 /* FMC option bytes 1 functions */
510 /* configure lock value in option bytes 1 */
511 fmc_state_enum ob1_lock_config(uint32_t lk_value);
512 /* configure the EPLOAD value of option bytes 1 loaded after the system reset */
513 fmc_state_enum ob1_epload_config(uint32_t epload);
514 /* configure option bytes 1 EEPROM parameters */
515 fmc_state_enum ob1_eeprom_parameter_config(uint32_t efalc, uint32_t epsize);
516 /* get data flash size in byte unit */
517 uint32_t dflash_size_get(void);
518 /* get EEPROM backup size in byte unit */
519 uint32_t eeprom_backup_size_get(void);
520 /* get EEPROM size in byte unit */
521 uint32_t eeprom_size_get(void);
522 
523 /* interrupt & flag functions */
524 /* get FMC flag status */
525 FlagStatus fmc_flag_get(fmc_flag_enum flag);
526 /* clear FMC flag status */
527 void fmc_flag_clear(fmc_flag_enum flag);
528 /* enable FMC interrupt */
529 void fmc_interrupt_enable(fmc_interrupt_enum interrupt);
530 /* disable FMC interrupt */
531 void fmc_interrupt_disable(fmc_interrupt_enum interrupt);
532 /* get FMC interrupt flag status */
533 FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag);
534 /* clear FMC interrupt flag status */
535 void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag);
536 
537 #endif /* GD32A50X_FMC_H */
538