1 /*!
2     \file    gd32a50x_fmc.c
3     \brief   FMC driver
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 #include "gd32a50x_fmc.h"
36 
37 /* FMC mask */
38 #define LOW_8BITS_MASK                  ((uint32_t)0x000000FFU)               /*!< the 0-7 bits mask of a word */
39 #define HIGH_8BITS_MASK                 ((uint32_t)0x0000FF00U)               /*!< the 8-15 bits mask of a word */
40 #define LOW_8BITS_MASK1                 ((uint32_t)0x00FF0000U)               /*!< the 16-23 bits mask of a word */
41 #define HIGH_8BITS_MASK1                ((uint32_t)0xFF000000U)               /*!< the 24-31 bits mask of a word */
42 #define LOW_16BITS_MASK                 ((uint32_t)0x0000FFFFU)               /*!< the 0-15 bits mask of a word */
43 #define HIGH_16BITS_MASK                ((uint32_t)0xFFFF0000U)               /*!< the 16-31 bits mask of a word */
44 #define ECCCS_FLAG_MASK                 ((uint32_t)0xEC000000U)               /*!< flag mask in ECCCS register */
45 #define ECCCS_ERROR_MASK                ((uint32_t)0x00F10000U)               /*!< error flag mask in ECCCS register */
46 
47 /* FMC register bit offset */
48 #define CTL_CBCMDLEN_OFFSET             ((uint32_t)0x0000001DU)               /*!< CBCMDLEN offset in FMC_CTL register */
49 #define OBSTAT_PLEVEL_OFFSET            ((uint32_t)0x00000001U)               /*!< PLEVEL offset in FMC_OBSTAT register */
50 #define OBSTAT_USER_OFFSET              ((uint32_t)0x00000008U)               /*!< USER offset in FMC_OBSTAT register */
51 #define OBSTAT_DATA_OFFSET              ((uint32_t)0x00000010U)               /*!< DATA offset in FMC_OBSTAT register */
52 #define WP1_BK1WP_OFFSET                ((uint32_t)0x00000000U)               /*!< BK1WP offset in FMC_WP1 register */
53 #define WP1_DFWP_OFFSET                 ((uint32_t)0x00000008U)               /*!< DFWP offset in FMC_WP1 register */
54 #define WP1_EPWP_OFFSET                 ((uint32_t)0x00000010U)               /*!< EPWP offset in FMC_WP1 register */
55 #define ECCCS_REG_OFFSET                ((uint32_t)0x00000004U)               /*!< ECCCS register offset */
56 
57 /* return the FMC bank0 state */
58 static fmc_state_enum fmc_bank0_state_get(void);
59 /* return the FMC bank1 state */
60 static fmc_state_enum fmc_bank1_state_get(void);
61 /* check FMC bank0 ready or not */
62 static fmc_state_enum fmc_bank0_ready_wait(uint32_t timeout);
63 /* check FMC bank1 ready or not */
64 static fmc_state_enum fmc_bank1_ready_wait(uint32_t timeout);
65 /* wait shared SRAM mode to be ready */
66 static void fmc_sram_mode_ready_wait(uint32_t ready_flag);
67 
68 /*!
69     \brief      unlock the main flash operation
70                 it is better to used in pairs with fmc_lock
71     \param[in]  none
72     \param[out] none
73     \retval     none
74 */
fmc_unlock(void)75 void fmc_unlock(void)
76 {
77     if((0U != (FMC_CTL0 & FMC_CTL0_LK))) {
78         /* write the FMC bank0 key */
79         FMC_KEY0 = UNLOCK_KEY0;
80         FMC_KEY0 = UNLOCK_KEY1;
81     }
82 
83     if((0U != (FMC_CTL1 & FMC_CTL1_LK))) {
84         /* write the FMC bank1 key */
85         FMC_KEY1 = UNLOCK_KEY0;
86         FMC_KEY1 = UNLOCK_KEY1;
87     }
88 }
89 
90 /*!
91     \brief      unlock the main flash bank0 operation
92                 it is better to used in pairs with fmc_bank0_lock
93     \param[in]  none
94     \param[out] none
95     \retval     none
96 */
fmc_bank0_unlock(void)97 void fmc_bank0_unlock(void)
98 {
99     if((0U != (FMC_CTL0 & FMC_CTL0_LK))) {
100         /* write the FMC bank0 key */
101         FMC_KEY0 = UNLOCK_KEY0;
102         FMC_KEY0 = UNLOCK_KEY1;
103     }
104 }
105 
106 /*!
107     \brief      unlock the main flash bank1 operation
108                 it is better to used in pairs with fmc_bank1_lock
109     \param[in]  none
110     \param[out] none
111     \retval     none
112 */
fmc_bank1_unlock(void)113 void fmc_bank1_unlock(void)
114 {
115     if((0U != (FMC_CTL1 & FMC_CTL1_LK))) {
116         /* write the FMC bank1 key */
117         FMC_KEY1 = UNLOCK_KEY0;
118         FMC_KEY1 = UNLOCK_KEY1;
119     }
120 }
121 
122 /*!
123     \brief      lock the main flash operation
124                 it is better to used in pairs with fmc_unlock after an operation
125     \param[in]  none
126     \param[out] none
127     \retval     none
128 */
fmc_lock(void)129 void fmc_lock(void)
130 {
131     /* set the bank0 LK bit*/
132     FMC_CTL0 |= FMC_CTL0_LK;
133 
134     /* set the bank1 LK bit*/
135     FMC_CTL1 |= FMC_CTL1_LK;
136 }
137 
138 /*!
139     \brief      lock the main flash bank0 operation
140                 it is better to used in pairs with fmc_bank0_unlock after an operation
141     \param[in]  none
142     \param[out] none
143     \retval     none
144 */
fmc_bank0_lock(void)145 void fmc_bank0_lock(void)
146 {
147     /* set the LK bit*/
148     FMC_CTL0 |= FMC_CTL0_LK;
149 }
150 
151 /*!
152     \brief      lock the main flash bank1 operation
153                 it is better to used in pairs with fmc_bank1_unlock after an operation
154     \param[in]  none
155     \param[out] none
156     \retval     none
157 */
fmc_bank1_lock(void)158 void fmc_bank1_lock(void)
159 {
160     /* set the LK bit*/
161     FMC_CTL1 |= FMC_CTL1_LK;
162 }
163 
164 /*!
165     \brief      set the wait state counter value
166     \param[in]  wscnt: wait state counter value
167                 only one parameter can be selected which is shown as below:
168       \arg        WS_WSCNT_0: 0 wait state added
169       \arg        WS_WSCNT_1: 1 wait state added
170       \arg        WS_WSCNT_2: 2 wait state added
171       \arg        WS_WSCNT_3: 3 wait state added
172     \param[out] none
173     \retval     none
174 */
fmc_wscnt_set(uint8_t wscnt)175 void fmc_wscnt_set(uint8_t wscnt)
176 {
177     uint32_t reg;
178 
179     reg = FMC_WS;
180     /* set the wait state counter value */
181     reg &= ~FMC_WS_WSCNT;
182     FMC_WS = (reg | wscnt);
183 }
184 
185 /*!
186     \brief      enable pre-fetch
187     \param[in]  none
188     \param[out] none
189     \retval     none
190 */
fmc_prefetch_enable(void)191 void fmc_prefetch_enable(void)
192 {
193     FMC_WS |= FMC_WS_PFEN;
194 }
195 
196 /*!
197     \brief      disable pre-fetch
198     \param[in]  none
199     \param[out] none
200     \retval     none
201 */
fmc_prefetch_disable(void)202 void fmc_prefetch_disable(void)
203 {
204     FMC_WS &= ~FMC_WS_PFEN;
205 }
206 
207 /*!
208     \brief      enable cache
209     \param[in]  none
210     \param[out] none
211     \retval     none
212 */
fmc_cache_enable(void)213 void fmc_cache_enable(void)
214 {
215     FMC_WS |= FMC_WS_IDCEN;
216 }
217 
218 /*!
219     \brief      disable cache
220     \param[in]  none
221     \param[out] none
222     \retval     none
223 */
fmc_cache_disable(void)224 void fmc_cache_disable(void)
225 {
226     FMC_WS &= ~FMC_WS_IDCEN;
227 }
228 
229 /*!
230     \brief      enable cache reset if cache is disabled
231     \param[in]  none
232     \param[out] none
233     \retval     none
234 */
fmc_cache_reset_enable(void)235 void fmc_cache_reset_enable(void)
236 {
237     FMC_WS |= FMC_WS_IDRST;
238 }
239 
240 /*!
241     \brief      disable cache reset
242     \param[in]  none
243     \param[out] none
244     \retval     none
245 */
fmc_cache_reset_disable(void)246 void fmc_cache_reset_disable(void)
247 {
248     FMC_WS &= ~FMC_WS_IDRST;
249 }
250 
251 /*!
252     \brief      flash goto power-down mode when MCU enters deepsleep mode
253     \param[in]  none
254     \param[out] none
255     \retval     none
256 */
fmc_powerdown_mode_set(void)257 void fmc_powerdown_mode_set(void)
258 {
259     FMC_WS &= ~FMC_WS_SLEEP_SLP;
260 }
261 
262 /*!
263     \brief      flash goto sleep mode when MCU enters deepsleep mode
264     \param[in]  none
265     \param[out] none
266     \retval     none
267 */
fmc_sleep_mode_set(void)268 void fmc_sleep_mode_set(void)
269 {
270     FMC_WS |= FMC_WS_SLEEP_SLP;
271 }
272 
273 /*!
274     \brief      configure shared SRAM mode
275     \param[in]  sram_mode: shared SRAM mode
276                 only one parameter can be selected which is shown as below:
277       \arg        FASTPG_SRAM_MODE: fast program SRAM mode
278       \arg        BASIC_SRAM_MODE: basic SRAM mode
279       \arg        EEPROM_SRAM_MODE: EEPROM SRAM mode
280     \param[out] none
281     \retval     none
282 */
fmc_sram_mode_config(fmc_sram_mode_enum sram_mode)283 void fmc_sram_mode_config(fmc_sram_mode_enum sram_mode)
284 {
285     fmc_sram_mode_enum curr_mode;
286 
287     curr_mode = fmc_sram_mode_get();
288     FMC_CTL1 &= ~FMC_CTL1_SRAMCMD;
289     if((EEPROM_SRAM_MODE == sram_mode) && (EEPROM_SRAM_MODE != curr_mode)) {
290         /* set shared SRAM to EEPROM SRAM mode*/
291         FMC_CTL1 |= EEPROM_SRAM_CMD;
292         fmc_sram_mode_ready_wait(FMC_WS_ERAMRDY);
293     } else if((BASIC_SRAM_MODE == sram_mode) && (BASIC_SRAM_MODE != curr_mode)) {
294         /* set shared SRAM to basic SRAM mode*/
295         FMC_CTL1 |= BASIC_SRAM_CMD;
296         fmc_sram_mode_ready_wait(FMC_WS_BRAMRDY);
297     } else if((FASTPG_SRAM_MODE == sram_mode) && (FASTPG_SRAM_MODE != curr_mode)) {
298         /* set shared SRAM to fast program SRAM mode*/
299         FMC_CTL1 |= FASTPG_SRAM_CMD;
300         fmc_sram_mode_ready_wait(FMC_WS_PRAMRDY);
301     } else {
302         /* illegal parameters */
303     }
304 }
305 
306 /*!
307     \brief      get shared SRAM mode
308     \param[in]  none
309     \param[out] none
310     \retval     sram_mode: shared SRAM mode
311       \arg        NO_SRAM_MODE: SRAM mode is not configured
312       \arg        FASTPG_SRAM_MODE: fast PG SRAM mode
313       \arg        BASIC_SRAM_MODE: basic SRAM mode
314       \arg        EEPROM_SRAM_MODE: EEPROM SRAM mode
315 */
fmc_sram_mode_get(void)316 fmc_sram_mode_enum fmc_sram_mode_get(void)
317 {
318     fmc_sram_mode_enum sram_mode;
319 
320     if(0U != (FMC_WS & FMC_WS_ERAMRDY)) {
321         /* SRAM is in EEPROM SRAM mode*/
322         sram_mode = EEPROM_SRAM_MODE;
323     } else if(0U != (FMC_WS & FMC_WS_BRAMRDY)) {
324         /* SRAM is in basic SRAM mode*/
325         sram_mode = BASIC_SRAM_MODE;
326     } else if(0U != (FMC_WS & FMC_WS_PRAMRDY)) {
327         /* SRAM is in fast program SRAM mode*/
328         sram_mode = FASTPG_SRAM_MODE;
329     } else {
330         sram_mode = NO_SRAM_MODE;
331     }
332 
333     return sram_mode;
334 }
335 
336 /*!
337     \brief      check whether flash page is blank or not by check blank command
338     \param[in]  address: start address to check
339     \param[in]  length: the read length is 2^length double words, the flash area to be checked must be in one page and should not exceed 1KB boundary
340     \param[out] none
341     \retval     state of FMC, refer to fmc_state_enum
342       \arg        FMC_READY: the operation has been completed
343       \arg        FMC_BUSY: the operation is in progress
344       \arg        FMC_PGSERR:  program sequence error
345       \arg        FMC_PGERR: program error
346       \arg        FMC_PGAERR: program alignment error
347       \arg        FMC_WPERR: erase/program protection error
348       \arg        FMC_TOERR: timeout error
349       \arg        FMC_CBCMDERR: the checked area not blank error
350       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
351 */
fmc_blank_check(uint32_t address,uint8_t length)352 fmc_state_enum fmc_blank_check(uint32_t address, uint8_t length)
353 {
354     fmc_state_enum fmc_state;
355 
356     if((address >= BANK0_BASE_ADDRESS) && (address < BANK1_BASE_ADDRESS)) {
357         /* start check blank command */
358         FMC_ADDR0 = address;
359         FMC_CTL0 &= ~FMC_CTL0_CBCMDLEN;
360         FMC_CTL0 |= (uint32_t)length << CTL_CBCMDLEN_OFFSET;
361         FMC_CTL0 |= FMC_CTL0_CBCMD;
362         FMC_CTL0 |= FMC_CTL0_START;
363 
364         /* wait for the FMC ready */
365         fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
366 
367         /* reset the CBCMD bit */
368         FMC_CTL0 &= ~FMC_CTL0_CBCMD;
369     } else {
370         /* start check blank command */
371         FMC_ADDR1 = address;
372         FMC_CTL1 &= ~FMC_CTL1_CBCMDLEN;
373         FMC_CTL1 |= (uint32_t)length << CTL_CBCMDLEN_OFFSET;
374         FMC_CTL1 |= FMC_CTL1_CBCMD;
375         FMC_CTL1 |= FMC_CTL1_START;
376 
377         /* wait for the FMC ready */
378         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
379 
380         /* reset the CBCMD bit */
381         FMC_CTL1 &= ~FMC_CTL1_CBCMD;
382     }
383 
384     return fmc_state;
385 }
386 
387 /*!
388     \brief      erase main flash page
389     \param[in]  page_address: target page start address
390     \param[out] none
391     \retval     state of FMC, refer to fmc_state_enum
392       \arg        FMC_READY: the operation has been completed
393       \arg        FMC_BUSY: the operation is in progress
394       \arg        FMC_PGSERR:  program sequence error
395       \arg        FMC_PGERR: program error
396       \arg        FMC_PGAERR: program alignment error
397       \arg        FMC_WPERR: erase/program protection error
398       \arg        FMC_TOERR: timeout error
399       \arg        FMC_CBCMDERR: the checked area not blank error
400       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
401 */
fmc_page_erase(uint32_t page_address)402 fmc_state_enum fmc_page_erase(uint32_t page_address)
403 {
404     fmc_state_enum fmc_state = FMC_READY;
405 
406     if((page_address >= BANK0_BASE_ADDRESS) && (page_address < BANK1_BASE_ADDRESS)) {
407         fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
408 
409         if(FMC_READY == fmc_state) {
410             /* start page erase */
411             FMC_CTL0 |= FMC_CTL0_PER;
412             FMC_ADDR0 = page_address;
413             FMC_CTL0 |= FMC_CTL0_START;
414 
415             /* wait for the FMC ready */
416             fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
417 
418             /* reset the PER bit */
419             FMC_CTL0 &= ~FMC_CTL0_PER;
420         }
421     } else {
422         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
423         if(FMC_READY == fmc_state) {
424             /* start page erase */
425             FMC_CTL1 |= FMC_CTL1_PER;
426             FMC_ADDR1 = page_address;
427             FMC_CTL1 |= FMC_CTL1_START;
428 
429             /* wait for the FMC ready */
430             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
431 
432             /* reset the PER bit */
433             FMC_CTL1 &= ~FMC_CTL1_PER;
434         }
435     }
436 
437     /* return the FMC state  */
438     return fmc_state;
439 }
440 
441 /*!
442     \brief      erase flash bank0
443     \param[in]  none
444     \param[out] none
445     \retval     state of FMC, refer to fmc_state_enum
446       \arg        FMC_READY: the operation has been completed
447       \arg        FMC_BUSY: the operation is in progress
448       \arg        FMC_PGSERR:  program sequence error
449       \arg        FMC_PGERR: program error
450       \arg        FMC_PGAERR: program alignment error
451       \arg        FMC_WPERR: erase/program protection error
452       \arg        FMC_TOERR: timeout error
453       \arg        FMC_CBCMDERR: the checked area not blank error
454       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
455 */
fmc_bank0_mass_erase(void)456 fmc_state_enum fmc_bank0_mass_erase(void)
457 {
458     fmc_state_enum fmc_state;
459 
460     /* wait for the FMC ready */
461     fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
462 
463     if(FMC_READY == fmc_state) {
464         /* start chip erase */
465         FMC_CTL0 |= FMC_CTL0_MER;
466         FMC_CTL0 |= FMC_CTL0_START;
467 
468         /* wait for the FMC ready */
469         fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
470 
471         /* reset the MER bit */
472         FMC_CTL0 &= ~FMC_CTL0_MER;
473     }
474     /* return the fmc state */
475     return fmc_state;
476 }
477 
478 /*!
479     \brief      erase flash bank1
480     \param[in]  none
481     \param[out] none
482     \retval     state of FMC, refer to fmc_state_enum
483       \arg        FMC_READY: the operation has been completed
484       \arg        FMC_BUSY: the operation is in progress
485       \arg        FMC_PGSERR:  program sequence error
486       \arg        FMC_PGERR: program error
487       \arg        FMC_PGAERR: program alignment error
488       \arg        FMC_WPERR: erase/program protection error
489       \arg        FMC_TOERR: timeout error
490       \arg        FMC_CBCMDERR: the checked area not blank error
491       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
492 */
fmc_bank1_mass_erase(void)493 fmc_state_enum fmc_bank1_mass_erase(void)
494 {
495     fmc_state_enum fmc_state;
496 
497     /* wait for the FMC ready */
498     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
499 
500     if(FMC_READY == fmc_state) {
501         /* start chip erase */
502         FMC_CTL1 |= FMC_CTL1_MER;
503         FMC_CTL1 |= FMC_CTL1_START;
504 
505         /* wait for the FMC ready */
506         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
507 
508         /* reset the MER bit */
509         FMC_CTL1 &= ~FMC_CTL1_MER;
510     }
511     /* return the fmc state  */
512     return fmc_state;
513 }
514 
515 /*!
516     \brief      erase the data flash
517     \param[in]  none
518     \param[out] none
519     \retval     state of FMC, refer to fmc_state_enum
520       \arg        FMC_READY: the operation has been completed
521       \arg        FMC_BUSY: the operation is in progress
522       \arg        FMC_PGSERR:  program sequence error
523       \arg        FMC_PGERR: program error
524       \arg        FMC_PGAERR: program alignment error
525       \arg        FMC_WPERR: erase/program protection error
526       \arg        FMC_TOERR: timeout error
527       \arg        FMC_CBCMDERR: the checked area not blank error
528       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
529 */
fmc_dflash_mass_erase(void)530 fmc_state_enum fmc_dflash_mass_erase(void)
531 {
532     fmc_state_enum fmc_state;
533 
534     /* wait for the FMC ready */
535     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
536 
537     if(FMC_READY == fmc_state) {
538         /* start data flash erase */
539         FMC_CTL1 |= FMC_CTL1_MERDF;
540         FMC_CTL1 |= FMC_CTL1_START;
541 
542         /* wait for the FMC ready */
543         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
544 
545         /* reset the MERDF bit */
546         FMC_CTL1 &= ~FMC_CTL1_MERDF;
547     }
548 
549     return fmc_state;
550 }
551 
552 /*!
553     \brief      erase whole chip
554     \param[in]  none
555     \param[out] none
556     \retval     state of FMC, refer to fmc_state_enum
557       \arg        FMC_READY: the operation has been completed
558       \arg        FMC_BUSY: the operation is in progress
559       \arg        FMC_PGSERR:  program sequence error
560       \arg        FMC_PGERR: program error
561       \arg        FMC_PGAERR: program alignment error
562       \arg        FMC_WPERR: erase/program protection error
563       \arg        FMC_TOERR: timeout error
564       \arg        FMC_CBCMDERR: the checked area not blank error
565       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
566 */
fmc_mass_erase(void)567 fmc_state_enum fmc_mass_erase(void)
568 {
569     fmc_state_enum fmc_state;
570 
571     /* mass erase flash bank0 */
572     fmc_state = fmc_bank0_mass_erase();
573 
574     /* return the bank0 abnormal state */
575     if(FMC_READY != fmc_state) {
576         return fmc_state;
577     }
578 
579     /* mass erase flash bank1 */
580     fmc_state = fmc_bank1_mass_erase();
581 
582     /* return the bank1 abnormal state */
583     if(FMC_READY != fmc_state) {
584         return fmc_state;
585     }
586 
587     /* mass erase data flash */
588     fmc_state = fmc_dflash_mass_erase();
589 
590     /* return the fmc state */
591     return fmc_state;
592 }
593 
594 /*!
595     \brief      program a double word at the corresponding address in main flash
596     \param[in]  address: address to program, apply to bank0, bank1 and data flash
597     \param[in]  data: double word to program
598     \param[out] none
599     \retval     state of FMC, refer to fmc_state_enum
600       \arg        FMC_READY: the operation has been completed
601       \arg        FMC_BUSY: the operation is in progress
602       \arg        FMC_PGSERR:  program sequence error
603       \arg        FMC_PGERR: program error
604       \arg        FMC_PGAERR: program alignment error
605       \arg        FMC_WPERR: erase/program protection error
606       \arg        FMC_TOERR: timeout error
607       \arg        FMC_CBCMDERR: the checked area not blank error
608       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
609 */
fmc_doubleword_program(uint32_t address,uint64_t data)610 fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data)
611 {
612     uint32_t data0, data1;
613     fmc_state_enum fmc_state;
614 
615     if((address >= BANK0_BASE_ADDRESS) && (address < BANK1_BASE_ADDRESS)) {
616         /* wait for the FMC ready */
617         fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
618 
619         data0 = (uint32_t)(data & 0xFFFFFFFFU);
620         data1 = (uint32_t)((data >> 32U) & 0xFFFFFFFFU);
621 
622         if(FMC_READY == fmc_state) {
623             /* set the PG bit to start program */
624             FMC_CTL0 |= FMC_CTL0_PG;
625             REG32(address) = data0;
626             REG32(address + 4U) = data1;
627 
628             /* wait for the FMC ready */
629             fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
630 
631             /* reset the PG bit */
632             FMC_CTL0 &= ~FMC_CTL0_PG;
633         }
634     } else {
635         /* wait for the FMC ready */
636         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
637 
638         data0 = (uint32_t)(data & 0xFFFFFFFFU);
639         data1 = (uint32_t)((data >> 32U) & 0xFFFFFFFFU);
640 
641         if(FMC_READY == fmc_state) {
642             /* set the PG bit to start program */
643             FMC_CTL1 |= FMC_CTL1_PG;
644             REG32(address) = data0;
645             REG32(address + 4U) = data1;
646 
647             /* wait for the FMC ready */
648             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
649 
650             /* reset the PG bit */
651             FMC_CTL1 &= ~FMC_CTL1_PG;
652         }
653     }
654     /* return the FMC state */
655     return fmc_state;
656 }
657 
658 /*!
659     \brief      FMC fast program one row data (32 double-word) starting at the corresponding address
660     \param[in]  address: address to program
661     \param[in]  data: data buffer to program
662     \param[out] none
663     \retval     state of FMC, refer to fmc_state_enum
664       \arg        FMC_READY: the operation has been completed
665       \arg        FMC_BUSY: the operation is in progress
666       \arg        FMC_PGSERR:  program sequence error
667       \arg        FMC_PGERR: program error
668       \arg        FMC_PGAERR: program alignment error
669       \arg        FMC_WPERR: erase/program protection error
670       \arg        FMC_TOERR: timeout error
671       \arg        FMC_CBCMDERR: the checked area not blank error
672       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
673 */
fmc_fast_program(uint32_t address,uint64_t data[])674 fmc_state_enum fmc_fast_program(uint32_t address, uint64_t data[])
675 {
676     uint8_t index;
677     fmc_state_enum fmc_state;
678     fmc_sram_mode_enum sram_mode;
679     uint8_t cache_en = 0U;
680 
681     /* get shared SRAM mode */
682     sram_mode = fmc_sram_mode_get();
683 
684     /* set shared SRAM to fast program mode */
685     if(FASTPG_SRAM_MODE != sram_mode) {
686         fmc_sram_mode_config(FASTPG_SRAM_MODE);
687     }
688 
689     /* check the row (32 double-word) in flash to confirm all data in flash is all 0xFF */
690     fmc_state = fmc_blank_check(address, CBCMDLEN_OF_ONE_ROW);
691     if(FMC_CBCMDERR == fmc_state) {
692         /* flash is not erased */
693         return FMC_PGERR;
694     }
695     /* flush the cache if it is enabled */
696     if(FMC_WS & FMC_WS_IDCEN) {
697         cache_en = 1U;
698         fmc_cache_disable();
699     }
700     fmc_cache_reset_enable();
701     fmc_cache_reset_disable();
702 
703     if((address >= BANK0_BASE_ADDRESS) && (address < BANK1_BASE_ADDRESS)) {
704         /* wait for the FMC ready */
705         fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
706 
707         if(FMC_READY == fmc_state) {
708             /* set the FSTPG bit to start program */
709             FMC_CTL0 |= FMC_CTL0_FSTPG;
710 
711             /* program the row data */
712             for(index = 0U; index < DOUBLEWORD_CNT_IN_ROW; index++) {
713                 REG32(address) = (uint32_t)(data[index] & 0x00000000FFFFFFFFU);
714                 REG32(address + 4U) = (uint32_t)(data[index] >> 32U);
715                 address += 8U;
716             }
717             /* set START bit to launch fast program operation to flash */
718             FMC_CTL0 |= FMC_CTL0_START;
719 
720             /* wait for the FMC ready */
721             fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT);
722 
723             /* reset the FSTPG bit */
724             FMC_CTL0 &= ~FMC_CTL0_FSTPG;
725         }
726     } else {
727         /* wait for the FMC ready */
728         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
729 
730         if(FMC_READY == fmc_state) {
731             /* set the FSTPG bit to start program */
732             FMC_CTL1 |= FMC_CTL1_FSTPG;
733 
734             /* program the row data */
735             for(index = 0U; index < DOUBLEWORD_CNT_IN_ROW; index++) {
736                 REG32(address) = (uint32_t)(data[index] & 0x00000000FFFFFFFFU);
737                 REG32(address + 4U) = (uint32_t)(data[index] >> 32U);
738                 address += 8U;
739             }
740 
741             /* set START bit to launch fast program operation to flash */
742             FMC_CTL1 |= FMC_CTL1_START;
743 
744             /* wait for the FMC ready */
745             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
746 
747             /* reset the FSTPG bit */
748             FMC_CTL1 &= ~FMC_CTL1_FSTPG;
749         }
750     }
751     if(1U == cache_en) {
752         fmc_cache_enable();
753     }
754     /* return the FMC state */
755     return fmc_state;
756 }
757 
758 /*!
759     \brief      program a double word at the corresponding address in OTP
760     \param[in]  address: address to program
761     \param[in]  data: double word to write
762     \param[out] none
763     \retval     state of FMC, refer to fmc_state_enum
764       \arg        FMC_READY: the operation has been completed
765       \arg        FMC_BUSY: the operation is in progress
766       \arg        FMC_PGSERR:  program sequence error
767       \arg        FMC_PGERR: program error
768       \arg        FMC_PGAERR: program alignment error
769       \arg        FMC_WPERR: erase/program protection error
770       \arg        FMC_TOERR: timeout error
771       \arg        FMC_CBCMDERR: the checked area not blank error
772       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
773 */
otp_doubleword_program(uint32_t address,uint64_t data)774 fmc_state_enum otp_doubleword_program(uint32_t address, uint64_t data)
775 {
776     uint32_t data0, data1;
777     fmc_state_enum fmc_state;
778 
779     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
780     data0 = (uint32_t)(data & 0xFFFFFFFFU);
781     data1 = (uint32_t)((data >> 32U) & 0xFFFFFFFFU);
782 
783     /* configure program width */
784     if(FMC_READY == fmc_state) {
785         /* set the PG bit to start program */
786         FMC_CTL1 |= FMC_CTL1_PG;
787         REG32(address) = data0;
788         REG32(address + 4U) = data1;
789         /* wait for the FMC ready */
790         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
791 
792         /* reset the PG bit */
793         FMC_CTL1 &= ~FMC_CTL1_PG;
794     }
795     /* return the FMC state */
796     return fmc_state;
797 }
798 
799 /*!
800     \brief      program a word at the corresponding address in EEPROM
801     \param[in]  address: address to program
802     \param[in]  data: word to write
803     \param[out] none
804     \retval     state of FMC, refer to fmc_state_enum
805       \arg        FMC_READY: the operation has been completed
806       \arg        FMC_BUSY: the operation is in progress
807       \arg        FMC_PGSERR:  program sequence error
808       \arg        FMC_PGERR: program error
809       \arg        FMC_PGAERR: program alignment error
810       \arg        FMC_WPERR: erase/program protection error
811       \arg        FMC_TOERR: timeout error
812       \arg        FMC_CBCMDERR: the checked area not blank error
813       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
814 */
eeprom_word_program(uint32_t address,uint32_t data)815 fmc_state_enum eeprom_word_program(uint32_t address, uint32_t data)
816 {
817     fmc_sram_mode_enum sram_mode;
818     fmc_state_enum fmc_state;
819 
820     /* get shared SRAM mode */
821     sram_mode = fmc_sram_mode_get();
822 
823     /* set Shared SRAM to EEPROM RAM mode */
824     if(EEPROM_SRAM_MODE != sram_mode) {
825         fmc_sram_mode_config(EEPROM_SRAM_MODE);
826     }
827 
828     /* wait for the FMC ready */
829     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
830 
831     /* configure program width */
832     if(FMC_READY == fmc_state) {
833         REG32(address) = data;
834 
835         /* wait for the FMC ready */
836         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
837     }
838 
839     /* return the FMC state */
840     return fmc_state;
841 }
842 
843 /*!
844     \brief      read a word at the corresponding address in EEPROM
845     \param[in]  address: address to read
846     \param[in]  none
847     \param[out] none
848     \retval     word data readout
849 */
eeprom_word_read(uint32_t address)850 uint32_t eeprom_word_read(uint32_t address)
851 {
852     uint32_t data;
853     fmc_sram_mode_enum sram_mode;
854 
855     /* get shared SRAM mode */
856     sram_mode = fmc_sram_mode_get();
857 
858     /* set shared SRAM to EEPROM RAM mode */
859     if(EEPROM_SRAM_MODE != sram_mode) {
860         fmc_sram_mode_config(EEPROM_SRAM_MODE);
861     }
862 
863     data = REG32(address);
864 
865     /* return data */
866     return data;
867 }
868 
869 /*!
870     \brief      unlock the option bytes 0 operation
871                 it is better to used in pairs with ob_lock
872     \param[in]  none
873     \param[out] none
874     \retval     none
875 */
ob_unlock(void)876 void ob_unlock(void)
877 {
878     if(0U == (FMC_CTL1 & FMC_CTL1_OBWEN)) {
879         /* write the FMC key */
880         FMC_OBKEY = UNLOCK_KEY0;
881         FMC_OBKEY = UNLOCK_KEY1;
882     }
883 
884     /* wait until OBWEN bit is set by hardware */
885     while(0U == (FMC_CTL1 & FMC_CTL1_OBWEN)) {
886     }
887 }
888 
889 /*!
890     \brief      lock the option bytes 0 operation
891                 it is better to used in pairs with ob_unlock after an operation
892     \param[in]  none
893     \param[out] none
894     \retval     none
895 */
ob_lock(void)896 void ob_lock(void)
897 {
898     /* reset the OBWEN bit */
899     FMC_CTL1 &= ~FMC_CTL1_OBWEN;
900 }
901 
902 /*!
903     \brief      force to reload the option bytes 0
904     \param[in]  none
905     \param[out] none
906     \retval     none
907 */
ob_reset(void)908 void ob_reset(void)
909 {
910     /* set the OBRLD bit */
911     FMC_CTL1 |= FMC_CTL1_OBRLD;
912 }
913 
914 /*!
915     \brief      erase the option bytes 0
916                 programmer must ensure FMC & option bytes are both unlocked before calling this function
917     \param[in]  none
918     \param[out] none
919     \retval     state of FMC, refer to fmc_state_enum
920       \arg        FMC_READY: the operation has been completed
921       \arg        FMC_BUSY: the operation is in progress
922       \arg        FMC_PGSERR:  program sequence error
923       \arg        FMC_PGERR: program error
924       \arg        FMC_PGAERR: program alignment error
925       \arg        FMC_WPERR: erase/program protection error
926       \arg        FMC_TOERR: timeout error
927       \arg        FMC_CBCMDERR: the checked area not blank error
928       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
929       \arg        FMC_OB_HSPC: FMC is under high security protection
930 */
ob_erase(void)931 fmc_state_enum ob_erase(void)
932 {
933     uint32_t temp_spc_user;
934     fmc_state_enum fmc_state;
935 
936     temp_spc_user = OB_SPC_USER;
937 
938     /* check the option bytes security protection value */
939     if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) {
940         return FMC_OB_HSPC;
941     }
942 
943     /* wait for the FMC ready */
944     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
945 
946     if(FMC_READY == fmc_state) {
947         /* start erase the option bytes */
948         FMC_CTL1 |= FMC_CTL1_OB0ER;
949         FMC_CTL1 |= FMC_CTL1_START;
950 
951         /* wait for the FMC ready */
952         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
953 
954         if(FMC_READY == fmc_state) {
955             /* reset the OB0ER bit */
956             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
957 
958             /* set the OB0PG bit */
959             FMC_CTL1 |= FMC_CTL1_OB0PG;
960 
961             /* restore the previous security protection configuration */
962             OB_SPC_USER = (temp_spc_user & LOW_8BITS_MASK) | LOW_8BITS_MASK1;
963             OB_DATA = 0xFFFFFFFFU;
964 
965             /* wait for the FMC ready */
966             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
967 
968             /* reset the OB0PG bit */
969             FMC_CTL1 &= ~FMC_CTL1_OB0PG;
970         } else {
971             /* reset the OB0ER bit */
972             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
973         }
974     }
975     /* return the FMC state */
976     return fmc_state;
977 }
978 
979 /*!
980     \brief      enable option bytes 0 write protection
981     \param[in]  wp_area: write protection area
982                 only one parameter can be selected which is shown as below:
983       \arg        BANK0_AREA: main flash bank0 write protection area
984       \arg        BANK1_AREA: main flash bank1 write protection area
985       \arg        DATA_FLASH_AREA: data flash write protection area
986       \arg        EEPROM_AREA: EEPROM write protection area
987     \param[in]  ob_wp: write protection configuration data. Notice that set the bit to 1 if you want to protect
988                 the corresponding pages. The lowest 8 bits is valid in area except bank0.
989     \param[out] none
990     \retval     state of FMC, refer to fmc_state_enum
991       \arg        FMC_READY: the operation has been completed
992       \arg        FMC_BUSY: the operation is in progress
993       \arg        FMC_PGSERR:  program sequence error
994       \arg        FMC_PGERR: program error
995       \arg        FMC_PGAERR: program alignment error
996       \arg        FMC_WPERR: erase/program protection error
997       \arg        FMC_TOERR: timeout error
998       \arg        FMC_CBCMDERR: the checked area not blank error
999       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1000       \arg        FMC_OB_HSPC: FMC is under high security protection
1001 */
ob_write_protection_enable(fmc_area_enum wp_area,uint32_t ob_wp)1002 fmc_state_enum ob_write_protection_enable(fmc_area_enum wp_area, uint32_t ob_wp)
1003 {
1004     uint32_t i;
1005     uint32_t op_byte[OB_WORD_CNT] = {0U};
1006     fmc_state_enum fmc_state;
1007 
1008     /* check the option bytes security protection value */
1009     if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) {
1010         return FMC_OB_HSPC;
1011     }
1012 
1013     /* read option bytes */
1014     for(i = 0U; i < OB_WORD_CNT; i++) {
1015         op_byte[i] = OP_BYTE(i);
1016     }
1017 
1018     ob_wp = (uint32_t)(~ob_wp);
1019     if(BANK0_AREA == wp_area) {
1020         /* configure write protection to main flash bank0 area */
1021         op_byte[2] &= (ob_wp & LOW_8BITS_MASK) | ((ob_wp & HIGH_8BITS_MASK) << 8);
1022         op_byte[3] &= ((ob_wp & LOW_8BITS_MASK1) >> 16) | ((ob_wp & HIGH_8BITS_MASK1) >> 8);
1023     } else if(BANK1_AREA == wp_area) {
1024         /* configure write protection to main flash bank1 area */
1025         op_byte[4] &= (uint32_t)((ob_wp & LOW_8BITS_MASK) | HIGH_16BITS_MASK);
1026     } else if(DATA_FLASH_AREA == wp_area) {
1027         /* configure write protection to data flash area */
1028         op_byte[4] &= (uint32_t)(((ob_wp & LOW_8BITS_MASK) << 16U) | LOW_16BITS_MASK);
1029     } else if(EEPROM_AREA == wp_area) {
1030         /* configure write protection to EEPROM area */
1031         op_byte[5] &= (uint32_t)(ob_wp & LOW_8BITS_MASK);
1032     } else {
1033         /* illegal parameters */
1034     }
1035 
1036     /* wait for the FMC ready */
1037     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1038 
1039     if(FMC_READY == fmc_state) {
1040         /* start erase the option bytes */
1041         FMC_CTL1 |= FMC_CTL1_OB0ER;
1042         FMC_CTL1 |= FMC_CTL1_START;
1043 
1044         /* wait for the FMC ready */
1045         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1046 
1047         if(FMC_READY == fmc_state) {
1048             /* reset the OB0ER bit */
1049             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1050 
1051             /* enable the option bytes programming */
1052             FMC_CTL1 |= FMC_CTL1_OB0PG;
1053 
1054             /* write option bytes */
1055             for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) {
1056                 OP_BYTE(i * 2U) = op_byte[i * 2U];
1057                 OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U];
1058                 fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1059                 if(FMC_READY != fmc_state) {
1060                     break;
1061                 }
1062             }
1063             /* wait for the FMC ready */
1064             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1065 
1066             /* reset the OB0PG bit */
1067             FMC_CTL1 &= ~FMC_CTL1_OB0PG;
1068         } else {
1069             /* reset the OB0ER bit */
1070             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1071         }
1072     }
1073 
1074     /* return the FMC state */
1075     return fmc_state;
1076 }
1077 
1078 /*!
1079     \brief      configure security protection
1080     \param[in]  ob_spc: specify security protection code
1081                 only one parameter can be selected which is shown as below:
1082       \arg        FMC_NSPC: no security protection
1083       \arg        FMC_LSPC: low security protection
1084       \arg        FMC_HSPC: high security protection
1085     \param[out] none
1086     \retval     state of FMC, refer to fmc_state_enum
1087       \arg        FMC_READY: the operation has been completed
1088       \arg        FMC_BUSY: the operation is in progress
1089       \arg        FMC_PGSERR:  program sequence error
1090       \arg        FMC_PGERR: program error
1091       \arg        FMC_PGAERR: program alignment error
1092       \arg        FMC_WPERR: erase/program protection error
1093       \arg        FMC_TOERR: timeout error
1094       \arg        FMC_CBCMDERR: the checked area not blank error
1095       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1096       \arg        FMC_OB_HSPC: FMC is under high security protection
1097 */
ob_security_protection_config(uint16_t ob_spc)1098 fmc_state_enum ob_security_protection_config(uint16_t ob_spc)
1099 {
1100     uint32_t i;
1101     uint32_t op_byte[OB_WORD_CNT] = {0U};
1102     fmc_state_enum fmc_state;
1103 
1104     /* check the option bytes security protection value */
1105     if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) {
1106         return FMC_OB_HSPC;
1107     }
1108     /* read option bytes */
1109     for(i = 0U; i < OB_WORD_CNT; i++) {
1110         op_byte[i] = OP_BYTE(i);
1111     }
1112 
1113     op_byte[0] = ((uint32_t)(ob_spc)) | ((op_byte[0] & HIGH_16BITS_MASK));
1114 
1115     /* wait for the FMC ready */
1116     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1117 
1118     if(FMC_READY == fmc_state) {
1119         /* start erase the option bytes */
1120         FMC_CTL1 |= FMC_CTL1_OB0ER;
1121         FMC_CTL1 |= FMC_CTL1_START;
1122 
1123         /* wait for the FMC ready */
1124         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1125 
1126         if(FMC_READY == fmc_state) {
1127 
1128             /* reset the OB0ER bit */
1129             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1130 
1131             /* enable the option bytes programming */
1132             FMC_CTL1 |= FMC_CTL1_OB0PG;
1133 
1134             /* write option bytes */
1135             for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) {
1136                 OP_BYTE(i * 2U) = op_byte[i * 2U];
1137                 OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U];
1138                 fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1139                 if(FMC_READY != fmc_state) {
1140                     break;
1141                 }
1142             }
1143 
1144             /* wait for the FMC ready */
1145             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1146 
1147             /* reset the OB0PG bit */
1148             FMC_CTL1 &= ~FMC_CTL1_OB0PG;
1149         } else {
1150             /* reset the OB0ER bit */
1151             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1152         }
1153     }
1154 
1155     /* return the FMC state */
1156     return fmc_state;
1157 }
1158 
1159 /*!
1160     \brief      program the FMC user option bytes 0
1161                 programmer must ensure FMC & option bytes are both unlocked before calling this function
1162                 this function can only clear the corresponding bits to be 0 rather than 1.
1163                 the function ob_erase is used to set all the bits to be 1.
1164     \param[in]  ob_user: user option bytes
1165                 one or more (bitwise OR) parameters can be selected which are shown as below:
1166       \arg        OB_FWDGT_HW/OB_FWDGT_SW: free watchdog mode
1167       \arg        OB_DEEPSLEEP_RST/OB_DEEPSLEEP_NRST: generate a reset or enter deep-sleep mode
1168       \arg        OB_STDBY_RST/OB_STDBY_NRST: generate a reset or enter standby mode
1169       \arg        OB_BOOT_FROM_BANK1/OB_BOOT_FROM_BANK0: boot mdoe
1170       \arg        OB_BOOT_OTA_ENABLE/OB_BOOT_OTA_DISABLE: OTA mdoe
1171       \arg        OB_BOR_DISABLE/OB_BOR_ENABLE: BOR on/off
1172     \param[out] none
1173     \retval     state of FMC, refer to fmc_state_enum
1174       \arg        FMC_READY: the operation has been completed
1175       \arg        FMC_BUSY: the operation is in progress
1176       \arg        FMC_PGSERR:  program sequence error
1177       \arg        FMC_PGERR: program error
1178       \arg        FMC_PGAERR: program alignment error
1179       \arg        FMC_WPERR: erase/program protection error
1180       \arg        FMC_TOERR: timeout error
1181       \arg        FMC_CBCMDERR: the checked area not blank error
1182       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1183       \arg        FMC_OB_HSPC: FMC is under high security protection
1184 */
ob_user_write(uint16_t ob_user)1185 fmc_state_enum ob_user_write(uint16_t ob_user)
1186 {
1187     uint32_t i;
1188     uint32_t op_byte[OB_WORD_CNT] = {0U};
1189     uint8_t ob_user_0, ob_user_1, ob_user_temp;
1190 
1191     /* check the option bytes security protection value */
1192     if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) {
1193         return FMC_OB_HSPC;
1194     }
1195 
1196     ob_user_0 = (uint8_t)(ob_user >> 8U);
1197     ob_user_1 = (uint8_t)(ob_user & 0xFFU);
1198 
1199     /* read option bytes */
1200     for(i = 0U; i < OB_WORD_CNT; i++) {
1201         op_byte[i] = OP_BYTE(i);
1202     }
1203 
1204     ob_user_temp = (uint8_t)(op_byte[0] >> 16U);
1205     ob_user_temp |= ob_user_1;
1206     ob_user_temp &= (uint8_t)(~ob_user_0);
1207 
1208     op_byte[0] = ((uint32_t)ob_user_temp << 16U) | ((op_byte[0] & LOW_16BITS_MASK));
1209 
1210     /* check whether FMC is ready or not */
1211     fmc_state_enum fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1212 
1213     if(FMC_READY == fmc_state) {
1214         /* start erase the option bytes */
1215         FMC_CTL1 |= FMC_CTL1_OB0ER;
1216         FMC_CTL1 |= FMC_CTL1_START;
1217 
1218         /* wait for the FMC ready */
1219         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1220 
1221         if(FMC_READY == fmc_state) {
1222 
1223             /* reset the OB0ER bit */
1224             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1225 
1226             /* enable the option bytes programming */
1227             FMC_CTL1 |= FMC_CTL1_OB0PG;
1228 
1229             /* write option bytes */
1230             for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) {
1231                 OP_BYTE(i * 2U) = op_byte[i * 2U];
1232                 OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U];
1233                 fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1234                 if(FMC_READY != fmc_state) {
1235                     break;
1236                 }
1237             }
1238 
1239             /* wait for the FMC ready */
1240             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1241 
1242             /* reset the OB0PG bit */
1243             FMC_CTL1 &= ~FMC_CTL1_OB0PG;
1244         } else {
1245             /* reset the OB0ER bit */
1246             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1247         }
1248     }
1249     /* return the FMC state */
1250     return fmc_state;
1251 }
1252 
1253 /*!
1254     \brief      program the FMC data option bytes 0
1255                 programmer must ensure FMC & option bytes are both unlocked before calling this function
1256     \param[in]  ob_data: the data to be programmed, OB_DATA[0:15]
1257     \param[out] none
1258     \retval     state of FMC, refer to fmc_state_enum
1259       \arg        FMC_READY: the operation has been completed
1260       \arg        FMC_BUSY: the operation is in progress
1261       \arg        FMC_PGSERR:  program sequence error
1262       \arg        FMC_PGERR: program error
1263       \arg        FMC_PGAERR: program alignment error
1264       \arg        FMC_WPERR: erase/program protection error
1265       \arg        FMC_TOERR: timeout error
1266       \arg        FMC_CBCMDERR: the checked area not blank error
1267       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1268       \arg        FMC_OB_HSPC: FMC is under high security protection
1269 */
ob_data_program(uint16_t ob_data)1270 fmc_state_enum ob_data_program(uint16_t ob_data)
1271 {
1272     uint32_t i;
1273     uint32_t val;
1274     uint32_t op_byte[OB_WORD_CNT] = {0U};
1275     fmc_state_enum fmc_state = FMC_READY;
1276 
1277     val = OB_SPC;
1278     /* check the option bytes security protection value */
1279     if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) {
1280         return FMC_OB_HSPC;
1281     }
1282 
1283     /* read option bytes */
1284     for(i = 0U; i < OB_WORD_CNT; i++) {
1285         op_byte[i] = OP_BYTE(i);
1286     }
1287 
1288     val = (uint32_t)(ob_data & LOW_8BITS_MASK);
1289     val |= ((uint32_t)ob_data & HIGH_8BITS_MASK) << 8U;
1290     op_byte[1] = val;
1291     /* wait for the FMC ready */
1292     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1293 
1294     if(FMC_READY == fmc_state) {
1295         /* start erase the option bytes */
1296         FMC_CTL1 |= FMC_CTL1_OB0ER;
1297         FMC_CTL1 |= FMC_CTL1_START;
1298 
1299         /* wait for the FMC ready */
1300         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1301 
1302         if(FMC_READY == fmc_state) {
1303             /* reset the OB0ER bit */
1304             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1305             /* set the OB0PG bit */
1306             FMC_CTL1 |= FMC_CTL1_OB0PG;
1307 
1308             /* write option bytes */
1309             for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) {
1310                 OP_BYTE(i * 2U) = op_byte[i * 2U];
1311                 OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U];
1312                 fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1313                 if(FMC_READY != fmc_state) {
1314                     break;
1315                 }
1316             }
1317             /* wait for the FMC ready */
1318             fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1319 
1320             /* reset the OB0PG bit */
1321             FMC_CTL1 &= ~FMC_CTL1_OB0PG;
1322         } else {
1323             /* reset the OB0ER bit */
1324             FMC_CTL1 &= ~FMC_CTL1_OB0ER;
1325         }
1326     }
1327 
1328     /* return the FMC state */
1329     return fmc_state;
1330 }
1331 
1332 /*!
1333     \brief      get the value of FMC option bytes OB_USER in FMC_OBSTAT register
1334     \param[in]  none
1335     \param[out] none
1336     \retval     the option bytes USER value
1337 */
ob_user_get(void)1338 uint8_t ob_user_get(void)
1339 {
1340     return (uint8_t)((FMC_OBSTAT & FMC_OBSTAT_USER) >> OBSTAT_USER_OFFSET);
1341 }
1342 
1343 /*!
1344     \brief      get the value of FMC option bytes OB_DATA in FMC_OBSTAT register
1345     \param[in]  none
1346     \param[out] none
1347     \retval     the option bytes DATA value
1348 */
ob_data_get(void)1349 uint16_t ob_data_get(void)
1350 {
1351     return (uint16_t)((FMC_OBSTAT & FMC_OBSTAT_DATA) >> OBSTAT_DATA_OFFSET);
1352 }
1353 
1354 /*!
1355     \brief      get the value of FMC option bytes BK0WP in FMC_WP0 register
1356     \param[in]  none
1357     \param[out] none
1358     \retval     the option bytes BK0WP value
1359 */
ob_write_protection_get(void)1360 uint32_t ob_write_protection_get(void)
1361 {
1362     return (uint32_t)(FMC_WP0);
1363 }
1364 
1365 /*!
1366     \brief      get the value of FMC option bytes BK1WP in FMC_WP1 register
1367     \param[in]  none
1368     \param[out] none
1369     \retval     the option bytes BK1WP value
1370 */
ob_bk1_write_protection_get(void)1371 uint8_t ob_bk1_write_protection_get(void)
1372 {
1373     return (uint8_t)((FMC_WP1 & FMC_WP1_BK1WP) >> WP1_BK1WP_OFFSET);
1374 }
1375 
1376 /*!
1377     \brief      get the value of FMC option bytes DFWP in FMC_WP1 register
1378     \param[in]  none
1379     \param[out] none
1380     \retval     the option bytes DFWP value
1381 */
ob_df_write_protection_get(void)1382 uint8_t ob_df_write_protection_get(void)
1383 {
1384     return (uint8_t)((FMC_WP1 & FMC_WP1_DFWP) >> WP1_DFWP_OFFSET);
1385 }
1386 
1387 /*!
1388     \brief      get the value of FMC option bytes EPWP in FMC_WP1 register
1389     \param[in]  none
1390     \param[out] none
1391     \retval     the option bytes EPWP value
1392 */
ob_ep_write_protection_get(void)1393 uint8_t ob_ep_write_protection_get(void)
1394 {
1395     return (uint8_t)((FMC_WP1 & FMC_WP1_EPWP) >> WP1_EPWP_OFFSET);
1396 }
1397 
1398 /*!
1399     \brief      get the value of FMC option bytes 0 security protection level (PLEVEL) in FMC_OBSTAT register
1400     \param[in]  none
1401     \param[out] none
1402     \retval     the value of PLEVEL
1403       \arg        OB_OBSTAT_PLEVEL_NO: no security protection
1404       \arg        OB_OBSTAT_PLEVEL_LOW: low security protection
1405       \arg        OB_OBSTAT_PLEVEL_HIGH: high security protection
1406 */
ob_plevel_get(void)1407 uint8_t ob_plevel_get(void)
1408 {
1409     return (uint8_t)((FMC_OBSTAT & FMC_OBSTAT_PLEVEL) >> OBSTAT_PLEVEL_OFFSET);
1410 }
1411 
1412 /*!
1413     \brief      configure lock value in option bytes 1
1414                 programmer must ensure FMC & option bytes are both unlocked before calling this function
1415     \param[in]  lk_value: the LK value to be programmed (OB1_LK_VALUE)
1416                 only one parameter can be selected which is shown as below:
1417       \arg        OB1CS_OB1_LK: when configured as OB1CS_OB1_LK, the option bytes 1 cannot be modified any more
1418       \arg        OB1CS_OB1_NOT_LK: option bytes 1 is not locked
1419     \param[out] none
1420     \retval     state of FMC, refer to fmc_state_enum
1421       \arg        FMC_READY: the operation has been completed
1422       \arg        FMC_BUSY: the operation is in progress
1423       \arg        FMC_PGSERR:  program sequence error
1424       \arg        FMC_PGERR: program error
1425       \arg        FMC_PGAERR: program alignment error
1426       \arg        FMC_WPERR: erase/program protection error
1427       \arg        FMC_TOERR: timeout error
1428       \arg        FMC_CBCMDERR: the checked area not blank error
1429       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1430       \arg        FMC_OB1_LK: option bytes 1 is locked
1431 */
ob1_lock_config(uint32_t lk_value)1432 fmc_state_enum ob1_lock_config(uint32_t lk_value)
1433 {
1434     uint32_t reg;
1435 
1436     /* check the option bytes 1 lock status */
1437     if(0U != (FMC_OB1CS & FMC_OB1CS_OB1LK)) {
1438         return FMC_OB1_LK;
1439     }
1440 
1441     reg = FMC_OB1CS;
1442     reg &= ~FMC_OB1CS_LKVAL;
1443     reg |= lk_value;
1444 
1445     /* wait for the FMC ready */
1446     fmc_state_enum fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1447 
1448     if(FMC_READY == fmc_state) {
1449         /* write the value to LKVAL in FMC_OB1CS register */
1450         FMC_OB1CS = reg;
1451 
1452         /* set the OB1START bit */
1453         FMC_OB1CS |= FMC_OB1CS_OB1START;
1454 
1455         /* wait for the FMC ready */
1456         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1457     }
1458 
1459     /* return the FMC state */
1460     return fmc_state;
1461 }
1462 
1463 /*!
1464     \brief      configure the EPLOAD value of option bytes 1 loaded after the system reset
1465                 programmer must ensure FMC & option bytes are both unlocked before calling this function
1466     \param[in]  epload: EPLOAD value to be programmed
1467                 only one parameter can be selected which is shown as below:
1468       \arg        OB1CS_EPLOAD_NOT_LOAD_EPDATA: shared SRAM is not loaded with valid EEPROM data during FMC reset
1469       \arg        OB1CS_EPLOAD_LOAD_EPDATA: shared SRAM is loaded with valid EEPROM data during FMC reset
1470     \param[out] none
1471     \retval     state of FMC, refer to fmc_state_enum
1472       \arg        FMC_READY: the operation has been completed
1473       \arg        FMC_BUSY: the operation is in progress
1474       \arg        FMC_PGSERR:  program sequence error
1475       \arg        FMC_PGERR: program error
1476       \arg        FMC_PGAERR: program alignment error
1477       \arg        FMC_WPERR: erase/program protection error
1478       \arg        FMC_TOERR: timeout error
1479       \arg        FMC_CBCMDERR: the checked area not blank error
1480       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1481       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1482       \arg        FMC_OB1_LK: option bytes 1 is locked
1483 */
ob1_epload_config(uint32_t epload)1484 fmc_state_enum ob1_epload_config(uint32_t epload)
1485 {
1486     uint32_t reg;
1487     fmc_state_enum fmc_state = FMC_READY;
1488 
1489     /* check the option bytes 1 lock status */
1490     if(0U != (FMC_OB1CS & FMC_OB1CS_OB1LK)) {
1491         return FMC_OB1_LK;
1492     }
1493 
1494     reg = FMC_OB1CS;
1495     reg &= ~FMC_OB1CS_EPLOAD;
1496     reg |= epload;
1497 
1498     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1499 
1500     if(FMC_READY == fmc_state) {
1501         /* write the value to EPLOAD in FMC_OB1CS register */
1502         FMC_OB1CS = reg;
1503 
1504         /* set the OB1START bit */
1505         FMC_OB1CS |= FMC_OB1CS_OB1START;
1506 
1507         /* wait for the FMC ready */
1508         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1509         /* reset the OB1START bit */
1510         FMC_OB1CS &= ~FMC_OB1CS_OB1START;
1511     }
1512 
1513     /* return the FMC state */
1514     return fmc_state;
1515 }
1516 
1517 /*!
1518     \brief      configure option bytes 1 EEPROM parameters
1519                 programmer must ensure FMC & option bytes are both unlocked before calling this function
1520     \param[in]  efalc: EFALC value to be programmed
1521                 only one parameter can be selected which is shown as below:
1522       \arg        OB1CS_DF_64K_EF_0K: data flash size is 64KB, EEPROM backup size is 0KB
1523       \arg        OB1CS_DF_48K_EF_16K: data flash size is 48KB, EEPROM backup size is 16KB
1524       \arg        OB1CS_DF_32K_EF_32K: data flash size is 32KB, EEPROM backup size is 32KB
1525       \arg        OB1CS_DF_16K_EF_48K: data flash size is 16KB, EEPROM backup size is 48KB
1526       \arg        OB1CS_DF_0K_EF_64K: data flash size is 0KB, EEPROM backup size is 64KB
1527       \arg        OB1CS_DF_EF_INVALID: data flash and EEPROM backup are invalid
1528       \arg        OB1CS_DF_32K_EF_0K: data flash size is 32KB, EEPROM backup size is 0KB
1529       \arg        OB1CS_DF_8K_EF_24K: data flash size is 8KB, EEPROM backup size is 24KB
1530       \arg        OB1CS_DF_0K_EF_32K: data flash size is 0KB, EEPROM backup size is 32KB
1531       \arg        OB1CS_DF_16K_EF_16K: data flash size is 16KB, EEPROM backup size is 16KB
1532       \arg        OB1CS_DF_24K_EF_8K: data flash size is 24KB, EEPROM backup size is 8KB
1533       \arg        OB1CS_DF_16K_EF_0K: data flash size is 16KB, EEPROM backup size is 0KB
1534       \arg        OB1CS_DF_4K_EF_12K: data flash size is 4KB, EEPROM backup size is 12KB
1535       \arg        OB1CS_DF_0K_EF_16K: data flash size is 0KB, EEPROM backup size is 16KB
1536       \arg        OB1CS_DF_8K_EF_8K: data flash size is 8KB, EEPROM backup size is 8KB
1537       \arg        OB1CS_DF_12K_EF_4K: data flash size is 12KB, EEPROM backup size is 4KB
1538     \param[in]  epsize: EPSIZE value to be programmed
1539                 only one parameter can be selected which is shown as below:
1540       \arg        OB1CS_EPSIZE_NONE: no EEPROM
1541       \arg        OB1CS_EPSIZE_4K: 4KB EEPROM
1542       \arg        OB1CS_EPSIZE_2K: 2KB EEPROM
1543       \arg        OB1CS_EPSIZE_1K: 1KB EEPROM
1544     \param[out] none
1545     \retval     state of FMC, refer to fmc_state_enum
1546       \arg        FMC_READY: the operation has been completed
1547       \arg        FMC_BUSY: the operation is in progress
1548       \arg        FMC_PGSERR:  program sequence error
1549       \arg        FMC_PGERR: program error
1550       \arg        FMC_PGAERR: program alignment error
1551       \arg        FMC_WPERR: erase/program protection error
1552       \arg        FMC_TOERR: timeout error
1553       \arg        FMC_CBCMDERR: the checked area not blank error
1554       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1555       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
1556       \arg        FMC_OB1_LK: option bytes 1 is locked
1557 */
ob1_eeprom_parameter_config(uint32_t efalc,uint32_t epsize)1558 fmc_state_enum ob1_eeprom_parameter_config(uint32_t efalc, uint32_t epsize)
1559 {
1560     uint32_t reg;
1561     fmc_state_enum fmc_state;
1562 
1563     /* check the option bytes security protection value */
1564     if(0U != (FMC_OB1CS & FMC_OB1CS_OB1LK)) {
1565         return FMC_OB1_LK;
1566     }
1567     /* configure the EFALC and EPSIZE */
1568     reg = FMC_OB1CS;
1569     reg &= ~FMC_OB1CS_EFALC;
1570     reg |= efalc;
1571     reg &= ~FMC_OB1CS_EPSIZE;
1572     reg |= epsize;
1573 
1574     /* wait for the FMC ready */
1575     fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1576 
1577     if(FMC_READY == fmc_state) {
1578         /* write the value to EPSIZE and EFALC in FMC_OB1CS register */
1579         FMC_OB1CS = reg;
1580 
1581         /* set the OB1START bit */
1582         FMC_OB1CS |= FMC_OB1CS_OB1START;
1583 
1584         /* wait for the FMC ready */
1585         fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT);
1586         /* reset the OB1START bit */
1587         FMC_OB1CS &= ~FMC_OB1CS_OB1START;
1588     }
1589 
1590     /* return the FMC state */
1591     return fmc_state;
1592 }
1593 
1594 /*!
1595     \brief      get data flash size in byte unit
1596     \param[in]  none
1597     \param[out] none
1598     \retval     data flash byte count
1599 */
dflash_size_get(void)1600 uint32_t dflash_size_get(void)
1601 {
1602     uint32_t efalc_value;
1603     uint32_t dflash_size = 0U;
1604 
1605     /* get EFALC value in option bytes 1 */
1606     efalc_value = FMC_OB1CS & FMC_OB1CS_EFALC;
1607 
1608     switch(efalc_value) {
1609     case OB1CS_DF_64K_EF_0K:
1610         dflash_size = 64U * 0x400U;
1611         break;
1612     case OB1CS_DF_48K_EF_16K:
1613         dflash_size = 48U * 0x400U;
1614         break;
1615     case OB1CS_DF_32K_EF_32K:
1616         dflash_size = 32U * 0x400U;
1617         break;
1618     case OB1CS_DF_16K_EF_48K:
1619         dflash_size = 16U * 0x400U;
1620         break;
1621     case OB1CS_DF_0K_EF_64K:
1622         dflash_size = 0x00000000U;
1623         break;
1624     case OB1CS_DF_EF_INVALID:
1625         dflash_size = 0x00000000U;
1626         break;
1627     case OB1CS_DF_32K_EF_0K:
1628         dflash_size = 32U * 0x400U;
1629         break;
1630     case OB1CS_DF_8K_EF_24K:
1631         dflash_size = 8U * 0x400U;
1632         break;
1633     case OB1CS_DF_0K_EF_32K:
1634         dflash_size = 0x00000000U;
1635         break;
1636     case OB1CS_DF_16K_EF_16K:
1637         dflash_size = 16U * 0x400U;
1638         break;
1639     case OB1CS_DF_24K_EF_8K:
1640         dflash_size = 24U * 0x400U;
1641         break;
1642     case OB1CS_DF_16K_EF_0K:
1643         dflash_size = 16U * 0x400U;
1644         break;
1645     case OB1CS_DF_4K_EF_12K:
1646         dflash_size = 4U * 0x400U;
1647         break;
1648     case OB1CS_DF_0K_EF_16K:
1649         dflash_size = 0x00000000U;
1650         break;
1651     case OB1CS_DF_8K_EF_8K:
1652         dflash_size = 8U * 0x400U;
1653         break;
1654     case OB1CS_DF_12K_EF_4K:
1655         dflash_size = 12U * 0x400U;
1656         break;
1657     default:
1658         break;
1659     }
1660 
1661     return dflash_size;
1662 }
1663 
1664 /*!
1665     \brief      get EEPROM backup size in byte unit
1666     \param[in]  none
1667     \param[out] none
1668     \retval     EEPROM backup byte count
1669 */
eeprom_backup_size_get(void)1670 uint32_t eeprom_backup_size_get(void)
1671 {
1672     uint32_t efalc_value;
1673     uint32_t eeprom_backup_size = 0U;
1674 
1675     /* get EFALC value in option bytes 1 */
1676     efalc_value = FMC_OB1CS & FMC_OB1CS_EFALC;
1677 
1678     switch(efalc_value) {
1679     case OB1CS_DF_64K_EF_0K:
1680         eeprom_backup_size = 0x00000000U;
1681         break;
1682     case OB1CS_DF_48K_EF_16K:
1683         eeprom_backup_size = 16U * 0x400U;
1684         break;
1685     case OB1CS_DF_32K_EF_32K:
1686         eeprom_backup_size = 32U * 0x400U;
1687         break;
1688     case OB1CS_DF_16K_EF_48K:
1689         eeprom_backup_size = 48U * 0x400U;
1690         break;
1691     case OB1CS_DF_0K_EF_64K:
1692         eeprom_backup_size = 64U * 0x400U;
1693         break;
1694     case OB1CS_DF_EF_INVALID:
1695         eeprom_backup_size = 0x00000000U;
1696         break;
1697     case OB1CS_DF_32K_EF_0K:
1698         eeprom_backup_size = 0x00000000U;
1699         break;
1700     case OB1CS_DF_8K_EF_24K:
1701         eeprom_backup_size = 24U * 0x400U;
1702         break;
1703     case OB1CS_DF_0K_EF_32K:
1704         eeprom_backup_size = 0x00000000U;
1705         break;
1706     case OB1CS_DF_16K_EF_16K:
1707         eeprom_backup_size = 16U * 0x400U;
1708         break;
1709     case OB1CS_DF_24K_EF_8K:
1710         eeprom_backup_size = 8U * 0x400U;
1711         break;
1712     case OB1CS_DF_16K_EF_0K:
1713         eeprom_backup_size = 0x00000000U;
1714         break;
1715     case OB1CS_DF_4K_EF_12K:
1716         eeprom_backup_size = 12U * 0x400U;
1717         break;
1718     case OB1CS_DF_0K_EF_16K:
1719         eeprom_backup_size = 16U * 0x400U;
1720         break;
1721     case OB1CS_DF_8K_EF_8K:
1722         eeprom_backup_size = 8U * 0x400U;
1723         break;
1724     case OB1CS_DF_12K_EF_4K:
1725         eeprom_backup_size = 4U * 0x400U;
1726         break;
1727     default:
1728         break;
1729     }
1730 
1731     return eeprom_backup_size;
1732 }
1733 
1734 /*!
1735     \brief      get EEPROM size in byte unit
1736     \param[in]  none
1737     \param[out] none
1738     \retval     EEPROM byte count
1739 */
eeprom_size_get(void)1740 uint32_t eeprom_size_get(void)
1741 {
1742     uint32_t epsize_value;
1743     uint32_t eeprom_size = 0U;
1744 
1745     /* get EPSIZE value in option bytes 1 */
1746     epsize_value = FMC_OB1CS & FMC_OB1CS_EPSIZE;
1747 
1748     switch(epsize_value) {
1749     case OB1CS_EPSIZE_NONE:
1750         eeprom_size = 0x000000000U;
1751         break;
1752     case OB1CS_EPSIZE_4K:
1753         eeprom_size = 4U * 0x400U;
1754         break;
1755     case OB1CS_EPSIZE_2K:
1756         eeprom_size = 2U * 0x400U;
1757         break;
1758     case OB1CS_EPSIZE_1K:
1759         eeprom_size = 0x400U;
1760         break;
1761     default:
1762         break;
1763     }
1764 
1765     return eeprom_size;
1766 }
1767 
1768 /*!
1769     \brief      get FMC flag status
1770     \param[in]  flag: FMC flag
1771                 only one parameter can be selected which is shown as below:
1772       \arg        FMC_BANK0_FLAG_BUSY: flash bank0 busy flag
1773       \arg        FMC_BANK0_FLAG_PGSERR: flash bank0 program sequence error flag
1774       \arg        FMC_BANK0_FLAG_PGERR: flash bank0 program error flag
1775       \arg        FMC_BANK0_FLAG_PGAERR: flash bank0 program alignment error flag
1776       \arg        FMC_BANK0_FLAG_WPERR: flash bank0 erase/program protection error flag
1777       \arg        FMC_BANK0_FLAG_END: flash bank0 end of operation flag
1778       \arg        FMC_BANK0_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not flag
1779       \arg        FMC_BANK0_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program flag
1780       \arg        FMC_BANK1_FLAG_BUSY: flash bank1 busy flag
1781       \arg        FMC_BANK1_FLAG_PGSERR: flash bank1 program sequence error flag
1782       \arg        FMC_BANK1_FLAG_PGERR: flash bank1 program error flag
1783       \arg        FMC_BANK1_FLAG_PGAERR: flash bank1 program alignment error flag
1784       \arg        FMC_BANK1_FLAG_WPERR: flash bank1 erase/program protection error flag
1785       \arg        FMC_BANK1_FLAG_END: flash bank1 end of operation flag
1786       \arg        FMC_BANK1_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not flag
1787       \arg        FMC_BANK1_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program flag
1788       \arg        FMC_FLAG_BK0ECC: an ECC bit error is detected in bank 0 flag
1789       \arg        FMC_FLAG_OB0ECC: an ECC bit error is detected in option byte 0 flag
1790       \arg        FMC_FLAG_BK1ECC: an ECC bit error is detected in bank 1 flag
1791       \arg        FMC_FLAG_SYSECC: an ECC bit error is detected in system memory flag
1792       \arg        FMC_FLAG_DFECC: an ECC bit error is detected in data flash flag
1793       \arg        FMC_FLAG_OTPECC: an ECC bit error is detected in OTP flag
1794       \arg        FMC_FLAG_OB1ECCDET: option bytes 1 two bit error detect flag
1795       \arg        FMC_FLAG_OB0ECCDET: option bytes 0 two bit error detect flag
1796       \arg        FMC_FLAG_EPECCDET: EEPROM two bits error detect flag
1797       \arg        FMC_FLAG_ECCCOR: one bit error detected and correct flag
1798       \arg        FMC_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect flag
1799       \arg        FMC_FLAG_OBERR: option bytes 0 error flag
1800       \arg        FMC_FLAG_OB1ERR: option bytes 1 read error flag
1801     \param[out] none
1802     \retval     FlagStatus: SET or RESET
1803 */
fmc_flag_get(fmc_flag_enum flag)1804 FlagStatus fmc_flag_get(fmc_flag_enum flag)
1805 {
1806     /* check if an ECC bit error is detected in bank 0 */
1807     if(FMC_FLAG_BK0ECC == flag) {
1808         if(0U != (FMC_REG_VAL(flag) & ECCCS_ERROR_MASK)) {
1809             return RESET;
1810         } else {
1811             return SET;
1812         }
1813     } else {
1814         /* get other flag */
1815         if(0U != (FMC_REG_VAL(flag) & BIT(FMC_BIT_POS(flag)))) {
1816             return SET;
1817         } else {
1818             return RESET;
1819         }
1820     }
1821 }
1822 
1823 /*!
1824     \brief      clear FMC flag status
1825     \param[in]  flag: FMC flag
1826                 only one parameter can be selected which is shown as below:
1827       \arg        FMC_BANK0_FLAG_PGSERR: flash bank0 program sequence error flag
1828       \arg        FMC_BANK0_FLAG_PGERR: flash bank0 program error flag
1829       \arg        FMC_BANK0_FLAG_PGAERR: flash bank0 program alignment error flag
1830       \arg        FMC_BANK0_FLAG_WPERR: flash bank0 erase/program protection error flag
1831       \arg        FMC_BANK0_FLAG_END: flash bank0 end of operation flag
1832       \arg        FMC_BANK0_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not flag
1833       \arg        FMC_BANK0_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program flag
1834       \arg        FMC_BANK1_FLAG_PGSERR: flash bank1 program sequence error flag
1835       \arg        FMC_BANK1_FLAG_PGERR: flash bank1 program error flag
1836       \arg        FMC_BANK1_FLAG_PGAERR: flash bank1 program alignment error flag
1837       \arg        FMC_BANK1_FLAG_WPERR: flash bank1 erase/program protection error flag
1838       \arg        FMC_BANK1_FLAG_END: flash bank1 end of operation flag
1839       \arg        FMC_BANK1_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not flag
1840       \arg        FMC_BANK1_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program flag
1841       \arg        FMC_FLAG_OB1ECCDET: option bytes 1 two bit error detect flag
1842       \arg        FMC_FLAG_OB0ECCDET: option bytes 0 two bit error detect flag
1843       \arg        FMC_FLAG_EPECCDET: EEPROM two bits error detect flag
1844       \arg        FMC_FLAG_ECCCOR: one bit error detected and correct flag
1845       \arg        FMC_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect flag
1846     \param[out] none
1847     \retval     FlagStatus: SET or RESET
1848 */
fmc_flag_clear(fmc_flag_enum flag)1849 void fmc_flag_clear(fmc_flag_enum flag)
1850 {
1851     uint32_t reg_offset, reg;
1852 
1853     reg_offset = ((uint32_t)(flag) & 0x0000FFFFU) >> 6U;
1854     /* clear the flags in ECCCS register */
1855     if(ECCCS_REG_OFFSET == reg_offset) {
1856         reg = FMC_REG_VAL(flag);
1857         reg &= ~ECCCS_FLAG_MASK;
1858         reg |= BIT(FMC_BIT_POS(flag));
1859         FMC_REG_VAL(flag) = reg;
1860     } else {
1861         /* clear the flags in STAT0/STAT1 register */
1862         FMC_REG_VAL(flag) = BIT(FMC_BIT_POS(flag));
1863     }
1864 }
1865 
1866 /*!
1867     \brief      enable FMC interrupt
1868     \param[in]  interrupt: the FMC interrupt source
1869                 only one parameter can be selected which is shown as below:
1870       \arg        FMC_BANK0_INT_ERR: FMC bank0 error interrupt
1871       \arg        FMC_BANK0_INT_END: FMC bank0 end of operation interrupt
1872       \arg        FMC_BANK1_INT_ERR: FMC bank1 error interrupt
1873       \arg        FMC_BANK1_INT_END: FMC bank1 end of operation interrupt
1874       \arg        FMC_INT_ECCCOR: FMC one bit error correct interrupt
1875       \arg        FMC_INT_ECCDET: FMC two bits error interrupt
1876     \param[out] none
1877     \retval     none
1878 */
fmc_interrupt_enable(fmc_interrupt_enum interrupt)1879 void fmc_interrupt_enable(fmc_interrupt_enum interrupt)
1880 {
1881     uint32_t reg_offset, reg;
1882 
1883     reg_offset = ((uint32_t)(interrupt) & 0x0000FFFFU) >> 6U;
1884     /* enable interrupt in ECCCS register */
1885     if(ECCCS_REG_OFFSET == reg_offset) {
1886         reg = FMC_REG_VAL(interrupt);
1887         reg &= ~ECCCS_FLAG_MASK;
1888         reg |= BIT(FMC_BIT_POS(interrupt));
1889         FMC_REG_VAL(interrupt) = reg;
1890     } else {
1891         /* enable interrupt in CTL0/CTL1 register */
1892         FMC_REG_VAL(interrupt) |= BIT(FMC_BIT_POS(interrupt));
1893     }
1894 }
1895 
1896 /*!
1897     \brief      disable FMC interrupt
1898     \param[in]  interrupt: the FMC interrupt source
1899                 only one parameter can be selected which is shown as below:
1900       \arg        FMC_BANK0_INT_ERR: FMC bank0 error interrupt
1901       \arg        FMC_BANK0_INT_END: FMC bank0 end of operation interrupt
1902       \arg        FMC_BANK1_INT_ERR: FMC bank1 error interrupt
1903       \arg        FMC_BANK1_INT_END: FMC bank1 end of operation interrupt
1904       \arg        FMC_INT_ECCCOR: FMC one bit error correct interrupt
1905       \arg        FMC_INT_ECCDET: FMC two bits error interrupt
1906     \param[out] none
1907     \retval     none
1908 */
fmc_interrupt_disable(fmc_interrupt_enum interrupt)1909 void fmc_interrupt_disable(fmc_interrupt_enum interrupt)
1910 {
1911     uint32_t reg_offset, reg;
1912 
1913     reg_offset = ((uint32_t)(interrupt) & 0x0000FFFFU) >> 6U;
1914     /* disable interrupt in ECCCS register */
1915     if(ECCCS_REG_OFFSET == reg_offset) {
1916         reg = FMC_REG_VAL(interrupt);
1917         reg &= ~ECCCS_FLAG_MASK;
1918         reg &= ~BIT(FMC_BIT_POS(interrupt));
1919         FMC_REG_VAL(interrupt) = reg;
1920     } else {
1921         /* disable interrupt in CTL0/CTL1 register */
1922         FMC_REG_VAL(interrupt) &= ~BIT(FMC_BIT_POS(interrupt));
1923     }
1924 }
1925 
1926 /*!
1927     \brief      get FMC interrupt flag status
1928     \param[in]  flag: FMC interrupt flag
1929                 only one parameter can be selected which is shown as below:
1930       \arg        FMC_BANK0_INT_FLAG_PGSERR: flash bank0 program sequence error intrrupt flag
1931       \arg        FMC_BANK0_INT_FLAG_PGERR: flash bank0 program error intrrupt flag
1932       \arg        FMC_BANK0_INT_FLAG_PGAERR: flash bank0 program alignment error intrrupt flag
1933       \arg        FMC_BANK0_INT_FLAG_WPERR: flash bank0 erase/program protection error intrrupt flag
1934       \arg        FMC_BANK0_INT_FLAG_END: flash bank0 end of operation intrrupt flag
1935       \arg        FMC_BANK0_INT_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not intrrupt flag
1936       \arg        FMC_BANK0_INT_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program intrrupt flag
1937       \arg        FMC_BANK1_INT_FLAG_PGSERR: flash bank1 program sequence error intrrupt flag
1938       \arg        FMC_BANK1_INT_FLAG_PGERR: flash bank1 program error intrrupt flag
1939       \arg        FMC_BANK1_INT_FLAG_PGAERR: flash bank1 program alignment error intrrupt flag
1940       \arg        FMC_BANK1_INT_FLAG_WPERR: flash bank1 erase/program protection error intrrupt flag
1941       \arg        FMC_BANK1_INT_FLAG_END: flash bank1 end of operation intrrupt flag
1942       \arg        FMC_BANK1_INT_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not intrrupt flag
1943       \arg        FMC_BANK1_INT_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program intrrupt flag
1944       \arg        FMC_INT_FLAG_OB1ECCDET: option bytes 1 two bit error detect intrrupt flag
1945       \arg        FMC_INT_FLAG_OB0ECCDET: option bytes 0 two bit error detect intrrupt flag
1946       \arg        FMC_INT_FLAG_EPECCDET: EEPROM two bits error detect intrrupt flag
1947       \arg        FMC_INT_FLAG_ECCCOR: one bit error detected and correct intrrupt flag
1948       \arg        FMC_INT_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect intrrupt flag
1949     \param[out] none
1950     \retval     FlagStatus: SET or RESET
1951 */
fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag)1952 FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag)
1953 {
1954     uint32_t intenable = 0U, flagstatus = 0U;
1955     /* get the interrupt enable bit status */
1956     intenable = (FMC_REG_VAL(int_flag) & BIT(FMC_BIT_POS(int_flag)));
1957     /* get the corresponding flag bit status */
1958     flagstatus = (FMC_REG_VAL2(int_flag) & BIT(FMC_BIT_POS2(int_flag)));
1959 
1960     if(flagstatus && intenable) {
1961         return SET;
1962     } else {
1963         return RESET;
1964     }
1965 }
1966 
1967 /*!
1968     \brief      clear FMC interrupt flag status
1969     \param[in]  flag: FMC interrupt flag
1970                 only one parameter can be selected which is shown as below:
1971       \arg        FMC_BANK0_INT_FLAG_PGSERR: flash bank0 program sequence error intrrupt flag
1972       \arg        FMC_BANK0_INT_FLAG_PGERR: flash bank0 program error intrrupt flag
1973       \arg        FMC_BANK0_INT_FLAG_PGAERR: flash bank0 program alignment error intrrupt flag
1974       \arg        FMC_BANK0_INT_FLAG_WPERR: flash bank0 erase/program protection error intrrupt flag
1975       \arg        FMC_BANK0_INT_FLAG_END: flash bank0 end of operation intrrupt flag
1976       \arg        FMC_BANK0_INT_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not intrrupt flag
1977       \arg        FMC_BANK0_INT_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program intrrupt flag
1978       \arg        FMC_BANK1_INT_FLAG_PGSERR: flash bank1 program sequence error intrrupt flag
1979       \arg        FMC_BANK1_INT_FLAG_PGERR: flash bank1 program error intrrupt flag
1980       \arg        FMC_BANK1_INT_FLAG_PGAERR: flash bank1 program alignment error intrrupt flag
1981       \arg        FMC_BANK1_INT_FLAG_WPERR: flash bank1 erase/program protection error intrrupt flag
1982       \arg        FMC_BANK1_INT_FLAG_END: flash bank1 end of operation intrrupt flag
1983       \arg        FMC_BANK1_INT_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not intrrupt flag
1984       \arg        FMC_BANK1_INT_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program intrrupt flag
1985       \arg        FMC_INT_FLAG_OB1ECCDET: option bytes 1 two bit error detect intrrupt flag
1986       \arg        FMC_INT_FLAG_OB0ECCDET: option bytes 0 two bit error detect intrrupt flag
1987       \arg        FMC_INT_FLAG_EPECCDET: EEPROM two bits error detect intrrupt flag
1988       \arg        FMC_INT_FLAG_ECCCOR: one bit error detected and correct intrrupt flag
1989       \arg        FMC_INT_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect intrrupt flag
1990     \param[out] none
1991     \retval     FlagStatus: SET or RESET
1992 */
fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag)1993 void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag)
1994 {
1995     uint32_t reg_offset, reg;
1996 
1997     reg_offset = (uint32_t)(int_flag) >> 22U;
1998     /* clear the intrrupt flag in ECCCS register */
1999     if(ECCCS_REG_OFFSET == reg_offset) {
2000         reg = FMC_REG_VAL2(int_flag);
2001         reg &= ~ECCCS_FLAG_MASK;
2002         reg |= BIT(FMC_BIT_POS2(int_flag));
2003         FMC_REG_VAL2(int_flag) = reg;
2004     } else {
2005         /* clear the intrrupt flag in STAT0/STAT1 register */
2006         FMC_REG_VAL2(int_flag) = BIT(FMC_BIT_POS2(int_flag));
2007     }
2008 }
2009 
2010 /*!
2011     \brief      get FMC bank0 state
2012     \param[in]  none
2013     \param[out] none
2014     \retval     state of FMC, refer to fmc_state_enum
2015       \arg        FMC_READY: the operation has been completed
2016       \arg        FMC_BUSY: the operation is in progress
2017       \arg        FMC_PGSERR:  program sequence error
2018       \arg        FMC_PGERR: program error
2019       \arg        FMC_PGAERR: program alignment error
2020       \arg        FMC_WPERR: erase/program protection error
2021       \arg        FMC_CBCMDERR: the checked area not blank error
2022       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
2023 */
fmc_bank0_state_get(void)2024 static fmc_state_enum fmc_bank0_state_get(void)
2025 {
2026     fmc_state_enum fmc_state = FMC_READY;
2027 
2028     if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_BUSY)) {
2029         fmc_state = FMC_BUSY;
2030     } else {
2031         if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_WPERR)) {
2032             fmc_state = FMC_WPERR;
2033         } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_PGERR)) {
2034             fmc_state = FMC_PGERR;
2035         } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_PGSERR)) {
2036             fmc_state = FMC_PGSERR;
2037         } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_PGAERR)) {
2038             fmc_state = FMC_PGAERR;
2039         } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_CBCMDERR)) {
2040             fmc_state = FMC_CBCMDERR;
2041         } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_RSTERR)) {
2042             fmc_state = FMC_RSTERR;
2043         } else {
2044             /* illegal parameters */
2045         }
2046     }
2047 
2048     /* return the FMC state */
2049     return fmc_state;
2050 }
2051 
2052 /*!
2053     \brief      get FMC bank1 state
2054     \param[in]  none
2055     \param[out] none
2056     \retval     state of FMC, refer to fmc_state_enum
2057       \arg        FMC_READY: the operation has been completed
2058       \arg        FMC_BUSY: the operation is in progress
2059       \arg        FMC_PGSERR:  program sequence error
2060       \arg        FMC_PGERR: program error
2061       \arg        FMC_PGAERR: program alignment error
2062       \arg        FMC_WPERR: erase/program protection error
2063       \arg        FMC_CBCMDERR: the checked area not blank error
2064       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
2065 */
fmc_bank1_state_get(void)2066 static fmc_state_enum fmc_bank1_state_get(void)
2067 {
2068     fmc_state_enum fmc_state = FMC_READY;
2069 
2070     if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_BUSY)) {
2071         fmc_state = FMC_BUSY;
2072     } else {
2073         if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_WPERR)) {
2074             fmc_state = FMC_WPERR;
2075         } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_PGERR)) {
2076             fmc_state = FMC_PGERR;
2077         } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_PGSERR)) {
2078             fmc_state = FMC_PGSERR;
2079         } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_PGAERR)) {
2080             fmc_state = FMC_PGAERR;
2081         } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_CBCMDERR)) {
2082             fmc_state = FMC_CBCMDERR;
2083         } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_RSTERR)) {
2084             fmc_state = FMC_RSTERR;
2085         } else {
2086             /* illegal parameters */
2087         }
2088     }
2089     /* return the FMC state */
2090     return fmc_state;
2091 }
2092 
2093 /*!
2094     \brief      check whether FMC bank0 is ready or not
2095     \param[in]  timeout: timeout count
2096     \param[out] none
2097     \retval     state of FMC, refer to fmc_state_enum
2098       \arg        FMC_READY: the operation has been completed
2099       \arg        FMC_BUSY: the operation is in progress
2100       \arg        FMC_PGSERR:  program sequence error
2101       \arg        FMC_PGERR: program error
2102       \arg        FMC_PGAERR: program alignment error
2103       \arg        FMC_WPERR: erase/program protection error
2104       \arg        FMC_TOERR: timeout error
2105       \arg        FMC_CBCMDERR: the checked area not blank error
2106       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
2107 */
fmc_bank0_ready_wait(uint32_t timeout)2108 static fmc_state_enum fmc_bank0_ready_wait(uint32_t timeout)
2109 {
2110     fmc_state_enum fmc_state = FMC_BUSY;
2111 
2112     /* wait for FMC ready */
2113     do {
2114         /* get FMC state */
2115         fmc_state = fmc_bank0_state_get();
2116         timeout--;
2117     } while((FMC_BUSY == fmc_state) && (0U != timeout));
2118 
2119     if(FMC_BUSY == fmc_state) {
2120         fmc_state = FMC_TOERR;
2121     }
2122     /* return the FMC state */
2123     return fmc_state;
2124 }
2125 
2126 /*!
2127     \brief      check whether FMC bank1 is ready or not
2128     \param[in]  timeout: timeout count
2129     \param[out] none
2130     \retval     state of FMC, refer to fmc_state_enum
2131       \arg        FMC_READY: the operation has been completed
2132       \arg        FMC_BUSY: the operation is in progress
2133       \arg        FMC_PGSERR:  program sequence error
2134       \arg        FMC_PGERR: program error
2135       \arg        FMC_PGAERR: program alignment error
2136       \arg        FMC_WPERR: erase/program protection error
2137       \arg        FMC_TOERR: timeout error
2138       \arg        FMC_CBCMDERR: the checked area not blank error
2139       \arg        FMC_RSTERR: BOR/POR or system reset during flash erase/program error
2140 */
fmc_bank1_ready_wait(uint32_t timeout)2141 static fmc_state_enum fmc_bank1_ready_wait(uint32_t timeout)
2142 {
2143     fmc_state_enum fmc_state = FMC_BUSY;
2144 
2145     /* wait for FMC ready */
2146     do {
2147         /* get FMC state */
2148         fmc_state = fmc_bank1_state_get();
2149         timeout--;
2150     } while((FMC_BUSY == fmc_state) && (0U != timeout));
2151 
2152     if(FMC_BUSY == fmc_state) {
2153         fmc_state = FMC_TOERR;
2154     }
2155     /* return the FMC state */
2156     return fmc_state;
2157 }
2158 
2159 /*!
2160     \brief      wait shared SRAM mode to be ready
2161     \param[in]  ready_flag: sram mode ready bit
2162       \arg        FMC_WS_ERAMRDY: EEPROM SRAM ready bit
2163       \arg        FMC_WS_BRAMRDY: basic SRAM ready bit
2164       \arg        FMC_WS_PRAMRDY: fast PG SRAM ready bit
2165     \param[out] none
2166     \retval     none
2167 */
fmc_sram_mode_ready_wait(uint32_t ready_flag)2168 static void fmc_sram_mode_ready_wait(uint32_t ready_flag)
2169 {
2170     while(1) {
2171         if(0U != (FMC_WS & ready_flag)) {
2172             break;
2173         }
2174     }
2175 }
2176