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