1 /*!
2 * @file apm32s10x_fmc.c
3 *
4 * @brief This file provides all the FMC firmware functions
5 *
6 * @version V1.0.1
7 *
8 * @date 2022-12-31
9 *
10 * @attention
11 *
12 * Copyright (C) 2022-2023 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be usefull and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 /* Includes */
27 #include "apm32s10x_fmc.h"
28 #include "apm32s10x_rcm.h"
29
30 /** @addtogroup APM32S10x_StdPeriphDriver
31 @{
32 */
33
34 /** @addtogroup FMC_Driver FMC Driver
35 @{
36 */
37
38 /** @defgroup FMC_Functions Functions
39 @{
40 */
41
42 /*!
43 * @brief Configure 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 Enable 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 Enable 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 Disable 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 Unlock 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 Lock 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 Erase a specified FMC page.
129 *
130 * @param pageAddr: The page address to be erased.
131 *
132 * @retval Return 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 Erase all FMC pages.
158 *
159 * @param None
160 *
161 * @retval Return 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 Erase the FMC option bytes.
185 *
186 * @param None
187 *
188 * @retval Return 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 Program 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 Return 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 APM32S10X_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 APM32S10X_HD
281 __set_PRIMASK(0);
282 #endif
283
284 return status;
285 }
286
287 /*!
288 * @brief Program 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 Return 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 APM32S10X_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 APM32S10X_HD
319 __set_PRIMASK(0);
320 #endif
321
322 return status;
323 }
324
325 /*!
326 * @brief Program 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 Return 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 * @arg FLASH_WRP_PAGE_0_3 to FLASH_WRP_PAGE_124_127
366 *
367 * @retval Return the flash state.It can be one of value:
368 * @arg FMC_STATUS_ERROR_PG
369 * @arg FMC_STATUS_ERROR_WRP
370 * @arg FMC_STATUS_COMPLETE
371 * @arg FMC_STATUS_TIMEOUT
372 */
FMC_EnableWriteProtection(uint32_t page)373 FMC_STATUS_T FMC_EnableWriteProtection(uint32_t page)
374 {
375 uint16_t WPP0_Data = 0xFFFF, WPP1_Data = 0xFFFF, WPP2_Data = 0xFFFF, WPP3_Data = 0xFFFF;
376 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
377
378 page = ~page;
379 WPP0_Data = (page & 0x000000FF);
380 WPP1_Data = (page & 0x0000FF00) >> 8;
381 WPP2_Data = (page & 0x00FF0000) >> 16;
382 WPP3_Data = (page & 0xFF000000) >> 24;
383
384 status = FMC_WaitForLastOperation(0x000B0000);
385
386 if (status == FMC_STATUS_COMPLETE)
387 {
388 FMC->OBKEY = 0x45670123;
389 FMC->OBKEY = 0xCDEF89AB;
390 FMC->CTRL2_B.OBP = BIT_SET;
391
392 if (WPP0_Data != 0xFF)
393 {
394 OB->WRP0 = WPP0_Data;
395 status = FMC_WaitForLastOperation(0x000B0000);
396 }
397 if ((status == FMC_STATUS_COMPLETE) && (WPP1_Data != 0xFF))
398 {
399 OB->WRP1 = WPP1_Data;
400 status = FMC_WaitForLastOperation(0x000B0000);
401 }
402 if ((status == FMC_STATUS_COMPLETE) && (WPP2_Data != 0xFF))
403 {
404 OB->WRP2 = WPP2_Data;
405 status = FMC_WaitForLastOperation(0x000B0000);
406 }
407 if ((status == FMC_STATUS_COMPLETE) && (WPP3_Data != 0xFF))
408 {
409 OB->WRP3 = WPP3_Data;
410 status = FMC_WaitForLastOperation(0x000B0000);
411 }
412
413 if (status != FMC_STATUS_TIMEOUT)
414 {
415 FMC->CTRL2_B.OBP = BIT_RESET;
416 }
417 }
418 return status;
419 }
420
421 /*!
422 * @brief Enable the read out protection.
423 *
424 * @param None
425 *
426 * @retval Return the flash state.It can be one of value:
427 * @arg FMC_STATUS_ERROR_PG
428 * @arg FMC_STATUS_ERROR_WRP
429 * @arg FMC_STATUS_COMPLETE
430 * @arg FMC_STATUS_TIMEOUT
431 */
FMC_EnableReadOutProtection(void)432 FMC_STATUS_T FMC_EnableReadOutProtection(void)
433 {
434 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
435
436 status = FMC_WaitForLastOperation(0x000B0000);
437
438 if (status == FMC_STATUS_COMPLETE)
439 {
440 FMC->OBKEY = 0x45670123;
441 FMC->OBKEY = 0xCDEF89AB;
442
443 FMC->CTRL2_B.OBE = BIT_SET;
444 FMC->CTRL2_B.STA = BIT_SET;
445
446 status = FMC_WaitForLastOperation(0x000B0000);
447
448 if (status == FMC_STATUS_COMPLETE)
449 {
450 FMC->CTRL2_B.OBE = BIT_RESET;
451 FMC->CTRL2_B.OBP = BIT_SET;
452 OB->RDP = 0x00;
453
454 status = FMC_WaitForLastOperation(0x000B0000);
455
456 if (status != FMC_STATUS_TIMEOUT)
457 {
458 FMC->CTRL2_B.OBP = BIT_RESET;
459 }
460 }
461 else if (status != FMC_STATUS_TIMEOUT)
462 {
463 FMC->CTRL2_B.OBE = BIT_RESET;
464 }
465 }
466 return status;
467 }
468
469 /*!
470 * @brief Disable the read out protection.
471 *
472 * @param None
473 *
474 * @retval Return the flash state.It can be one of value:
475 * @arg FMC_STATUS_ERROR_PG
476 * @arg FMC_STATUS_ERROR_WRP
477 * @arg FMC_STATUS_COMPLETE
478 * @arg FMC_STATUS_TIMEOUT
479 */
FMC_DisableReadOutProtection(void)480 FMC_STATUS_T FMC_DisableReadOutProtection(void)
481 {
482 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
483
484 status = FMC_WaitForLastOperation(0x000B0000);
485
486 if (status == FMC_STATUS_COMPLETE)
487 {
488 FMC->OBKEY = 0x45670123;
489 FMC->OBKEY = 0xCDEF89AB;
490 FMC->CTRL2_B.OBE = BIT_SET;
491 FMC->CTRL2_B.STA = BIT_SET;
492
493 status = FMC_WaitForLastOperation(0x000B0000);
494
495 if (status == FMC_STATUS_COMPLETE)
496 {
497 FMC->CTRL2_B.OBE = BIT_RESET;
498 FMC->CTRL2_B.OBP = BIT_SET;
499 OB->RDP = 0xA5;
500
501 status = FMC_WaitForLastOperation(0x000B0000);
502
503 if (status != FMC_STATUS_TIMEOUT)
504 {
505 FMC->CTRL2_B.OBP = BIT_RESET;
506 }
507 }
508 else if (status != FMC_STATUS_TIMEOUT)
509 {
510 FMC->CTRL2_B.OBE = BIT_RESET;
511 }
512 }
513 return status;
514 }
515
516 /*!
517 * @brief Program the FMC User Option Byte.
518 *
519 * @param userConfig: Point to a FMC_UserConfig_T structure.
520 *
521 * @retval Return the flash state.It can be one of value:
522 * @arg FMC_STATUS_ERROR_PG
523 * @arg FMC_STATUS_ERROR_WRP
524 * @arg FMC_STATUS_COMPLETE
525 * @arg FMC_STATUS_TIMEOUT
526 */
FMC_ConfigUserOptionByte(FMC_UserConfig_T * userConfig)527 FMC_STATUS_T FMC_ConfigUserOptionByte(FMC_UserConfig_T* userConfig)
528 {
529 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
530
531 FMC->OBKEY = 0x45670123;
532 FMC->OBKEY = 0xCDEF89AB;
533
534 status = FMC_WaitForLastOperation(0x000B0000);
535
536 if (status == FMC_STATUS_COMPLETE)
537 {
538 FMC->CTRL2_B.OBP = BIT_SET;
539 OB->USER = (uint32_t)userConfig->iwdtSet | \
540 (uint32_t)userConfig->stopSet | \
541 (uint32_t)userConfig->stdbySet | 0xF8;
542 status = FMC_WaitForLastOperation(0x000B0000);
543 if (status == FMC_STATUS_TIMEOUT)
544 {
545 FMC->CTRL2_B.OBP = BIT_RESET;
546 }
547 }
548 return status;
549 }
550
551 /*!
552 * @brief Read the FMC User Option Bytes values.
553 *
554 * @param None
555 *
556 * @retval Return User Option Bytes values
557 */
FMC_ReadUserOptionByte(void)558 uint32_t FMC_ReadUserOptionByte(void)
559 {
560 return (FMC->OBCS_B.UOB >> 2);
561 }
562
563 /*!
564 * @brief Read the FMC Write Protection Option Bytes Register value.
565 *
566 * @param None
567 *
568 * @retval Return the value of Option Bytes Write Protection Register.
569 */
FMC_ReadOptionByteWriteProtection(void)570 uint32_t FMC_ReadOptionByteWriteProtection(void)
571 {
572 return FMC->WRTPROT;
573 }
574
575 /*!
576 * @brief Get the FMC Read Out Protection Status is set or not.
577 *
578 * @param None
579 *
580 * @retval status : set or reset.
581 */
FMC_GetReadProtectionStatus(void)582 uint8_t FMC_GetReadProtectionStatus(void)
583 {
584 uint8_t flagstatus = RESET;
585
586 if (FMC->OBCS_B.READPROT != RESET)
587 {
588 flagstatus = SET;
589 }
590 else
591 {
592 flagstatus = RESET;
593 }
594 return flagstatus;
595 }
596
597 /*!
598 * @brief FMC Prefetch Buffer status is set or not.
599 *
600 * @param None
601 *
602 * @retval status : set or reset.
603 */
FMC_ReadPrefetchBufferStatus(void)604 uint8_t FMC_ReadPrefetchBufferStatus(void)
605 {
606 return FMC->CTRL1_B.PBSF;
607 }
608
609 /*!
610 * @brief Enable the specified FMC interrupts.
611 *
612 * @param interrupt: Select the FMC interrupt sources
613 * This parameter can be one of the following values:
614 * @arg FMC_INT_ERR : Error Interrupt
615 * @arg FMC_INT_OC : Operation Complete Interrupt
616 *
617 * @retval None
618 */
FMC_EnableInterrupt(FMC_INT_T interrupt)619 void FMC_EnableInterrupt(FMC_INT_T interrupt)
620 {
621 if (interrupt == FMC_INT_ERR)
622 {
623 FMC->CTRL2_B.ERRIE = ENABLE;
624 }
625 else
626 {
627 FMC->CTRL2_B.OCIE = ENABLE;
628 }
629 }
630
631 /*!
632 * @brief Disable the specified FMC interrupts.
633 *
634 * @param interrupt: Select the FMC interrupt sources
635 * This parameter can be one of the following values:
636 * @arg FMC_INT_ERR : Error Interrupt
637 * @arg FMC_INT_OC : Operation Complete Interrupt
638 *
639 * @retval None
640 */
FMC_DisableInterrupt(FMC_INT_T interrupt)641 void FMC_DisableInterrupt(FMC_INT_T interrupt)
642 {
643 if (interrupt == FMC_INT_ERR)
644 {
645 FMC->CTRL2_B.ERRIE = DISABLE;
646 }
647 else
648 {
649 FMC->CTRL2_B.OCIE = DISABLE;
650 }
651 }
652
653 /*!
654 * @brief Read FMC flag is set or not
655 *
656 * @param flag: status flag of FMC
657 * This parameter can be one of the following values:
658 * @arg FMC_FLAG_BUSY : FMC Busy flag
659 * @arg FMC_FLAG_OC : FMC Operation Complete flag
660 * @arg FMC_FLAG_PE : FMC Program error flag
661 * @arg FMC_FLAG_WPE : FMC Write protected error flag
662 * @arg FMC_FLAG_OBE : FMC Option Byte error flag
663 *
664 * @retval flag status : set or reset
665 */
FMC_ReadStatusFlag(FMC_FLAG_T flag)666 uint8_t FMC_ReadStatusFlag(FMC_FLAG_T flag)
667 {
668 if (flag == FMC_FLAG_OBE)
669 {
670 return FMC->OBCS_B.OBE;
671 }
672 else if ((FMC->STS & flag) != RESET)
673 {
674 return SET;
675 }
676 return RESET;
677 }
678
679 /*!
680 * @brief Clear the FMC's flag.
681 *
682 * @param flag: status flag of FMC
683 * This parameter can be any combination of the following values:
684 * @arg FMC_FLAG_OC : FMC Operation Complete flag
685 * @arg FMC_FLAG_PE : FMC Program error flag
686 * @arg FMC_FLAG_WPE : FMC Write protected error flag
687 *
688 * @retval None
689 *
690 */
FMC_ClearStatusFlag(uint32_t flag)691 void FMC_ClearStatusFlag(uint32_t flag)
692 {
693 FMC->STS = flag;
694 }
695
696 /*!
697 * @brief Read the FMC Status.
698 *
699 * @param None
700 *
701 * @retval Return the flash state.It can be one of value:
702 * @arg FMC_STATUS_BUSY
703 * @arg FMC_STATUS_ERROR_PG
704 * @arg FMC_STATUS_ERROR_WRP
705 * @arg FMC_STATUS_COMPLETE
706 */
FMC_ReadStatus(void)707 FMC_STATUS_T FMC_ReadStatus(void)
708 {
709 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
710
711 if (FMC->STS_B.BUSYF == BIT_SET)
712 {
713 status = FMC_STATUS_BUSY;
714 }
715 else if (FMC->STS_B.PEF == BIT_SET)
716 {
717 status = FMC_STATUS_ERROR_PG;
718 }
719 else if (FMC->STS_B.WPEF == BIT_SET)
720 {
721 status = FMC_STATUS_ERROR_WRP;
722 }
723 else
724 {
725 status = FMC_STATUS_COMPLETE;
726 }
727 return status;
728 }
729
730 /*!
731 * @brief Wait for a Flash operation to complete or a TIMEOUT to occur.
732 *
733 * @param timeOut:FMC programming timeout value.
734 *
735 * @retval Return the flash state.It can be one of value:
736 * @arg FMC_STATUS_ERROR_PG
737 * @arg FMC_STATUS_ERROR_WRP
738 * @arg FMC_STATUS_COMPLETE
739 * @arg FMC_STATUS_TIMEOUT
740 */
FMC_WaitForLastOperation(uint32_t timeOut)741 FMC_STATUS_T FMC_WaitForLastOperation(uint32_t timeOut)
742 {
743 FMC_STATUS_T status = FMC_STATUS_COMPLETE;
744
745 /* Check for the Flash Status */
746 status = FMC_ReadStatus();
747
748 /* Wait for a Flash operation to complete or a TIMEOUT to occur */
749 while ((status == FMC_STATUS_BUSY) && (timeOut != 0))
750 {
751 status = FMC_ReadStatus();
752 timeOut--;
753 }
754 if (timeOut == 0x00)
755 {
756 status = FMC_STATUS_TIMEOUT;
757 }
758 return status;
759 }
760
761 /**@} end of group FMC_Functions */
762 /**@} end of group FMC_Driver */
763 /**@} end of group APM32S10x_StdPeriphDriver */
764