1 /*!
2  * @file       apm32f4xx_fmc.h
3  *
4  * @brief      This file contains all the functions prototypes for the FMC firmware library
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Define to prevent recursive inclusion */
27 #ifndef __APM32F4XX_FMC_H
28 #define __APM32F4XX_FMC_H
29 
30 #ifdef __cplusplus
31   extern "C" {
32 #endif
33 
34 /* Includes */
35 #include "apm32f4xx.h"
36 
37 /** @addtogroup APM32F4xx_StdPeriphDriver
38   @{
39 */
40 
41 /** @addtogroup FMC_Driver
42   @{
43 */
44 
45 /** @defgroup FMC_Enumerations
46   @{
47 */
48 
49 /**
50  * @brief FMC Status
51  */
52 typedef enum
53 {
54     FMC_BUSY = 1,           /*!< Busy */
55     FMC_ERROR_RD,           /*!< Reserved */
56     FMC_ERROR_PGS,          /*!< Programming Sequence Error */
57     FMC_ERROR_PGP,          /*!< Programming Parallelism Error */
58     FMC_ERROR_PGA,          /*!< Programming Alignment Error */
59     FMC_ERROR_WRP,          /*!< Write Protection Error */
60     FMC_ERROR_PROGRAM,      /*!< Programming Error */
61     FMC_ERROR_OPERATION,    /*!< Operation Error */
62     FMC_COMPLETE            /*!< Operation Complete */
63 } FMC_STATUS_T;
64 
65 /**
66  * @brief FMC Latency
67  */
68 typedef enum
69 {
70     FMC_LTNCY_0    = ((uint8_t)0x0000), /*!< FMC 0 Latency cycle */
71     FMC_LTNCY_1    = ((uint8_t)0x0001), /*!< FMC 1 Latency cycle */
72     FMC_LTNCY_2    = ((uint8_t)0x0002), /*!< FMC 2 Latency cycles */
73     FMC_LTNCY_3    = ((uint8_t)0x0003), /*!< FMC 3 Latency cycles */
74     FMC_LTNCY_4    = ((uint8_t)0x0004), /*!< FMC 4 Latency cycles */
75     FMC_LTNCY_5    = ((uint8_t)0x0005), /*!< FMC 5 Latency cycles */
76     FMC_LTNCY_6    = ((uint8_t)0x0006), /*!< FMC 6 Latency cycles */
77     FMC_LTNCY_7    = ((uint8_t)0x0007), /*!< FMC 7 Latency cycles */
78     FMC_LTNCY_8    = ((uint8_t)0x0008), /*!< FMC 8 Latency cycles */
79     FMC_LTNCY_9    = ((uint8_t)0x0009), /*!< FMC 9 Latency cycles */
80     FMC_LTNCY_10   = ((uint8_t)0x000A), /*!< FMC 10 Latency cycles */
81     FMC_LTNCY_11   = ((uint8_t)0x000B), /*!< FMC 11 Latency cycles */
82     FMC_LTNCY_12   = ((uint8_t)0x000C), /*!< FMC 12 Latency cycles */
83     FMC_LTNCY_13   = ((uint8_t)0x000D), /*!< FMC 13 Latency cycles */
84     FMC_LTNCY_14   = ((uint8_t)0x000E), /*!< FMC 14 Latency cycles */
85     FMC_LTNCY_15   = ((uint8_t)0x000F)  /*!< FMC 15 Latency cycles */
86 } FMC_LATENCY_T;
87 
88 /**
89  * @brief FMC Voltage Range
90  */
91 typedef enum
92 {
93     FMC_VOLTAGE_1  = (uint8_t)0x00, /*!< when the device voltage range is 1.8V to 2.1V,
94                                         the operation will be done by byte (8-bit) */
95     FMC_VOLTAGE_2  = (uint8_t)0x01, /*!< when the device voltage range is 2.1V to 2.7V,
96                                         the operation will be done by half word (16-bit) */
97     FMC_VOLTAGE_3  = (uint8_t)0x02, /*!< when the device voltage range is 2.7V to 3.6V,
98                                         the operation will be done by word (32-bit) */
99     FMC_VOLTAGE_4  = (uint8_t)0x03, /*!< when the device voltage range is 2.7V to 3.6V + External Vpp,
100                                         the operation will be done by double word (64-bit) */
101 } FMC_VOLTAGE_T;
102 
103 /**
104  * @brief FMC Sectors
105  */
106 typedef enum
107 {
108     FMC_SECTOR_0   = ((uint16_t)0x0000),    /*!< Sector number 0 */
109     FMC_SECTOR_1   = ((uint16_t)0x0008),    /*!< Sector number 1 */
110     FMC_SECTOR_2   = ((uint16_t)0x0010),    /*!< Sector number 2 */
111     FMC_SECTOR_3   = ((uint16_t)0x0018),    /*!< Sector number 3 */
112     FMC_SECTOR_4   = ((uint16_t)0x0020),    /*!< Sector number 4 */
113     FMC_SECTOR_5   = ((uint16_t)0x0028),    /*!< Sector number 5 */
114     FMC_SECTOR_6   = ((uint16_t)0x0030),    /*!< Sector number 6 */
115     FMC_SECTOR_7   = ((uint16_t)0x0038),    /*!< Sector number 7 */
116     FMC_SECTOR_8   = ((uint16_t)0x0040),    /*!< Sector number 8 */
117     FMC_SECTOR_9   = ((uint16_t)0x0048),    /*!< Sector number 9 */
118     FMC_SECTOR_10  = ((uint16_t)0x0050),    /*!< Sector number 10 */
119     FMC_SECTOR_11  = ((uint16_t)0x0058),    /*!< Sector number 11 */
120     FMC_SECTOR_12  = ((uint16_t)0x0080),    /*!< Sector number 12 */
121     FMC_SECTOR_13  = ((uint16_t)0x0088),    /*!< Sector number 13 */
122     FMC_SECTOR_14  = ((uint16_t)0x0090),    /*!< Sector number 14 */
123     FMC_SECTOR_15  = ((uint16_t)0x0098),    /*!< Sector number 15 */
124     FMC_SECTOR_16  = ((uint16_t)0x00A0),    /*!< Sector number 16 */
125     FMC_SECTOR_17  = ((uint16_t)0x00A8),    /*!< Sector number 17 */
126     FMC_SECTOR_18  = ((uint16_t)0x00B0),    /*!< Sector number 18 */
127     FMC_SECTOR_19  = ((uint16_t)0x00B8),    /*!< Sector number 19 */
128     FMC_SECTOR_20  = ((uint16_t)0x00C0),    /*!< Sector number 20 */
129     FMC_SECTOR_21  = ((uint16_t)0x00C8),    /*!< Sector number 21 */
130     FMC_SECTOR_22  = ((uint16_t)0x00D0),    /*!< Sector number 22 */
131     FMC_SECTOR_23  = ((uint16_t)0x00D8)     /*!< Sector number 23 */
132 } FMC_SECTOR_T;
133 
134 /**
135  * @brief Option Bytes Write Protection
136  */
137 typedef enum
138 {
139     FMC_OPT_WRP_SECTOR_0   = (uint32_t)0x00000001,  /*!< Write protection of sector 0 */
140     FMC_OPT_WRP_SECTOR_1   = (uint32_t)0x00000002,  /*!< Write protection of sector 1 */
141     FMC_OPT_WRP_SECTOR_2   = (uint32_t)0x00000004,  /*!< Write protection of sector 2 */
142     FMC_OPT_WRP_SECTOR_3   = (uint32_t)0x00000008,  /*!< Write protection of sector 3 */
143     FMC_OPT_WRP_SECTOR_4   = (uint32_t)0x00000010,  /*!< Write protection of sector 4 */
144     FMC_OPT_WRP_SECTOR_5   = (uint32_t)0x00000020,  /*!< Write protection of sector 5 */
145     FMC_OPT_WRP_SECTOR_6   = (uint32_t)0x00000040,  /*!< Write protection of sector 6 */
146     FMC_OPT_WRP_SECTOR_7   = (uint32_t)0x00000080,  /*!< Write protection of sector 7 */
147     FMC_OPT_WRP_SECTOR_8   = (uint32_t)0x00000100,  /*!< Write protection of sector 8 */
148     FMC_OPT_WRP_SECTOR_9   = (uint32_t)0x00000200,  /*!< Write protection of sector 9 */
149     FMC_OPT_WRP_SECTOR_10  = (uint32_t)0x00000400,  /*!< Write protection of sector 10 */
150     FMC_OPT_WRP_SECTOR_11  = (uint32_t)0x00000800,  /*!< Write protection of sector 11 */
151 
152     FMC_OPT_WRP_SECTOR_12  = (uint32_t)0x00000001,  /*!< Write protection of sector 12 */
153     FMC_OPT_WRP_SECTOR_13  = (uint32_t)0x00000002,  /*!< Write protection of sector 13 */
154     FMC_OPT_WRP_SECTOR_14  = (uint32_t)0x00000004,  /*!< Write protection of sector 14 */
155     FMC_OPT_WRP_SECTOR_15  = (uint32_t)0x00000008,  /*!< Write protection of sector 15 */
156     FMC_OPT_WRP_SECTOR_16  = (uint32_t)0x00000010,  /*!< Write protection of sector 16 */
157     FMC_OPT_WRP_SECTOR_17  = (uint32_t)0x00000020,  /*!< Write protection of sector 17 */
158     FMC_OPT_WRP_SECTOR_18  = (uint32_t)0x00000040,  /*!< Write protection of sector 18 */
159     FMC_OPT_WRP_SECTOR_19  = (uint32_t)0x00000080,  /*!< Write protection of sector 19 */
160     FMC_OPT_WRP_SECTOR_20  = (uint32_t)0x00000100,  /*!< Write protection of sector 20 */
161     FMC_OPT_WRP_SECTOR_21  = (uint32_t)0x00000200,  /*!< Write protection of sector 21 */
162     FMC_OPT_WRP_SECTOR_22  = (uint32_t)0x00000400,  /*!< Write protection of sector 22 */
163     FMC_OPT_WRP_SECTOR_23  = (uint32_t)0x00000800,  /*!< Write protection of sector 23 */
164     FMC_OPT_WRP_SECTOR_All = (uint32_t)0x00000FFF   /*!< Write protection of sector 24 */
165 } FMC_OPT_WRP_T;
166 
167 /**
168  * @brief FMC Option Bytes Read Protection
169  */
170 typedef enum
171 {
172     FMC_OPT_RDP_LV0 =(uint8_t)0xAA,     /*!< No protection */
173     FMC_OPT_RDP_LV1 =(uint8_t)0x55      /*!< Read protection of the memory */
174 } FMC_OPT_RDP_T;
175 
176 /**
177  * @brief FMC Option Bytes Independent Watchdog
178  */
179 typedef enum
180 {
181     FMC_OPT_IWDT_SOFT = (uint8_t)0x20,  /*!< Software IWDT selected */
182     FMC_OPT_IWDT_HARD = (uint8_t)0x00   /*!< Hardware IWDT selected */
183 } FMC_OPT_IWDT_T;
184 
185 /**
186  * @brief FMC Option Bytes nRST STOP
187  */
188 typedef enum
189 {
190     FMC_OPT_STOP_NORST = (uint8_t)0x40, /*!< No reset generated when entering in STOP */
191     FMC_OPT_STOP_RST   = (uint8_t)0x00  /*!< Reset generated when entering in STOP */
192 } FMC_OPT_STOP_T;
193 
194 /**
195  * @brief FMC Option Bytes nRST STDBY
196  */
197 typedef enum
198 {
199     FMC_OPT_STDBY_NORST = (uint8_t)0x80,    /*!< No reset generated when entering in STANDBY */
200     FMC_OPT_STDBY_RST   = (uint8_t)0x00     /*!< Reset generated when entering in STANDBY */
201 } FMC_OPT_STDBY_T;
202 
203 /**
204  * @brief FMC BOR Reset Level
205  */
206 typedef enum
207 {
208     FMC_OPT_BOR_LV3 = (uint8_t)0x00,    /*!< Supply voltage ranges from 2.7 to 3.6 V */
209     FMC_OPT_BOR_LV2 = (uint8_t)0x04,    /*!< Supply voltage ranges from 2.4 to 2.7 V */
210     FMC_OPT_BOR_LV1 = (uint8_t)0x08,    /*!< Supply voltage ranges from 2.1 to 2.4 V */
211     FMC_OPT_BOR_OFF = (uint8_t)0x0C     /*!< Supply voltage ranges from 1.62 to 2.1 V */
212 } FMC_OPT_BOR_T;
213 
214 /**
215  * @brief FMC Dual Boot
216  */
217 typedef enum
218 {
219     FMC_OPT_BOOTEN  = (uint8_t)0x10,    /*!< Dual boot mode enable */
220     FMC_OPT_BOOTDIS = (uint8_t)0x00     /*!< Dual boot mode disable */
221 } FMC_OPT_BOOT_T;
222 
223 /**
224  * @brief FMC Interrupts
225  */
226 typedef enum
227 {
228     FMC_INT_OC  = (uint32_t)0x01000000, /*!< Operation Complete Interrupt */
229     FMC_INT_ERR = (uint32_t)0x02000000  /*!< Error Interrupt */
230 } FMC_INT_T;
231 
232 /**
233  * @brief FMC Flags
234  */
235 typedef enum
236 {
237     FMC_FLAG_ENDOP  = (uint32_t)0x00000001, /*!< FMC End of Operation flag */
238     FMC_FLAG_ERROP  = (uint32_t)0x00000002, /*!< FMC operation Error flag */
239     FMC_FLAG_ERRWRP = (uint32_t)0x00000010, /*!< FMC Write protected error flag */
240     FMC_FLAG_ERRPGA = (uint32_t)0x00000020, /*!< FMC Programming Alignment error flag */
241     FMC_FLAG_ERRPGP = (uint32_t)0x00000040, /*!< FMC Programming Parallelism error flag */
242     FMC_FLAG_ERRPGS = (uint32_t)0x00000080, /*!< FMC Programming Sequence error flag */
243     FMC_FLAG_BUSY   = (uint32_t)0x00010000  /*!< FMC Busy flag */
244 } FMC_FLAG_T;
245 
246 /**
247  * @brief FMC Program Parallelism
248  */
249 typedef enum
250 {
251     FMC_PSIZE_BYTE        = (uint32_t)0x00000000,   /*!< Set program parallelism to 8-bit */
252     FMC_PSIZE_HALF_WORD   = (uint32_t)0x00000100,   /*!< Set program parallelism to 16-bit */
253     FMC_PSIZE_WORD        = (uint32_t)0x00000200,   /*!< Set program parallelism to 32-bit */
254     FMC_PSIZE_DOUBLE_WORD = (uint32_t)0x00000300    /*!< Set program parallelism to 64-bit */
255 } FMC_PSIZE_T;
256 
257 /**@} end of group FMC_Enumerations*/
258 
259 /** @defgroup FMC_Macros Macros
260   @{
261 */
262 
263 #define PMC_RDP_KEY            ((uint16_t)0x00A5)
264 #define FMC_KEY1               ((uint32_t)0x45670123)
265 #define FMC_KEY2               ((uint32_t)0xCDEF89AB)
266 #define FMC_OPT_KEY1           ((uint32_t)0x08192A3B)
267 #define FMC_OPT_KEY2           ((uint32_t)0x4C5D6E7F)
268 
269 /* FMC ACCTRL register Bits definition */
270 #define FMC_ACCTRL_PREFEN      ((uint32_t)0x00000100)
271 #define FMC_ACCTRL_ICACHEEN    ((uint32_t)0x00000200)
272 #define FMC_ACCTRL_DCACHEEN    ((uint32_t)0x00000400)
273 #define FMC_ACCTRL_ICACHERST   ((uint32_t)0x00000800)
274 #define FMC_ACCTRL_DCACHERST   ((uint32_t)0x00001000)
275 
276 /* FMC CTRL register Bits definition */
277 #define FMC_CTRL_PG            ((uint32_t)0x00000001)
278 #define FMC_CTRL_SERS          ((uint32_t)0x00000002)
279 #define FMC_CTRL_MERS          ((uint32_t)0x00000004)
280 #define FMC_CTRL_SNUM          ((uint32_t)0x00000008)
281 #define FMC_CTRL_START         ((uint32_t)0x00010000)
282 #define FMC_CTRL_LOCK          ((uint32_t)0x80000000)
283 
284 /* FMC OPTCTRL register Bits definition */
285 #define FMC_OPTCTRL_OPTLOCK    ((uint32_t)0x00000001)
286 #define FMC_OPTCTRL_OPTSTART   ((uint32_t)0x00000002)
287 #define FMC_OPTCTRL_BORLVL     ((uint32_t)0x0000000C)
288 
289 /* ACCTRL  register byte 0 (Bits[7:0]) base address */
290 #define ACCTRL_BYTE0_ADDRESS          ((uint32_t)0x40023C00)
291 
292 /* OPTCTRL register byte 0 (Bits[7:0]) base address */
293 #define OPTCTRL_BYTE0_ADDRESS         ((uint32_t)0x40023C14)
294 
295 /* OPTCTRL register byte 1 (Bits[15:8]) base address */
296 #define OPTCTRL_BYTE1_ADDRESS         ((uint32_t)0x40023C15)
297 
298 /* OPTCTRL register byte 2 (Bits[23:16]) base address */
299 #define OPTCTRL_BYTE2_ADDRESS         ((uint32_t)0x40023C16)
300 
301 /* OPTCTRL register byte 3 (Bits[31:24]) base address */
302 #define OPTCTRL_BYTE3_ADDRESS         ((uint32_t)0x40023C17)
303 
304 /**@} end of group FMC_Macros*/
305 
306 /** @defgroup FMC_Functions
307   @{
308 */
309 
310 /* FMC Interface configuration functions */
311 void FMC_ConfigLatency(FMC_LATENCY_T latency);
312 void FMC_EnablePrefetchBuffer(void);
313 void FMC_DisablePrefetchBuffer(void);
314 void FMC_EnableInstructionCache(void);
315 void FMC_DisableInstructionCache(void);
316 void FMC_EnableDataCache(void);
317 void FMC_DisableDataCache(void);
318 void FMC_ResetInstructionCache(void);
319 void FMC_ResetDataCache(void);
320 
321 /* FMC Memory Programming functions */
322 void FMC_Unlock(void);
323 void FMC_Lock(void);
324 FMC_STATUS_T FMC_EraseSector(FMC_SECTOR_T sector, FMC_VOLTAGE_T voltageRange);
325 FMC_STATUS_T FMC_EraseAllSectors(FMC_VOLTAGE_T voltageRange);
326 FMC_STATUS_T FMC_ProgramDoubleWord(uint32_t address, uint64_t data);
327 FMC_STATUS_T FMC_ProgramWord(uint32_t address, uint32_t data);
328 FMC_STATUS_T FMC_ProgramHalfWord(uint32_t address, uint16_t data);
329 FMC_STATUS_T FMC_ProgramByte(uint32_t address, uint8_t data);
330 
331 /* Option Bytes Programming functions */
332 void FMC_UnlockOptionByte(void);
333 void FMC_LockOptionByte(void);
334 void FMC_OPT_EnableWriteProtect(FMC_OPT_WRP_T wrp);
335 void FMC_OPT_DisableWriteProtect(FMC_OPT_WRP_T wrp);
336 void FMC_OPT_ConfigReadProtect(FMC_OPT_RDP_T rdp);
337 void FMC_OPT_ConfigUser(FMC_OPT_IWDT_T iwdt, FMC_OPT_STOP_T stop, FMC_OPT_STDBY_T stdby);
338 void FMC_OPT_ConfigBrownoutReset(FMC_OPT_BOR_T bor);
339 FMC_STATUS_T FMC_OPT_Launch(void);
340 uint8_t FMC_OPT_ReadUser(void);
341 uint16_t FMC_OPT_ReadWriteProtect(void);
342 uint8_t FMC_OPT_ReadProtectLevel(void);
343 uint8_t FMC_OPT_ReadBrownoutReset(void);
344 
345 /* Interrupts and flags management functions */
346 void FMC_EnableInterrupt(uint32_t interrupt);
347 void FMC_DisableInterrupt(uint32_t interrupt);
348 uint8_t FMC_ReadStatusFlag(FMC_FLAG_T flag);
349 void FMC_ClearStatusFlag(uint32_t flag);
350 FMC_STATUS_T FMC_ReadStatus(void);
351 FMC_STATUS_T FMC_WaitForLastOperation(void);
352 
353 #ifdef __cplusplus
354 }
355 #endif
356 
357 #endif /* __APM32F4XX_FMC_H */
358 
359 /**@} end of group FMC_Enumerations */
360 /**@} end of group FMC_Driver */
361 /**@} end of group APM32F4xx_StdPeriphDriver */
362