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