1 /*!
2 * @file apm32f10x_fmc.c
3 *
4 * @brief This file provides all the FMC firmware functions
5 *
6 * @version V1.0.4
7 *
8 * @date 2022-12-01
9 *
10 * @attention
11 *
12 * Copyright (C) 2020-2022 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be useful and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 /* Includes */
27 #include "apm32f10x_fmc.h"
28 #include "apm32f10x_rcm.h"
29
30 /** @addtogroup APM32F10x_StdPeriphDriver
31 @{
32 */
33
34 /** @addtogroup FMC_Driver FMC Driver
35 @{
36 */
37
38 /** @defgroup FMC_Functions Functions
39 @{
40 */
41
42 /*!
43 * @brief Configs the code latency value.
44 *
45 * @param latency: the FMC Latency value.
46 *
47 * @retval None
48 */
FMC_ConfigLatency(FMC_LATENCY_T latency)49 void FMC_ConfigLatency(FMC_LATENCY_T latency)
50 {
51 FMC->CTRL1_B.WS = latency;
52 }
53
54 /*!
55 * @brief Enables the Half cycle flash access.
56 *
57 * @param None
58 *
59 * @retval None
60 */
FMC_EnableHalfCycleAccess(void)61 void FMC_EnableHalfCycleAccess(void)
62 {
63 FMC->CTRL1_B.HCAEN = BIT_SET;
64 }
65
66 /*!
67 * @brief Disable the Half cycle flash access.
68 *
69 * @param None
70 *
71 * @retval None
72 */
FMC_DisableHalfCycleAccess(void)73 void FMC_DisableHalfCycleAccess(void)
74 {
75 FMC->CTRL1_B.HCAEN = BIT_RESET;
76 }
77
78 /*!
79 * @brief Enables the Prefetch Buffer.
80 *
81 * @param None
82 *
83 * @retval None
84 */
FMC_EnablePrefetchBuffer(void)85 void FMC_EnablePrefetchBuffer(void)
86 {
87 FMC->CTRL1_B.PBEN = ENABLE;
88 }
89
90 /*!
91 * @brief Disables the Prefetch Buffer.
92 *
93 * @param None
94 *
95 * @retval None
96 */
FMC_DisablePrefetchBuffer(void)97 void FMC_DisablePrefetchBuffer(void)
98 {
99 FMC->CTRL1_B.PBEN = DISABLE;
100 }
101
102 /*!
103 * @brief Unlocks the FMC Program Erase Controller
104 *
105 * @param None
106 *
107 * @retval None
108 */
FMC_Unlock(void)109 void FMC_Unlock(void)
110 {
111 FMC->KEY = 0x45670123;
112 FMC->KEY = 0xCDEF89AB;
113 }
114
115 /*!
116 * @brief Locks the FMC Program Erase Controller.
117 *
118 * @param None
119 *
120 * @retval None
121 */
FMC_Lock(void)122 void FMC_Lock(void)
123 {
124 FMC->CTRL2_B.LOCK = BIT_SET;
125 }
126
127 /*!
128 * @brief Erases a specified FMC page.
129 *
130 * @param pageAddr: The page address to be erased.
131 *
132 * @retval Returns the flash state.It can be one of value:
133 * @arg FMC_STATUS_BUSY
134 * @arg FMC_STATUS_ERROR_PG
135 * @arg FMC_STATUS_ERROR_WRP
136 * @arg FMC_STATUS_COMPLETE
137 * @arg FMC_STATUS_TIMEOUT
138 */
FMC_ErasePage(uint32_t pageAddr)139 FMC_STATUS_T FMC_ErasePage(uint32_t pageAddr)
140 {
141 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
142
143 status = FMC_WaitForLastOperation(0x000B0000);
144 if (status == FMC_STATUS_COMPLETE)
145 {
146 FMC->CTRL2_B.PAGEERA = BIT_SET;
147 FMC->ADDR = pageAddr;
148 FMC->CTRL2_B.STA = BIT_SET;
149
150 status = FMC_WaitForLastOperation(0x000B0000);
151 FMC->CTRL2_B.PAGEERA = BIT_RESET;
152 }
153 return status;
154 }
155
156 /*!
157 * @brief Erases all FMC pages.
158 *
159 * @param None
160 *
161 * @retval Returns the flash state.It can be one of value:
162 * @arg FMC_STATUS_ERROR_PG
163 * @arg FMC_STATUS_ERROR_WRP
164 * @arg FMC_STATUS_COMPLETE
165 * @arg FMC_STATUS_TIMEOUT
166 */
FMC_EraseAllPage(void)167 FMC_STATUS_T FMC_EraseAllPage(void)
168 {
169 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
170
171 status = FMC_WaitForLastOperation(0x000B0000);
172 if (status == FMC_STATUS_COMPLETE)
173 {
174 FMC->CTRL2_B.MASSERA = BIT_SET;
175 FMC->CTRL2_B.STA = BIT_SET;
176
177 status = FMC_WaitForLastOperation(0x000B0000);
178 FMC->CTRL2_B.MASSERA = BIT_RESET;
179 }
180 return status;
181 }
182
183 /*!
184 * @brief Erases the FMC option bytes.
185 *
186 * @param None
187 *
188 * @retval Returns the flash state.It can be one of value:
189 * @arg FMC_STATUS_ERROR_PG
190 * @arg FMC_STATUS_ERROR_WRP
191 * @arg FMC_STATUS_COMPLETE
192 * @arg FMC_STATUS_TIMEOUT
193 */
FMC_EraseOptionBytes(void)194 FMC_STATUS_T FMC_EraseOptionBytes(void)
195 {
196 uint16_t rdtemp = 0x00A5;
197 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
198
199 if (FMC_GetReadProtectionStatus() != RESET)
200 {
201 rdtemp = 0x00;
202 }
203 status = FMC_WaitForLastOperation(0x000B0000);
204 if (status == FMC_STATUS_COMPLETE)
205 {
206 FMC->OBKEY = 0x45670123;
207 FMC->OBKEY = 0xCDEF89AB;
208
209 FMC->CTRL2_B.OBE = BIT_SET;
210 FMC->CTRL2_B.STA = BIT_SET;
211
212 status = FMC_WaitForLastOperation(0x000B0000);
213
214 if (status == FMC_STATUS_COMPLETE)
215 {
216 FMC->CTRL2_B.OBE = BIT_RESET;
217 FMC->CTRL2_B.OBP = BIT_SET;
218 OB->RDP = rdtemp;
219 status = FMC_WaitForLastOperation(0x000B0000);
220 if (status != FMC_STATUS_TIMEOUT)
221 {
222 FMC->CTRL2_B.OBP = BIT_RESET;
223 }
224 }
225 else if (status != FMC_STATUS_TIMEOUT)
226 {
227 FMC->CTRL2_B.OBP = BIT_RESET;
228 }
229 }
230 return status;
231 }
232
233 /*!
234 * @brief Programs a word at a specified address.
235 *
236 * @param address:the address to be programmed.
237 *
238 * @param data: the data to be programmed.
239 *
240 * @retval Returns the flash state.It can be one of value:
241 * @arg FMC_STATUS_ERROR_PG
242 * @arg FMC_STATUS_ERROR_WRP
243 * @arg FMC_STATUS_COMPLETE
244 * @arg FMC_STATUS_TIMEOUT
245 */
FMC_ProgramWord(uint32_t address,uint32_t data)246 FMC_STATUS_T FMC_ProgramWord(uint32_t address, uint32_t data)
247 {
248 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
249 __IOM uint32_t temp = 0;
250
251 #ifdef APM32F10X_HD
252 __set_PRIMASK(1);
253 #endif
254
255 status = FMC_WaitForLastOperation(0x000B0000);
256
257 if (status == FMC_STATUS_COMPLETE)
258 {
259 FMC->CTRL2_B.PG = BIT_SET;
260
261 *(__IOM uint16_t*)address = data;
262
263 status = FMC_WaitForLastOperation(0x000B0000);
264
265 if (status == FMC_STATUS_COMPLETE)
266 {
267 temp = address + 2;
268
269 *(__IOM uint16_t*) temp = data >> 16;
270
271 status = FMC_WaitForLastOperation(0x000B0000);
272 FMC->CTRL2_B.PG = BIT_RESET;
273 }
274 else
275 {
276 FMC->CTRL2_B.PG = BIT_RESET;
277 }
278 }
279
280 #ifdef APM32F10X_HD
281 __set_PRIMASK(0);
282 #endif
283
284 return status;
285 }
286
287 /*!
288 * @brief Programs a half word at a specified address.
289 *
290 * @param address:the address to be programmed.
291 *
292 * @param data: the data to be programmed.
293 *
294 * @retval Returns the flash state.It can be one of value:
295 * @arg FMC_STATUS_ERROR_PG
296 * @arg FMC_STATUS_ERROR_WRP
297 * @arg FMC_STATUS_COMPLETE
298 * @arg FMC_STATUS_TIMEOUT
299 */
FMC_ProgramHalfWord(uint32_t address,uint16_t data)300 FMC_STATUS_T FMC_ProgramHalfWord(uint32_t address, uint16_t data)
301 {
302 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
303
304 #ifdef APM32F10X_HD
305 __set_PRIMASK(1);
306 #endif
307
308 status = FMC_WaitForLastOperation(0x000B0000);
309
310 if (status == FMC_STATUS_COMPLETE)
311 {
312 FMC->CTRL2_B.PG = BIT_SET;
313 *(__IOM uint16_t*)address = data;
314 status = FMC_WaitForLastOperation(0x000B0000);
315 FMC->CTRL2_B.PG = BIT_RESET;
316 }
317
318 #ifdef APM32F10X_HD
319 __set_PRIMASK(0);
320 #endif
321
322 return status;
323 }
324
325 /*!
326 * @brief Programs a half word at a specified Option Byte Data address.
327 *
328 * @param address:the address to be programmed.
329 *
330 * @param data: the data to be programmed.
331 *
332 * @retval Returns the flash state.It can be one of value:
333 * @arg FMC_STATUS_ERROR_PG
334 * @arg FMC_STATUS_ERROR_WRP
335 * @arg FMC_STATUS_COMPLETE
336 * @arg FMC_STATUS_TIMEOUT
337 */
FMC_ProgramOptionByteData(uint32_t address,uint8_t data)338 FMC_STATUS_T FMC_ProgramOptionByteData(uint32_t address, uint8_t data)
339 {
340 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
341
342 status = FMC_WaitForLastOperation(0x000B0000);
343
344 if (status == FMC_STATUS_COMPLETE)
345 {
346 FMC->OBKEY = 0x45670123;
347 FMC->OBKEY = 0xCDEF89AB;
348
349 FMC->CTRL2_B.OBP = BIT_SET;
350 *(__IOM uint16_t*)address = data;
351 status = FMC_WaitForLastOperation(0x000B0000);
352 if (status == FMC_STATUS_TIMEOUT)
353 {
354 FMC->CTRL2_B.OBP = BIT_RESET;
355 }
356 }
357 return status;
358 }
359
360 /*!
361 * @brief Write protects the desired pages
362 *
363 * @param page:the address of the pages to be write protection
364 * This parameter can be any combination of the following values:
365 * for APM32F10X_LD :
366 * @arg FLASH_WRP_PAGE_0_3 to FLASH_WRP_PAGE_28_31
367 * for APM32F10X_MD :
368 * @arg FLASH_WRP_PAGE_0_3 to FLASH_WRP_PAGE_124_127
369 * for APM32F10X_HD :
370 * @arg FLASH_WRP_PAGE_0_1 to FLASH_WRP_PAGE_60_61 or FLASH_WRP_PAGE_62_127
371 * @arg FMC_WRP_PAGE_ALL
372 *
373 * @retval Returns the flash state.It can be one of value:
374 * @arg FMC_STATUS_ERROR_PG
375 * @arg FMC_STATUS_ERROR_WRP
376 * @arg FMC_STATUS_COMPLETE
377 * @arg FMC_STATUS_TIMEOUT
378 */
FMC_EnableWriteProtection(uint32_t page)379 FMC_STATUS_T FMC_EnableWriteProtection(uint32_t page)
380 {
381 uint16_t WPP0_Data = 0xFFFF, WPP1_Data = 0xFFFF, WPP2_Data = 0xFFFF, WPP3_Data = 0xFFFF;
382 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
383
384 page = ~page;
385 WPP0_Data = (page & 0x000000FF);
386 WPP1_Data = (page & 0x0000FF00) >> 8;
387 WPP2_Data = (page & 0x00FF0000) >> 16;
388 WPP3_Data = (page & 0xFF000000) >> 24;
389
390 status = FMC_WaitForLastOperation(0x000B0000);
391
392 if (status == FMC_STATUS_COMPLETE)
393 {
394 FMC->OBKEY = 0x45670123;
395 FMC->OBKEY = 0xCDEF89AB;
396 FMC->CTRL2_B.OBP = BIT_SET;
397
398 if (WPP0_Data != 0xFF)
399 {
400 OB->WRP0 = WPP0_Data;
401 status = FMC_WaitForLastOperation(0x000B0000);
402 }
403 if ((status == FMC_STATUS_COMPLETE) && (WPP1_Data != 0xFF))
404 {
405 OB->WRP1 = WPP1_Data;
406 status = FMC_WaitForLastOperation(0x000B0000);
407 }
408 if ((status == FMC_STATUS_COMPLETE) && (WPP2_Data != 0xFF))
409 {
410 OB->WRP2 = WPP2_Data;
411 status = FMC_WaitForLastOperation(0x000B0000);
412 }
413 if ((status == FMC_STATUS_COMPLETE) && (WPP3_Data != 0xFF))
414 {
415 OB->WRP3 = WPP3_Data;
416 status = FMC_WaitForLastOperation(0x000B0000);
417 }
418
419 if (status != FMC_STATUS_TIMEOUT)
420 {
421 FMC->CTRL2_B.OBP = BIT_RESET;
422 }
423 }
424 return status;
425 }
426
427 /*!
428 * @brief Enables the read out protection.
429 *
430 * @param None
431 *
432 * @retval Returns the flash state.It can be one of value:
433 * @arg FMC_STATUS_ERROR_PG
434 * @arg FMC_STATUS_ERROR_WRP
435 * @arg FMC_STATUS_COMPLETE
436 * @arg FMC_STATUS_TIMEOUT
437 */
FMC_EnableReadOutProtection(void)438 FMC_STATUS_T FMC_EnableReadOutProtection(void)
439 {
440 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
441
442 status = FMC_WaitForLastOperation(0x000B0000);
443
444 if (status == FMC_STATUS_COMPLETE)
445 {
446 FMC->OBKEY = 0x45670123;
447 FMC->OBKEY = 0xCDEF89AB;
448
449 FMC->CTRL2_B.OBE = BIT_SET;
450 FMC->CTRL2_B.STA = BIT_SET;
451
452 status = FMC_WaitForLastOperation(0x000B0000);
453
454 if (status == FMC_STATUS_COMPLETE)
455 {
456 FMC->CTRL2_B.OBE = BIT_RESET;
457 FMC->CTRL2_B.OBP = BIT_SET;
458 OB->RDP = 0x00;
459
460 status = FMC_WaitForLastOperation(0x000B0000);
461
462 if (status != FMC_STATUS_TIMEOUT)
463 {
464 FMC->CTRL2_B.OBP = BIT_RESET;
465 }
466 }
467 else if (status != FMC_STATUS_TIMEOUT)
468 {
469 FMC->CTRL2_B.OBE = BIT_RESET;
470 }
471 }
472 return status;
473 }
474
475 /*!
476 * @brief Disables the read out protection.
477 *
478 * @param None
479 *
480 * @retval Returns the flash state.It can be one of value:
481 * @arg FMC_STATUS_ERROR_PG
482 * @arg FMC_STATUS_ERROR_WRP
483 * @arg FMC_STATUS_COMPLETE
484 * @arg FMC_STATUS_TIMEOUT
485 */
FMC_DisableReadOutProtection(void)486 FMC_STATUS_T FMC_DisableReadOutProtection(void)
487 {
488 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
489
490 status = FMC_WaitForLastOperation(0x000B0000);
491
492 if (status == FMC_STATUS_COMPLETE)
493 {
494 FMC->OBKEY = 0x45670123;
495 FMC->OBKEY = 0xCDEF89AB;
496 FMC->CTRL2_B.OBE = BIT_SET;
497 FMC->CTRL2_B.STA = BIT_SET;
498
499 status = FMC_WaitForLastOperation(0x000B0000);
500
501 if (status == FMC_STATUS_COMPLETE)
502 {
503 FMC->CTRL2_B.OBE = BIT_RESET;
504 FMC->CTRL2_B.OBP = BIT_SET;
505 OB->RDP = 0xA5;
506
507 status = FMC_WaitForLastOperation(0x000B0000);
508
509 if (status != FMC_STATUS_TIMEOUT)
510 {
511 FMC->CTRL2_B.OBP = BIT_RESET;
512 }
513 }
514 else if (status != FMC_STATUS_TIMEOUT)
515 {
516 FMC->CTRL2_B.OBE = BIT_RESET;
517 }
518 }
519 return status;
520 }
521
522 /*!
523 * @brief Programs the FMC User Option Byte.
524 *
525 * @param userConfig: Point to a FMC_UserConfig_T structure.
526 *
527 * @retval Returns the flash state.It can be one of value:
528 * @arg FMC_STATUS_ERROR_PG
529 * @arg FMC_STATUS_ERROR_WRP
530 * @arg FMC_STATUS_COMPLETE
531 * @arg FMC_STATUS_TIMEOUT
532 */
FMC_ConfigUserOptionByte(FMC_UserConfig_T * userConfig)533 FMC_STATUS_T FMC_ConfigUserOptionByte(FMC_UserConfig_T* userConfig)
534 {
535 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
536
537 FMC->OBKEY = 0x45670123;
538 FMC->OBKEY = 0xCDEF89AB;
539
540 status = FMC_WaitForLastOperation(0x000B0000);
541
542 if (status == FMC_STATUS_COMPLETE)
543 {
544 FMC->CTRL2_B.OBP = BIT_SET;
545 OB->USER = (uint32_t)userConfig->iwdtSet | \
546 (uint32_t)userConfig->stopSet | \
547 (uint32_t)userConfig->stdbySet | 0xF8;
548 status = FMC_WaitForLastOperation(0x000B0000);
549 if (status == FMC_STATUS_TIMEOUT)
550 {
551 FMC->CTRL2_B.OBP = BIT_RESET;
552 }
553 }
554 return status;
555 }
556
557 /*!
558 * @brief Read the FMC User Option Bytes values.
559 *
560 * @param None
561 *
562 * @retval Returns User Option Bytes values
563 */
FMC_ReadUserOptionByte(void)564 uint32_t FMC_ReadUserOptionByte(void)
565 {
566 return (FMC->OBCS_B.UOB >> 2);
567 }
568
569 /*!
570 * @brief Read the FMC Write Protection Option Bytes Register value.
571 *
572 * @param None
573 *
574 * @retval Returns the value of Option Bytes Write Protection Register.
575 */
FMC_ReadOptionByteWriteProtection(void)576 uint32_t FMC_ReadOptionByteWriteProtection(void)
577 {
578 return FMC->WRTPROT;
579 }
580
581 /*!
582 * @brief Get the FMC Read Out Protection Status is set or not.
583 *
584 * @param None
585 *
586 * @retval status : set or reset.
587 */
FMC_GetReadProtectionStatus(void)588 uint8_t FMC_GetReadProtectionStatus(void)
589 {
590 uint8_t flagstatus = RESET;
591
592 if (FMC->OBCS_B.READPROT != RESET)
593 {
594 flagstatus = SET;
595 }
596 else
597 {
598 flagstatus = RESET;
599 }
600 return flagstatus;
601 }
602
603 /*!
604 * @brief FMC Prefetch Buffer status is set or not.
605 *
606 * @param None
607 *
608 * @retval status : set or reset.
609 */
FMC_ReadPrefetchBufferStatus(void)610 uint8_t FMC_ReadPrefetchBufferStatus(void)
611 {
612 return FMC->CTRL1_B.PBSF;
613 }
614
615 /*!
616 * @brief Enables the specified FMC interrupts.
617 *
618 * @param interrupt: Select the FMC interrupt sources
619 * This parameter can be one of the following values:
620 * @arg FMC_INT_ERR : Error Interrupt
621 * @arg FMC_INT_OC : Operation Complete Interrupt
622 *
623 * @retval None
624 */
FMC_EnableInterrupt(FMC_INT_T interrupt)625 void FMC_EnableInterrupt(FMC_INT_T interrupt)
626 {
627 if (interrupt == FMC_INT_ERR)
628 {
629 FMC->CTRL2_B.ERRIE = ENABLE;
630 }
631 else
632 {
633 FMC->CTRL2_B.OCIE = ENABLE;
634 }
635 }
636
637 /*!
638 * @brief Disable the specified FMC interrupts.
639 *
640 * @param interrupt: Select the FMC interrupt sources
641 * This parameter can be one of the following values:
642 * @arg FMC_INT_ERR : Error Interrupt
643 * @arg FMC_INT_OC : Operation Complete Interrupt
644 *
645 * @retval None
646 */
FMC_DisableInterrupt(FMC_INT_T interrupt)647 void FMC_DisableInterrupt(FMC_INT_T interrupt)
648 {
649 if (interrupt == FMC_INT_ERR)
650 {
651 FMC->CTRL2_B.ERRIE = DISABLE;
652 }
653 else
654 {
655 FMC->CTRL2_B.OCIE = DISABLE;
656 }
657 }
658
659 /*!
660 * @brief Read FMC flag is set or not
661 *
662 * @param flag: status flag of FMC
663 * This parameter can be one of the following values:
664 * @arg FMC_FLAG_BUSY : FMC Busy flag
665 * @arg FMC_FLAG_OC : FMC Operation Complete flag
666 * @arg FMC_FLAG_PE : FMC Program error flag
667 * @arg FMC_FLAG_WPE : FMC Write protected error flag
668 * @arg FMC_FLAG_OBE : FMC Option Byte error flag
669 *
670 * @retval flag status : set or reset
671 */
FMC_ReadStatusFlag(FMC_FLAG_T flag)672 uint8_t FMC_ReadStatusFlag(FMC_FLAG_T flag)
673 {
674 if (flag == FMC_FLAG_OBE)
675 {
676 return FMC->OBCS_B.OBE;
677 }
678 else if ((FMC->STS & flag) != RESET)
679 {
680 return SET;
681 }
682 return RESET;
683 }
684
685 /*!
686 * @brief Clears the FMC's flag.
687 *
688 * @param flag: status flag of FMC
689 * This parameter can be any combination of the following values:
690 * @arg FMC_FLAG_OC : FMC Operation Complete flag
691 * @arg FMC_FLAG_PE : FMC Program error flag
692 * @arg FMC_FLAG_WPE : FMC Write protected error flag
693 *
694 * @retval None
695 *
696 */
FMC_ClearStatusFlag(uint32_t flag)697 void FMC_ClearStatusFlag(uint32_t flag)
698 {
699 FMC->STS = flag;
700 }
701
702 /*!
703 * @brief Read the FMC Status.
704 *
705 * @param None
706 *
707 * @retval Returns the flash state.It can be one of value:
708 * @arg FMC_STATUS_BUSY
709 * @arg FMC_STATUS_ERROR_PG
710 * @arg FMC_STATUS_ERROR_WRP
711 * @arg FMC_STATUS_COMPLETE
712 */
FMC_ReadStatus(void)713 FMC_STATUS_T FMC_ReadStatus(void)
714 {
715 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
716
717 if (FMC->STS_B.BUSYF == BIT_SET)
718 {
719 status = FMC_STATUS_BUSY;
720 }
721 else if (FMC->STS_B.PEF == BIT_SET)
722 {
723 status = FMC_STATUS_ERROR_PG;
724 }
725 else if (FMC->STS_B.WPEF == BIT_SET)
726 {
727 status = FMC_STATUS_ERROR_WRP;
728 }
729 else
730 {
731 status = FMC_STATUS_COMPLETE;
732 }
733 return status;
734 }
735
736 /*!
737 * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
738 *
739 * @param timeOut:FMC programming timeout value.
740 *
741 * @retval Returns the flash state.It can be one of value:
742 * @arg FMC_STATUS_ERROR_PG
743 * @arg FMC_STATUS_ERROR_WRP
744 * @arg FMC_STATUS_COMPLETE
745 * @arg FMC_STATUS_TIMEOUT
746 */
FMC_WaitForLastOperation(uint32_t timeOut)747 FMC_STATUS_T FMC_WaitForLastOperation(uint32_t timeOut)
748 {
749 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
750
751 /** Check for the Flash Status */
752 status = FMC_ReadStatus();
753
754 /** Wait for a Flash operation to complete or a TIMEOUT to occur */
755 while ((status == FMC_STATUS_BUSY) && (timeOut != 0))
756 {
757 status = FMC_ReadStatus();
758 timeOut--;
759 }
760 if (timeOut == 0x00)
761 {
762 status = FMC_STATUS_TIMEOUT;
763 }
764 return status;
765 }
766
767 /**@} end of group FMC_Functions*/
768 /**@} end of group FMC_Driver*/
769 /**@} end of group APM32F10x_StdPeriphDriver*/
770