1 /*!
2 * @file apm32f0xx_fmc.c
3 *
4 * @brief This file provides all the FMC firmware functions
5 *
6 * @version V1.0.3
7 *
8 * @date 2022-09-20
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 #include "apm32f0xx_fmc.h"
27
28 /** @addtogroup APM32F0xx_StdPeriphDriver
29 @{
30 */
31
32 /** @addtogroup FMC_Driver
33 @{
34 */
35
36 /** @defgroup FMC_Macros Macros
37 @{
38 */
39
40 /**@} end of group FMC_Macros */
41
42 /** @defgroup FMC_Enumerates Enumerates
43 @{
44 */
45
46 /**@} end of group FMC_Enumerates */
47
48 /** @defgroup FMC_Structures Structures
49 @{
50 */
51
52 /**@} end of group FMC_Structures */
53
54 /** @defgroup FMC_Variables Variables
55 @{
56 */
57
58 /**@} end of group FMC_Variables */
59
60 /** @defgroup FMC_Functions Functions
61 @{
62 */
63
64 /*!
65 * @brief Sets the code latency value.
66 *
67 * @param latency: the flash latency value.
68 * The parameter can be one of following values:
69 * @arg FMC_LATENCY_0
70 * @arg FMC_LATENCY_1
71 * @retval None
72 */
FMC_SetLatency(FMC_LATENCY_T latency)73 void FMC_SetLatency(FMC_LATENCY_T latency)
74 {
75 FMC->CTRL1_B.WS = latency;
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 Checks whether the flash Prefetch Buffer status is set or not
104 *
105 * @param None
106 *
107 * @retval flash Prefetch Buffer Status (SET or RESET)
108 */
FMC_ReadPrefetchBufferStatus(void)109 uint8_t FMC_ReadPrefetchBufferStatus(void)
110 {
111 if (FMC->CTRL1_B.PBSF)
112 {
113 return SET;
114 }
115
116 return RESET;
117 }
118
119 /*!
120 * @brief Unlocks the flash Program Erase Controller
121 *
122 * @param None
123 *
124 * @retval None
125 */
FMC_Unlock(void)126 void FMC_Unlock(void)
127 {
128 FMC->KEY = FMC_KEY_1;
129 FMC->KEY = FMC_KEY_2;
130 }
131
132 /*!
133 * @brief Locks the flash Program Erase Controller
134 *
135 * @param None
136 *
137 * @retval None
138 */
FMC_Lock(void)139 void FMC_Lock(void)
140 {
141 FMC->CTRL2_B.LOCK = BIT_SET;
142 }
143
144 /*!
145 * @brief Read flash state
146 *
147 * @param None
148 *
149 * @retval Returns the flash state.It can be one of value:
150 * @arg FMC_STATE_COMPLETE
151 * @arg FMC_STATE_BUSY
152 * @arg FMC_STATE_PG_ERR
153 * @arg FMC_STATE_WRP_ERR
154 */
FMC_ReadState(void)155 FMC_STATE_T FMC_ReadState(void)
156 {
157 uint32_t status;
158 FMC_STATE_T state = FMC_STATE_COMPLETE;
159
160 status = FMC->STS;
161
162 if (status & FMC_FLAG_PE)
163 {
164 state = FMC_STATE_PG_ERR;
165 }
166 else if (status & FMC_FLAG_WPE)
167 {
168 state = FMC_STATE_WRP_ERR;
169 }
170 else if (status & FMC_FLAG_BUSY)
171 {
172 state = FMC_STATE_BUSY;
173 }
174
175 return state;
176 }
177
178 /*!
179 * @brief Wait for flash controler ready
180 *
181 * @param timeOut: Specifies the time to wait
182 *
183 * @retval Returns the flash state.It can be one of value:
184 * @arg FMC_STATE_COMPLETE
185 * @arg FMC_STATE_BUSY
186 * @arg FMC_STATE_PG_ERR
187 * @arg FMC_STATE_WRP_ERR
188 * @arg FMC_STATE_TIMEOUT
189 */
FMC_WaitForReady(uint32_t timeOut)190 FMC_STATE_T FMC_WaitForReady(uint32_t timeOut)
191 {
192 FMC_STATE_T state;
193
194 do
195 {
196 state = FMC_ReadState();
197 timeOut--;
198 }
199 while ((state == FMC_STATE_BUSY) && (timeOut));
200
201 if (!timeOut)
202 {
203 state = FMC_STATE_TIMEOUT;
204 }
205
206 return state;
207 }
208
209 /*!
210 * @brief Erases a specified flash page
211 *
212 * @param pageAddr: Specifies the page address
213 *
214 * @retval Returns the flash state.It can be one of value:
215 * @arg FMC_STATE_COMPLETE
216 * @arg FMC_STATE_PG_ERR
217 * @arg FMC_STATE_WRP_ERR
218 * @arg FMC_STATE_TIMEOUT
219 */
FMC_ErasePage(uint32_t pageAddr)220 FMC_STATE_T FMC_ErasePage(uint32_t pageAddr)
221 {
222 FMC_STATE_T state;
223
224 state = FMC_WaitForReady(FMC_DELAY_ERASE);
225
226 if (state == FMC_STATE_COMPLETE)
227 {
228 FMC->CTRL2_B.PAGEERA = BIT_SET;
229
230 FMC->ADDR = pageAddr;
231
232 FMC->CTRL2_B.STA = BIT_SET;
233
234 state = FMC_WaitForReady(FMC_DELAY_ERASE);
235
236 FMC->CTRL2_B.PAGEERA = BIT_RESET;
237 }
238
239 return state;
240 }
241
242 /*!
243 * @brief Erases all flash pages
244 *
245 * @param None
246 *
247 * @retval Returns the flash state.It can be one of value:
248 * @arg FMC_STATE_COMPLETE
249 * @arg FMC_STATE_PG_ERR
250 * @arg FMC_STATE_WRP_ERR
251 * @arg FMC_STATE_TIMEOUT
252 * @note
253 */
FMC_EraseAllPages(void)254 FMC_STATE_T FMC_EraseAllPages(void)
255 {
256 FMC_STATE_T state;
257
258 state = FMC_WaitForReady(FMC_DELAY_ERASE);
259
260 if (state == FMC_STATE_COMPLETE)
261 {
262 FMC->CTRL2_B.MASSERA = BIT_SET;
263 FMC->CTRL2_B.STA = BIT_SET;
264
265 state = FMC_WaitForReady(FMC_DELAY_ERASE);
266
267 FMC->CTRL2_B.MASSERA = BIT_RESET;
268 }
269
270 return state;
271 }
272
273 /*!
274 * @brief Program a word at a specified address
275 *
276 * @param addr: Specifies the address to be programmed
277 *
278 * @param data: Specifies the data to be programmed
279 *
280 * @retval Returns the flash state.It can be one of value:
281 * @arg FMC_STATE_COMPLETE
282 * @arg FMC_STATE_PG_ERR
283 * @arg FMC_STATE_WRP_ERR
284 * @arg FMC_STATE_TIMEOUT
285 */
FMC_ProgramWord(uint32_t addr,uint32_t data)286 FMC_STATE_T FMC_ProgramWord(uint32_t addr, uint32_t data)
287 {
288 FMC_STATE_T state;
289
290 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
291
292 if (state == FMC_STATE_COMPLETE)
293 {
294 FMC->CTRL2_B.PG = BIT_SET;
295
296 *(__IO uint16_t*)addr = (uint16_t)data;
297
298 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
299
300 if (state == FMC_STATE_COMPLETE)
301 {
302 *(__IO uint16_t*)(addr + 2) = (uint16_t)(data >> 16);
303
304 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
305 }
306
307 FMC->CTRL2_B.PG = BIT_RESET;
308 }
309
310 return state;
311 }
312
313 /*!
314 * @brief Programs a half word at a specified address
315 *
316 * @param addr: Specifies the address to be programmed
317 *
318 * @param data: Specifies the data to be programmed
319 *
320 * @retval Returns the flash state.It can be one of value:
321 * @arg FMC_STATE_COMPLETE
322 * @arg FMC_STATE_PG_ERR
323 * @arg FMC_STATE_WRP_ERR
324 * @arg FMC_STATE_TIMEOUT
325 */
FMC_ProgramHalfWord(uint32_t addr,uint16_t data)326 FMC_STATE_T FMC_ProgramHalfWord(uint32_t addr, uint16_t data)
327 {
328 FMC_STATE_T state;
329
330 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
331
332 if (state == FMC_STATE_COMPLETE)
333 {
334 FMC->CTRL2_B.PG = BIT_SET;
335
336 *(__IO uint16_t*)addr = data;
337
338 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
339
340 FMC->CTRL2_B.PG = BIT_RESET;
341 }
342
343 return state;
344 }
345
346 /*!
347 * @brief Unlocks the option bytes block access
348 *
349 * @param None
350 *
351 * @retval None
352 */
FMC_UnlockOptionByte(void)353 void FMC_UnlockOptionByte(void)
354 {
355 FMC->OBKEY = FMC_OB_KEY_1;
356 FMC->OBKEY = FMC_OB_KEY_2;
357 }
358
359 /*!
360 * @brief Locks the option bytes block access
361 *
362 * @param None
363 *
364 * @retval None
365 */
FMC_LockOptionByte(void)366 void FMC_LockOptionByte(void)
367 {
368 FMC->CTRL2_B.OBWEN = BIT_RESET;
369 }
370
371 /*!
372 * @brief Launch the option byte loading
373 *
374 * @param None
375 *
376 * @retval None
377 */
FMC_LaunchOptionByte(void)378 void FMC_LaunchOptionByte(void)
379 {
380 FMC->CTRL2_B.OBLOAD = BIT_SET;
381 }
382
383 /*!
384 * @brief Erase the flash option bytes
385 *
386 * @param None
387 *
388 * @retval Returns the flash state.It can be one of value:
389 * @arg FMC_STATE_COMPLETE
390 * @arg FMC_STATE_PG_ERR
391 * @arg FMC_STATE_WRP_ERR
392 * @arg FMC_STATE_TIMEOUT
393 */
FMC_EraseOptionByte(void)394 FMC_STATE_T FMC_EraseOptionByte(void)
395 {
396 uint16_t rpKey;
397 FMC_STATE_T state;
398
399 rpKey = FMC->OBCS_B.READPROT ? 0 : FMC_RP_KEY;
400
401 state = FMC_WaitForReady(FMC_DELAY_ERASE);
402
403 if (state == FMC_STATE_COMPLETE)
404 {
405 FMC->OBKEY = FMC_KEY_1;
406 FMC->OBKEY = FMC_KEY_2;
407
408 FMC->CTRL2_B.OBE = BIT_SET;
409 FMC->CTRL2_B.STA = BIT_SET;
410
411 state = FMC_WaitForReady(FMC_DELAY_ERASE);
412
413 if (state == FMC_STATE_COMPLETE)
414 {
415 FMC->CTRL2_B.OBE = BIT_RESET;
416
417 FMC->CTRL2_B.OBP = BIT_SET;
418
419 OB->READPROT = rpKey;
420
421 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
422
423 if (state != FMC_STATE_TIMEOUT)
424 {
425 FMC->CTRL2_B.OBP = BIT_RESET;
426 }
427 }
428 else if (state != FMC_STATE_TIMEOUT)
429 {
430 FMC->CTRL2_B.OBE = BIT_RESET;
431 }
432 }
433
434 return state;
435 }
436
437 /*!
438 * @brief Enable the specified page write protection
439 *
440 * @param page: Specifies the address of the pages to be write protected
441 * This parameter can be any combination of the flowing values:
442 * @arg FMC_WRP_PAGE_0_1 ... FMC_WRP_PAGE_60_61
443 * @arg FMC_WRP_PAGE_ALL
444 *
445 * @retval Returns the flash state.It can be one of value:
446 * @arg FMC_STATE_COMPLETE
447 * @arg FMC_STATE_PG_ERR
448 * @arg FMC_STATE_WRP_ERR
449 * @arg FMC_STATE_TIMEOU
450 */
FMC_EnableWriteProtection(uint32_t page)451 FMC_STATE_T FMC_EnableWriteProtection(uint32_t page)
452 {
453 uint8_t i;
454 uint16_t temp;
455 __IO uint16_t* WRPT;
456 FMC_STATE_T state;
457
458 WRPT = &OB->WRTPROT0;
459
460 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
461
462 if (state == FMC_STATE_COMPLETE)
463 {
464 FMC->OBKEY = FMC_KEY_1;
465 FMC->OBKEY = FMC_KEY_2;
466
467 FMC->CTRL2_B.OBP = BIT_SET;
468
469 for (i = 0; i < 4; i++)
470 {
471 temp = (uint16_t)~(page & 0xff);
472
473 if ((temp != 0xff) && (state == FMC_STATE_COMPLETE))
474 {
475 WRPT[i] = temp;
476
477 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
478 }
479
480 page >>= 8;
481 }
482
483 if (state != FMC_STATE_TIMEOUT)
484 {
485 FMC->CTRL2_B.OBP = BIT_RESET;
486 }
487 }
488
489 return state;
490 }
491
492 /*!
493 * @brief Read out protection configuration.
494 *
495 * @param rdp: specifies the read protection level
496 * This parameter can be any combination of the flowing values:
497 * @arg FMC_RDP_LEVEL_0
498 * @arg FMC_RDP_LEVEL_1
499 *
500 * @retval Returns the flash state.It can be one of value:
501 * @arg FMC_STATE_COMPLETE
502 * @arg FMC_STATE_PG_ERR
503 * @arg FMC_STATE_WRP_ERR
504 * @arg FMC_STATE_TIMEOU
505 */
FMC_ConfigReadOutProtection(FMC_RDP_T rdp)506 FMC_STATE_T FMC_ConfigReadOutProtection(FMC_RDP_T rdp)
507 {
508 FMC_STATE_T state;
509
510 state = FMC_WaitForReady(FMC_DELAY_ERASE);
511
512 if (state == FMC_STATE_COMPLETE)
513 {
514 FMC->OBKEY = FMC_KEY_1;
515 FMC->OBKEY = FMC_KEY_2;
516
517 FMC->CTRL2_B.OBE = BIT_SET;
518 FMC->CTRL2_B.STA = BIT_SET;
519
520 state = FMC_WaitForReady(FMC_DELAY_ERASE);
521
522 if (state == FMC_STATE_COMPLETE)
523 {
524 FMC->CTRL2_B.OBE = BIT_RESET;
525
526 FMC->CTRL2_B.OBP = BIT_SET;
527
528 OB->READPROT = rdp;
529
530 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
531
532 if (state != FMC_STATE_TIMEOUT)
533 {
534 FMC->CTRL2_B.OBP = BIT_RESET;
535 }
536 }
537 else if (state != FMC_STATE_TIMEOUT)
538 {
539 FMC->CTRL2_B.OBE = BIT_SET;
540 }
541 }
542
543 return state;
544 }
545
546 /*!
547 * @brief User option byte configuration
548 *
549 * @param userConfig: Pointer to a FMC_UserConfig_T structure that
550 * contains the configuration information for User option byte
551 *
552 * @retval Returns the flash state.It can be one of value:
553 * @arg FMC_STATE_COMPLETE
554 * @arg FMC_STATE_PG_ERR
555 * @arg FMC_STATE_WRP_ERR
556 * @arg FMC_STATE_TIMEOU
557 */
FMC_ConfigOptionByteUser(FMC_UserConfig_T * userConfig)558 FMC_STATE_T FMC_ConfigOptionByteUser(FMC_UserConfig_T* userConfig)
559 {
560 FMC_STATE_T state;
561 uint16_t temp;
562
563 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
564
565 if (state == FMC_STATE_COMPLETE)
566 {
567 FMC->OBKEY = FMC_OB_KEY_1;
568 FMC->OBKEY = FMC_OB_KEY_2;
569
570 FMC->CTRL2_B.OBP = BIT_SET;
571
572 temp = (uint32_t)userConfig->iwdtSw | \
573 (uint32_t)userConfig->stopce | \
574 (uint32_t)userConfig->stdbyce | 0xF8;
575
576 OB->USER = temp;
577
578 state = FMC_WaitForReady(FMC_DELAY_PROGRAM);
579
580 if (state != FMC_STATE_TIMEOUT)
581 {
582 FMC->CTRL2_B.OBP = BIT_RESET;
583 }
584 }
585
586 return state;
587 }
588
589 /*!
590 * @brief Enable the BOOT1 option bit
591 *
592 * @param None
593 *
594 * @retval Returns the flash state.It can be one of value:
595 * @arg FMC_STATE_COMPLETE
596 * @arg FMC_STATE_PG_ERR
597 * @arg FMC_STATE_WRP_ERR
598 * @arg FMC_STATE_TIMEOU
599 */
FMC_EnableOptionByteBOOT(void)600 FMC_STATE_T FMC_EnableOptionByteBOOT(void)
601 {
602 FMC_STATE_T state;
603
604 state = FMC_WaitForReady(FMC_DELAY_ERASE);
605
606 if (state == FMC_STATE_COMPLETE)
607 {
608 FMC->CTRL2_B.OBP = BIT_SET;
609
610 OB->USER_B.BOT1 = BIT_SET;
611
612 state = FMC_WaitForReady(FMC_DELAY_ERASE);
613
614 if (state != FMC_STATE_TIMEOUT)
615 {
616 FMC->CTRL2_B.OBP = BIT_RESET;
617 }
618 }
619
620 return state;
621 }
622
623 /*!
624 * @brief Disable the BOOT1 option bit
625 *
626 * @param None
627 *
628 * @retval Returns the flash state.It can be one of value:
629 * @arg FMC_STATE_COMPLETE
630 * @arg FMC_STATE_PG_ERR
631 * @arg FMC_STATE_WRP_ERR
632 * @arg FMC_STATE_TIMEOU
633 */
FMC_DisableOptionByteBOOT(void)634 FMC_STATE_T FMC_DisableOptionByteBOOT(void)
635 {
636 FMC_STATE_T state;
637
638 state = FMC_WaitForReady(FMC_DELAY_ERASE);
639
640 if (state == FMC_STATE_COMPLETE)
641 {
642 FMC->CTRL2_B.OBP = BIT_SET;
643
644 OB->USER_B.BOT1 = BIT_RESET;
645
646 state = FMC_WaitForReady(FMC_DELAY_ERASE);
647
648 if (state != FMC_STATE_TIMEOUT)
649 {
650 FMC->CTRL2_B.OBP = BIT_RESET;
651 }
652 }
653
654 return state;
655
656 }
657
658 /*!
659 * @brief Enable the analogue monitoring on VDDA Power source
660 *
661 * @param None
662 *
663 * @retval Returns the flash state.It can be one of value:
664 * @arg FMC_STATE_COMPLETE
665 * @arg FMC_STATE_PG_ERR
666 * @arg FMC_STATE_WRP_ERR
667 * @arg FMC_STATE_TIMEOU
668 */
FMC_EnableOptionByteVDDA(void)669 FMC_STATE_T FMC_EnableOptionByteVDDA(void)
670 {
671 FMC_STATE_T state;
672
673 state = FMC_WaitForReady(FMC_DELAY_ERASE);
674
675 if (state == FMC_STATE_COMPLETE)
676 {
677 FMC->CTRL2_B.OBP = BIT_SET;
678
679 OB->USER_B.VDDAMON = BIT_SET;
680
681 state = FMC_WaitForReady(FMC_DELAY_ERASE);
682
683 if (state != FMC_STATE_TIMEOUT)
684 {
685 FMC->CTRL2_B.OBP = BIT_RESET;
686 }
687 }
688
689 return state;
690
691 }
692
693 /*!
694 * @brief Disable the analogue monitoring on VDDA Power source
695 *
696 * @param None
697 *
698 * @retval Returns the flash state.It can be one of value:
699 * @arg FMC_STATE_COMPLETE
700 * @arg FMC_STATE_PG_ERR
701 * @arg FMC_STATE_WRP_ERR
702 * @arg FMC_STATE_TIMEOU
703 */
FMC_DisableOptionByteVDDA(void)704 FMC_STATE_T FMC_DisableOptionByteVDDA(void)
705 {
706 FMC_STATE_T state;
707
708 state = FMC_WaitForReady(FMC_DELAY_ERASE);
709
710 if (state == FMC_STATE_COMPLETE)
711 {
712 FMC->CTRL2_B.OBP = BIT_SET;
713
714 OB->USER_B.VDDAMON = BIT_RESET;
715
716 state = FMC_WaitForReady(FMC_DELAY_ERASE);
717
718 if (state != FMC_STATE_TIMEOUT)
719 {
720 FMC->CTRL2_B.OBP = BIT_RESET;
721 }
722 }
723
724 return state;
725
726 }
727
728 /*!
729 * @brief Enable the SRAM parity
730 *
731 * @param None
732 *
733 * @retval Returns the flash state.It can be one of value:
734 * @arg FMC_STATE_COMPLETE
735 * @arg FMC_STATE_PG_ERR
736 * @arg FMC_STATE_WRP_ERR
737 * @arg FMC_STATE_TIMEOU
738 */
FMC_EnableOptionByteSRAMParity(void)739 FMC_STATE_T FMC_EnableOptionByteSRAMParity(void)
740 {
741 FMC_STATE_T state;
742
743 state = FMC_WaitForReady(FMC_DELAY_ERASE);
744
745 if (state == FMC_STATE_COMPLETE)
746 {
747 FMC->CTRL2_B.OBP = BIT_SET;
748
749 OB->USER_B.RPC = BIT_SET;
750
751 state = FMC_WaitForReady(FMC_DELAY_ERASE);
752
753 if (state != FMC_STATE_TIMEOUT)
754 {
755 FMC->CTRL2_B.OBP = BIT_RESET;
756 }
757 }
758
759 return state;
760
761 }
762
763 /*!
764 * @brief Disable the SRAM parity
765 *
766 * @param None
767 *
768 * @retval Returns the flash state.It can be one of value:
769 * @arg FMC_STATE_COMPLETE
770 * @arg FMC_STATE_PG_ERR
771 * @arg FMC_STATE_WRP_ERR
772 * @arg FMC_STATE_TIMEOU
773 */
FMC_DisableOptionByteSRAMParity(void)774 FMC_STATE_T FMC_DisableOptionByteSRAMParity(void)
775 {
776 FMC_STATE_T state;
777
778 state = FMC_WaitForReady(FMC_DELAY_ERASE);
779
780 if (state == FMC_STATE_COMPLETE)
781 {
782 FMC->CTRL2_B.OBP = BIT_SET;
783
784 OB->USER_B.RPC = BIT_RESET;
785
786 state = FMC_WaitForReady(FMC_DELAY_ERASE);
787
788 if (state != FMC_STATE_TIMEOUT)
789 {
790 FMC->CTRL2_B.OBP = BIT_RESET;
791 }
792 }
793
794 return state;
795
796 }
797 /*!
798 * @brief Programs the FMC User Option Byte: WDT, STOP, STDBY,
799 * BOOT1 and VDDA ANALOG monitoring
800 *
801 * @param ob_user: Selects all user option bytes
802 * This parameter is a combination of the following values:
803 * @arg FMC_OB_IWDT_HW / FMC_OB_IWDT_SW
804 * @arg FMC_OB_STOP_RESET / FMC_OB_STOP_NRST
805 * @arg FMC_OB_STDBY_RESET / FMC_OB_STDBY_NRST
806 * @arg FMC_OB_BOOT0_RESET / FMC_OB_BOOT0_SET
807 * @arg FMC_OB_BOOT1_RESET / FMC_OB_BOOT1_SET
808 * @arg FMC_OB_VDDA_ANALOG_OFF / FMC_OB_VDDA_ANALOG_ON
809 * @arg FMC_OB_SRAM_PARITY_SET / FMC_OB_SRAM_PARITY_RESET
810 * @arg FMC_OB_BOOT0_SW / FMC_OB_BOOT0_HW
811 *
812 * @retval Returns the flash state.It can be one of value:
813 * @arg FMC_STATE_COMPLETE
814 * @arg FMC_STATE_PG_ERR
815 * @arg FMC_STATE_WRP_ERR
816 * @arg FMC_STATE_TIMEOU
817 */
FMC_WriteOptionByteUser(uint8_t ob_user)818 FMC_STATE_T FMC_WriteOptionByteUser(uint8_t ob_user)
819 {
820 FMC_STATE_T state;
821
822 state = FMC_WaitForReady(FMC_DELAY_ERASE);
823
824 if (state == FMC_STATE_COMPLETE)
825 {
826 FMC->CTRL2_B.OBP = BIT_SET;
827
828 OB->USER = ob_user;
829
830 state = FMC_WaitForReady(FMC_DELAY_ERASE);
831
832 if (state != FMC_STATE_TIMEOUT)
833 {
834 FMC->CTRL2_B.OBP = BIT_RESET;
835 }
836 }
837
838 return state;
839
840 }
841
842 /*!
843 * @brief Programs a half word at a specified Option Byte Data address
844 *
845 * @param addr: specifies the address to be programmed.
846 * This parameter can be 0x1FFFF804 or 0x1FFFF806.
847 * @param data: specifies the data to be programmed.
848 *
849 * @retval Returns the flash state.It can be one of value:
850 * @arg FMC_STATE_COMPLETE
851 * @arg FMC_STATE_PG_ERR
852 * @arg FMC_STATE_WRP_ERR
853 * @arg FMC_STATE_TIMEOU
854 */
FMC_ProgramOptionByteData(uint32_t addr,uint8_t data)855 FMC_STATE_T FMC_ProgramOptionByteData(uint32_t addr, uint8_t data)
856 {
857 FMC_STATE_T state;
858
859 state = FMC_WaitForReady(FMC_DELAY_ERASE);
860
861 if (state == FMC_STATE_COMPLETE)
862 {
863 FMC->CTRL2_B.OBP = BIT_SET;
864
865 *(__IO uint16_t*)addr = data;
866
867 state = FMC_WaitForReady(FMC_DELAY_ERASE);
868
869 if (state != FMC_STATE_TIMEOUT)
870 {
871 FMC->CTRL2_B.OBP = BIT_RESET;
872 }
873 }
874
875 return state;
876
877 }
878
879 /*!
880 * @brief Returns the Flash User Option Bytes values
881 *
882 * @param None
883 *
884 * @retval The flash User Option Bytes
885 */
FMC_ReadOptionByteUser(void)886 uint8_t FMC_ReadOptionByteUser(void)
887 {
888 return (uint8_t)(FMC->OBCS >> 8);
889 }
890
891 /*!
892 * @brief Returns the flash Write Protection Option Bytes value:
893 *
894 * @param None
895 *
896 * @retval The Flash Write Protection Option Bytes value:
897 */
FMC_ReadOptionByteWriteProtection(void)898 uint32_t FMC_ReadOptionByteWriteProtection(void)
899 {
900 return (uint32_t)(FMC->WRTPROT);
901 }
902
903 /*!
904 * @brief Checks whether the Flash Read Protection Status is set or not
905 *
906 * @param None
907 *
908 * @retval Flash ReadOut Protection Status(SET or RESET)
909 */
FMC_GetReadProtectionStatus(void)910 uint8_t FMC_GetReadProtectionStatus(void)
911 {
912 if (FMC->OBCS_B.READPROT)
913 {
914 return SET;
915 }
916
917 return RESET;
918 }
919 /*!
920 * @brief Enable the specified flash interrupts
921 *
922 * @param interrupt: Specifies the flash interrupt sources
923 * The parameter can be combination of following values:
924 * @arg FMC_INT_ERROR: Error interruption
925 * @arg FMC_INT_COMPLETE: operation complete interruption
926 *
927 * @retval None
928 */
FMC_EnableInterrupt(uint32_t interrupt)929 void FMC_EnableInterrupt(uint32_t interrupt)
930 {
931 FMC->CTRL2 |= interrupt;
932 }
933
934 /*!
935 * @brief Disable the specified flash interrupts
936 *
937 * @param interrupt: Specifies the flash interrupt sources
938 * The parameter can be combination of following values:
939 * @arg FMC_INT_ERROR: Error interruption
940 * @arg FMC_INT_COMPLETE: operation complete interruption
941 *
942 * @retval None
943 */
FMC_DisableInterrupt(uint32_t interrupt)944 void FMC_DisableInterrupt(uint32_t interrupt)
945 {
946 FMC->CTRL2 &= ~interrupt;
947 }
948
949 /*!
950 * @brief Checks whether the specified flash flag is set or not
951 *
952
953 * @param flag: Specifies the flash flag to check
954 * The parameter can be one of following values:
955 * @arg FMC_FLAG_BUSY: Busy flag
956 * @arg FMC_FLAG_PE: Program error flag
957 * @arg FMC_FLAG_WPE: Write protection flag
958 * @arg FMC_FLAG_OC: Operation complete flag
959 *
960 * @retval None
961 */
FMC_ReadStatusFlag(FMC_FLAG_T flag)962 uint8_t FMC_ReadStatusFlag(FMC_FLAG_T flag)
963 {
964 uint8_t status;
965
966 if (flag & 0xff)
967 {
968 status = FMC->STS & flag;
969 }
970 else
971 {
972 status = FMC->OBCS & flag;
973 }
974
975 if (status)
976 {
977 return SET;
978 }
979
980 return RESET;
981 }
982
983 /*!
984 * @brief Clear the specified flash flag
985 *
986 * @param flag: Specifies the flash flag to clear
987 * This parameter can be any combination of the following values:
988 * @arg FMC_FLAG_BUSY: Busy flag
989 * @arg FMC_FLAG_PE: Program error flag
990 * @arg FMC_FLAG_WPE: Write protection error flag
991 * @arg FMC_FLAG_OC: Operation complete flag
992 *
993 * @retval None
994 */
FMC_ClearStatusFlag(uint8_t flag)995 void FMC_ClearStatusFlag(uint8_t flag)
996 {
997 if (flag & 0xff)
998 {
999 FMC->STS = flag;
1000 }
1001 }
1002
1003 /**@} end of group FMC_Functions*/
1004 /**@} end of group FMC_Driver*/
1005 /**@} end of group APM32F0xx_StdPeriphDriver*/
1006