1 /********************************** (C) COPYRIGHT  *******************************
2  * File Name          : ch32v10x_flash.c
3  * Author             : WCH
4  * Version            : V1.0.0
5  * Date               : 2020/04/30
6  * Description        : This file provides all the FLASH firmware functions.
7  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
8  * SPDX-License-Identifier: Apache-2.0
9  ***************************************************************************************/
10 #include "ch32v10x_flash.h"
11 
12 /* Flash Access Control Register bits */
13 #define ACR_LATENCY_Mask           ((uint32_t)0x00000038)
14 #define ACR_HLFCYA_Mask            ((uint32_t)0xFFFFFFF7)
15 #define ACR_PRFTBE_Mask            ((uint32_t)0xFFFFFFEF)
16 
17 /* Flash Access Control Register bits */
18 #define ACR_PRFTBS_Mask            ((uint32_t)0x00000020)
19 
20 /* Flash Control Register bits */
21 #define CR_PG_Set                  ((uint32_t)0x00000001)
22 #define CR_PG_Reset                ((uint32_t)0x00001FFE)
23 #define CR_PER_Set                 ((uint32_t)0x00000002)
24 #define CR_PER_Reset               ((uint32_t)0x00001FFD)
25 #define CR_MER_Set                 ((uint32_t)0x00000004)
26 #define CR_MER_Reset               ((uint32_t)0x00001FFB)
27 #define CR_OPTPG_Set               ((uint32_t)0x00000010)
28 #define CR_OPTPG_Reset             ((uint32_t)0x00001FEF)
29 #define CR_OPTER_Set               ((uint32_t)0x00000020)
30 #define CR_OPTER_Reset             ((uint32_t)0x00001FDF)
31 #define CR_STRT_Set                ((uint32_t)0x00000040)
32 #define CR_LOCK_Set                ((uint32_t)0x00000080)
33 #define CR_PAGE_PG                 ((uint32_t)0x00010000)
34 #define CR_PAGE_ER                 ((uint32_t)0x00020000)
35 #define CR_BUF_LOAD                ((uint32_t)0x00040000)
36 #define CR_BUF_RST                 ((uint32_t)0x00080000)
37 
38 /* FLASH Status Register bits */
39 #define SR_BSY                     ((uint32_t)0x00000001)
40 #define SR_PGERR                   ((uint32_t)0x00000004)
41 #define SR_WRPRTERR                ((uint32_t)0x00000010)
42 #define SR_EOP                     ((uint32_t)0x00000020)
43 
44 /* FLASH Mask */
45 #define RDPRT_Mask                 ((uint32_t)0x00000002)
46 #define WRP0_Mask                  ((uint32_t)0x000000FF)
47 #define WRP1_Mask                  ((uint32_t)0x0000FF00)
48 #define WRP2_Mask                  ((uint32_t)0x00FF0000)
49 #define WRP3_Mask                  ((uint32_t)0xFF000000)
50 #define OB_USER_BFB2               ((uint16_t)0x0008)
51 
52 /* FLASH Keys */
53 #define RDP_Key                    ((uint16_t)0x00A5)
54 #define FLASH_KEY1                 ((uint32_t)0x45670123)
55 #define FLASH_KEY2                 ((uint32_t)0xCDEF89AB)
56 
57 /* FLASH BANK address */
58 #define FLASH_BANK1_END_ADDRESS    ((uint32_t)0x807FFFF)
59 
60 /* Delay definition */
61 #define EraseTimeout               ((uint32_t)0x000B0000)
62 #define ProgramTimeout             ((uint32_t)0x00002000)
63 
64 /* Flash Program Vaild Address */
65 #define ValidAddrStart             (FLASH_BASE)
66 #define ValidAddrEnd               (FLASH_BASE + 0x10000)
67 
68 /********************************************************************************
69   * @fn            FLASH_SetLatency
70   *
71   * @brief         Sets the code latency value.
72   *
73   * @param         FLASH_Latency - specifies the FLASH Latency value.
74   *                    FLASH_Latency_0 - FLASH Zero Latency cycle
75   *                    FLASH_Latency_1 - FLASH One Latency cycle
76   *                    FLASH_Latency_2 - FLASH Two Latency cycles
77   *
78   * @return         None
79   */
FLASH_SetLatency(uint32_t FLASH_Latency)80 void FLASH_SetLatency(uint32_t FLASH_Latency)
81 {
82     uint32_t tmpreg = 0;
83 
84     tmpreg = FLASH->ACTLR;
85     tmpreg &= ACR_LATENCY_Mask;
86     tmpreg |= FLASH_Latency;
87     FLASH->ACTLR = tmpreg;
88 }
89 
90 /********************************************************************************
91  * @fn            FLASH_HalfCycleAccessCmd
92  *
93  * @brief          Enables or disables the Half cycle flash access.
94  *
95  * @param          FLASH_HalfCycleAccess - specifies the FLASH Half cycle Access mode.
96  *                   FLASH_HalfCycleAccess_Enable - FLASH Half Cycle Enable
97  *                   FLASH_HalfCycleAccess_Disable - FLASH Half Cycle Disable
98  *
99  * @return         None
100  */
FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)101 void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)
102 {
103     FLASH->ACTLR &= ACR_HLFCYA_Mask;
104     FLASH->ACTLR |= FLASH_HalfCycleAccess;
105 }
106 
107 /********************************************************************************
108  * @fn             FLASH_PrefetchBufferCmd
109  *
110  * @brief          Enables or disables the Prefetch Buffer.
111  *
112  * @param          FLASH_PrefetchBuffer - specifies the Prefetch buffer status.
113  *                   FLASH_PrefetchBuffer_Enable - FLASH Prefetch Buffer Enable
114  *                   FLASH_PrefetchBuffer_Disable - FLASH Prefetch Buffer Disable
115  *
116  * @return         None
117  */
FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)118 void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)
119 {
120     FLASH->ACTLR &= ACR_PRFTBE_Mask;
121     FLASH->ACTLR |= FLASH_PrefetchBuffer;
122 }
123 
124 /********************************************************************************
125  * @fn             FLASH_Unlock
126  *
127  * @brief          Unlocks the FLASH Program Erase Controller.
128  *
129  * @return         None
130  */
FLASH_Unlock(void)131 void FLASH_Unlock(void)
132 {
133     /* Authorize the FPEC of Bank1 Access */
134     FLASH->KEYR = FLASH_KEY1;
135     FLASH->KEYR = FLASH_KEY2;
136 }
137 
138 /********************************************************************************
139  * @fn             FLASH_UnlockBank1
140  *
141  * @brief          Unlocks the FLASH Bank1 Program Erase Controller.
142  *                 equivalent to FLASH_Unlock function.
143  *
144  * @return         None
145  */
FLASH_UnlockBank1(void)146 void FLASH_UnlockBank1(void)
147 {
148     FLASH->KEYR = FLASH_KEY1;
149     FLASH->KEYR = FLASH_KEY2;
150 }
151 
152 /********************************************************************************
153  * @fn             FLASH_Lock
154  *
155  * @brief          Locks the FLASH Program Erase Controller.
156  *
157  * @return         None
158  */
FLASH_Lock(void)159 void FLASH_Lock(void)
160 {
161     FLASH->CTLR |= CR_LOCK_Set;
162 }
163 
164 /********************************************************************************
165  * @fn             FLASH_LockBank1
166  *
167  * @brief          Locks the FLASH Bank1 Program Erase Controller.
168  *
169  * @return         None
170  */
FLASH_LockBank1(void)171 void FLASH_LockBank1(void)
172 {
173     FLASH->CTLR |= CR_LOCK_Set;
174 }
175 
176 /********************************************************************************
177  * @fn             FLASH_ErasePage
178  *
179  * @brief          Erases a specified FLASH page.
180  *
181  * @param          Page_Address - The page address to be erased.
182  *
183  * @return         FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
184  *                 FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
185  */
FLASH_ErasePage(uint32_t Page_Address)186 FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
187 {
188     FLASH_Status status = FLASH_COMPLETE;
189 
190     status = FLASH_WaitForLastOperation(EraseTimeout);
191 
192     if(status == FLASH_COMPLETE)
193     {
194         FLASH->CTLR |= CR_PER_Set;
195         FLASH->ADDR = Page_Address;
196         FLASH->CTLR |= CR_STRT_Set;
197 
198         status = FLASH_WaitForLastOperation(EraseTimeout);
199 
200         FLASH->CTLR &= CR_PER_Reset;
201     }
202 
203     *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Page_Address & 0xFFFFFFFC) ^ 0x00001000);
204 
205     return status;
206 }
207 
208 /********************************************************************************
209  * @fn             FLASH_EraseAllPages
210  *
211  * @brief          Erases all FLASH pages.
212  *
213  * @return         FLASH Status - The returned value can be:FLASH_BUSY, FLASH_ERROR_PG,
214  *                 FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
215  */
FLASH_EraseAllPages(void)216 FLASH_Status FLASH_EraseAllPages(void)
217 {
218     FLASH_Status status = FLASH_COMPLETE;
219 
220     status = FLASH_WaitForLastOperation(EraseTimeout);
221     if(status == FLASH_COMPLETE)
222     {
223         FLASH->CTLR |= CR_MER_Set;
224         FLASH->CTLR |= CR_STRT_Set;
225 
226         status = FLASH_WaitForLastOperation(EraseTimeout);
227 
228         FLASH->CTLR &= CR_MER_Reset;
229     }
230 
231     return status;
232 }
233 
234 /********************************************************************************
235  * @fn             FLASH_EraseAllBank1Pages
236  *
237  * @brief          Erases all Bank1 FLASH pages.
238  *
239  * @return         FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
240  *                 FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
241  */
FLASH_EraseAllBank1Pages(void)242 FLASH_Status FLASH_EraseAllBank1Pages(void)
243 {
244     FLASH_Status status = FLASH_COMPLETE;
245     status = FLASH_WaitForLastBank1Operation(EraseTimeout);
246 
247     if(status == FLASH_COMPLETE)
248     {
249         FLASH->CTLR |= CR_MER_Set;
250         FLASH->CTLR |= CR_STRT_Set;
251 
252         status = FLASH_WaitForLastBank1Operation(EraseTimeout);
253 
254         FLASH->CTLR &= CR_MER_Reset;
255     }
256     return status;
257 }
258 
259 /********************************************************************************
260  * @fn             FLASH_EraseOptionBytes
261  *
262  * @brief          Erases the FLASH option bytes.
263  *
264  * @return         FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
265  *                 FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
266  */
FLASH_EraseOptionBytes(void)267 FLASH_Status FLASH_EraseOptionBytes(void)
268 {
269     uint16_t rdptmp = RDP_Key;
270 
271     FLASH_Status status = FLASH_COMPLETE;
272     if(FLASH_GetReadOutProtectionStatus() != RESET)
273     {
274         rdptmp = 0x00;
275     }
276     status = FLASH_WaitForLastOperation(EraseTimeout);
277     if(status == FLASH_COMPLETE)
278     {
279         FLASH->OBKEYR = FLASH_KEY1;
280         FLASH->OBKEYR = FLASH_KEY2;
281 
282         FLASH->CTLR |= CR_OPTER_Set;
283         FLASH->CTLR |= CR_STRT_Set;
284         status = FLASH_WaitForLastOperation(EraseTimeout);
285 
286         if(status == FLASH_COMPLETE)
287         {
288             FLASH->CTLR &= CR_OPTER_Reset;
289             FLASH->CTLR |= CR_OPTPG_Set;
290             OB->RDPR = (uint16_t)rdptmp;
291             status = FLASH_WaitForLastOperation(ProgramTimeout);
292 
293             if(status != FLASH_TIMEOUT)
294             {
295                 FLASH->CTLR &= CR_OPTPG_Reset;
296             }
297         }
298         else
299         {
300             if(status != FLASH_TIMEOUT)
301             {
302                 FLASH->CTLR &= CR_OPTPG_Reset;
303             }
304         }
305     }
306     return status;
307 }
308 
309 /*********************************************************************
310  * @fn         FLASH_ProgramWord
311  *
312  * @brief       Programs a word at a specified address.
313  *
314  * @param       Address - specifies the address to be programmed.
315  *              Data - specifies the data to be programmed.
316  *
317  * @return       FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
318  *              FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
319  */
FLASH_ProgramWord(uint32_t Address,uint32_t Data)320 FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
321 {
322     FLASH_Status  status = FLASH_COMPLETE;
323     __IO uint32_t tmp = 0;
324 
325     status = FLASH_WaitForLastOperation(ProgramTimeout);
326 
327     if(status == FLASH_COMPLETE)
328     {
329         FLASH->CTLR |= CR_PG_Set;
330 
331         *(__IO uint16_t *)Address = (uint16_t)Data;
332         status = FLASH_WaitForLastOperation(ProgramTimeout);
333 
334         if(status == FLASH_COMPLETE)
335         {
336             tmp = Address + 2;
337             *(__IO uint16_t *)tmp = Data >> 16;
338             status = FLASH_WaitForLastOperation(ProgramTimeout);
339             FLASH->CTLR &= CR_PG_Reset;
340         }
341         else
342         {
343             FLASH->CTLR &= CR_PG_Reset;
344         }
345     }
346 
347     *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Address & 0xFFFFFFFC) ^ 0x00001000);
348 
349     return status;
350 }
351 
352 /*********************************************************************
353  * @fn         FLASH_ProgramHalfWord
354  *
355  * @brief       Programs a half word at a specified address.
356  *
357  * @param       Address - specifies the address to be programmed.
358  *              Data - specifies the data to be programmed.
359  *
360  * @return      FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
361  *             FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
362  */
FLASH_ProgramHalfWord(uint32_t Address,uint16_t Data)363 FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
364 {
365     FLASH_Status status = FLASH_COMPLETE;
366 
367     status = FLASH_WaitForLastOperation(ProgramTimeout);
368     if(status == FLASH_COMPLETE)
369     {
370         FLASH->CTLR |= CR_PG_Set;
371         *(__IO uint16_t *)Address = Data;
372         status = FLASH_WaitForLastOperation(ProgramTimeout);
373         FLASH->CTLR &= CR_PG_Reset;
374     }
375 
376     *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Address & 0xFFFFFFFC) ^ 0x00001000);
377 
378     return status;
379 }
380 
381 /*********************************************************************
382  * @fn        FLASH_ProgramOptionByteData
383  *
384  * @brief     Programs a half word at a specified Option Byte Data address.
385  *
386  * @param     Address - specifies the address to be programmed.
387  *            Data - specifies the data to be programmed.
388  *
389  * @return    FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
390  *           FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
391  */
FLASH_ProgramOptionByteData(uint32_t Address,uint8_t Data)392 FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)
393 {
394     FLASH_Status status = FLASH_COMPLETE;
395     status = FLASH_WaitForLastOperation(ProgramTimeout);
396     if(status == FLASH_COMPLETE)
397     {
398         FLASH->OBKEYR = FLASH_KEY1;
399         FLASH->OBKEYR = FLASH_KEY2;
400         FLASH->CTLR |= CR_OPTPG_Set;
401         *(__IO uint16_t *)Address = Data;
402         status = FLASH_WaitForLastOperation(ProgramTimeout);
403         if(status != FLASH_TIMEOUT)
404         {
405             FLASH->CTLR &= CR_OPTPG_Reset;
406         }
407     }
408 
409     *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Address & 0xFFFFFFFC) ^ 0x00001000);
410 
411     return status;
412 }
413 
414 /*********************************************************************
415  * @fn      FLASH_EnableWriteProtection
416  *
417  * @brief   Write protects the desired sectors
418  *
419  * @param   FLASH_Sectors - specifies the address of the pages to be write protected.
420  *
421  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
422  *        FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
423  */
FLASH_EnableWriteProtection(uint32_t FLASH_Pages)424 FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
425 {
426     uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
427 
428     FLASH_Status status = FLASH_COMPLETE;
429 
430     FLASH_Pages = (uint32_t)(~FLASH_Pages);
431     WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
432     WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
433     WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
434     WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);
435 
436     status = FLASH_WaitForLastOperation(ProgramTimeout);
437 
438     if(status == FLASH_COMPLETE)
439     {
440         FLASH->OBKEYR = FLASH_KEY1;
441         FLASH->OBKEYR = FLASH_KEY2;
442         FLASH->CTLR |= CR_OPTPG_Set;
443         if(WRP0_Data != 0xFF)
444         {
445             OB->WRPR0 = WRP0_Data;
446             status = FLASH_WaitForLastOperation(ProgramTimeout);
447         }
448         if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
449         {
450             OB->WRPR1 = WRP1_Data;
451             status = FLASH_WaitForLastOperation(ProgramTimeout);
452         }
453         if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))
454         {
455             OB->WRPR2 = WRP2_Data;
456             status = FLASH_WaitForLastOperation(ProgramTimeout);
457         }
458 
459         if((status == FLASH_COMPLETE) && (WRP3_Data != 0xFF))
460         {
461             OB->WRPR3 = WRP3_Data;
462             status = FLASH_WaitForLastOperation(ProgramTimeout);
463         }
464 
465         if(status != FLASH_TIMEOUT)
466         {
467             FLASH->CTLR &= CR_OPTPG_Reset;
468         }
469     }
470     return status;
471 }
472 
473 /*********************************************************************
474  * @fn      FLASH_ReadOutProtection
475  *
476  * @brief   Enables or disables the read out protection.
477  *
478  * @param   Newstate - new state of the ReadOut Protection(ENABLE or DISABLE).
479  *
480  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
481  *        FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
482  */
FLASH_ReadOutProtection(FunctionalState NewState)483 FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
484 {
485     FLASH_Status status = FLASH_COMPLETE;
486     status = FLASH_WaitForLastOperation(EraseTimeout);
487     if(status == FLASH_COMPLETE)
488     {
489         FLASH->OBKEYR = FLASH_KEY1;
490         FLASH->OBKEYR = FLASH_KEY2;
491         FLASH->CTLR |= CR_OPTER_Set;
492         FLASH->CTLR |= CR_STRT_Set;
493         status = FLASH_WaitForLastOperation(EraseTimeout);
494         if(status == FLASH_COMPLETE)
495         {
496             FLASH->CTLR &= CR_OPTER_Reset;
497             FLASH->CTLR |= CR_OPTPG_Set;
498             if(NewState != DISABLE)
499             {
500                 OB->RDPR = 0x00;
501             }
502             else
503             {
504                 OB->RDPR = RDP_Key;
505             }
506             status = FLASH_WaitForLastOperation(EraseTimeout);
507 
508             if(status != FLASH_TIMEOUT)
509             {
510                 FLASH->CTLR &= CR_OPTPG_Reset;
511             }
512         }
513         else
514         {
515             if(status != FLASH_TIMEOUT)
516             {
517                 FLASH->CTLR &= CR_OPTER_Reset;
518             }
519         }
520     }
521     return status;
522 }
523 
524 /*********************************************************************
525  * @fn      FLASH_UserOptionByteConfig
526  *
527  * @brief   Programs the FLASH User Option Byte - IWDG_SW / RST_STOP / RST_STDBY.
528  *
529  * @param   OB_IWDG - Selects the IWDG mode
530  *            OB_IWDG_SW - Software IWDG selected
531  *            OB_IWDG_HW - Hardware IWDG selected
532  *          OB_STOP - Reset event when entering STOP mode.
533  *            OB_STOP_NoRST - No reset generated when entering in STOP
534  *            OB_STOP_RST - Reset generated when entering in STOP
535  *          OB_STDBY - Reset event when entering Standby mode.
536  *            OB_STDBY_NoRST - No reset generated when entering in STANDBY
537  *            OB_STDBY_RST - Reset generated when entering in STANDBY
538  *
539  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
540  *        FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
541  */
FLASH_UserOptionByteConfig(uint16_t OB_IWDG,uint16_t OB_STOP,uint16_t OB_STDBY)542 FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY)
543 {
544     FLASH_Status status = FLASH_COMPLETE;
545 
546     FLASH->OBKEYR = FLASH_KEY1;
547     FLASH->OBKEYR = FLASH_KEY2;
548     status = FLASH_WaitForLastOperation(ProgramTimeout);
549 
550     if(status == FLASH_COMPLETE)
551     {
552         FLASH->CTLR |= CR_OPTPG_Set;
553 
554         OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8)));
555 
556         status = FLASH_WaitForLastOperation(ProgramTimeout);
557         if(status != FLASH_TIMEOUT)
558         {
559             FLASH->CTLR &= CR_OPTPG_Reset;
560         }
561     }
562     return status;
563 }
564 
565 /*********************************************************************
566  * @fn      FLASH_GetUserOptionByte
567  *
568  * @brief   Returns the FLASH User Option Bytes values.
569  *
570  * @return  The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
571  *        and RST_STDBY(Bit2).
572  */
FLASH_GetUserOptionByte(void)573 uint32_t FLASH_GetUserOptionByte(void)
574 {
575     return (uint32_t)(FLASH->OBR >> 2);
576 }
577 
578 /*********************************************************************
579  * @fn      FLASH_GetWriteProtectionOptionByte
580  *
581  * @brief   Returns the FLASH Write Protection Option Bytes Register value.
582  *
583  * @return  The FLASH Write Protection Option Bytes Register value.
584  */
FLASH_GetWriteProtectionOptionByte(void)585 uint32_t FLASH_GetWriteProtectionOptionByte(void)
586 {
587     return (uint32_t)(FLASH->WPR);
588 }
589 
590 /*********************************************************************
591  * @fn      FLASH_GetReadOutProtectionStatus
592  *
593  * @brief   Checks whether the FLASH Read Out Protection Status is set or not.
594  *
595  * @return  FLASH ReadOut Protection Status(SET or RESET)
596  */
FLASH_GetReadOutProtectionStatus(void)597 FlagStatus FLASH_GetReadOutProtectionStatus(void)
598 {
599     FlagStatus readoutstatus = RESET;
600     if((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
601     {
602         readoutstatus = SET;
603     }
604     else
605     {
606         readoutstatus = RESET;
607     }
608     return readoutstatus;
609 }
610 
611 /*********************************************************************
612  * @fn      FLASH_GetPrefetchBufferStatus
613  *
614  * @brief   Checks whether the FLASH Prefetch Buffer status is set or not.
615  *
616  * @return  FLASH ReadOut Protection Status(SET or RESET)
617  */
FLASH_GetPrefetchBufferStatus(void)618 FlagStatus FLASH_GetPrefetchBufferStatus(void)
619 {
620     FlagStatus bitstatus = RESET;
621 
622     if((FLASH->ACTLR & ACR_PRFTBS_Mask) != (uint32_t)RESET)
623     {
624         bitstatus = SET;
625     }
626     else
627     {
628         bitstatus = RESET;
629     }
630     return bitstatus;
631 }
632 
633 /*********************************************************************
634  * @fn      FLASH_ITConfig
635  *
636  * @brief   Enables or disables the specified FLASH interrupts.
637  *
638  * @param   FLASH_IT - specifies the FLASH interrupt sources to be enabled or disabled.
639  *            FLASH_IT_ERROR - FLASH Error Interrupt
640  *            FLASH_IT_EOP - FLASH end of operation Interrupt
641  *          NewState - new state of the specified Flash interrupts(ENABLE or DISABLE).
642  *
643  * @return  FLASH Prefetch Buffer Status (SET or RESET).
644  */
FLASH_ITConfig(uint32_t FLASH_IT,FunctionalState NewState)645 void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
646 {
647     if(NewState != DISABLE)
648     {
649         FLASH->CTLR |= FLASH_IT;
650     }
651     else
652     {
653         FLASH->CTLR &= ~(uint32_t)FLASH_IT;
654     }
655 }
656 
657 /*********************************************************************
658  * @fn      FLASH_GetFlagStatus
659  *
660  * @brief   Checks whether the specified FLASH flag is set or not.
661  *
662  * @param   FLASH_FLAG - specifies the FLASH flag to check.
663  *            FLASH_FLAG_BSY - FLASH Busy flag
664  *            FLASH_FLAG_PGERR - FLASH Program error flag
665  *            FLASH_FLAG_WRPRTERR - FLASH Write protected error flag
666  *            FLASH_FLAG_EOP - FLASH End of Operation flag
667  *            FLASH_FLAG_OPTERR - FLASH Option Byte error flag
668  *
669  * @return  The new state of FLASH_FLAG (SET or RESET).
670  */
FLASH_GetFlagStatus(uint32_t FLASH_FLAG)671 FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
672 {
673     FlagStatus bitstatus = RESET;
674 
675     if(FLASH_FLAG == FLASH_FLAG_OPTERR)
676     {
677         if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
678         {
679             bitstatus = SET;
680         }
681         else
682         {
683             bitstatus = RESET;
684         }
685     }
686     else
687     {
688         if((FLASH->STATR & FLASH_FLAG) != (uint32_t)RESET)
689         {
690             bitstatus = SET;
691         }
692         else
693         {
694             bitstatus = RESET;
695         }
696     }
697     return bitstatus;
698 }
699 
700 /*********************************************************************
701  * @fn      FLASH_ClearFlag
702  *
703  * @brief   Clears the FLASH's pending flags.
704  *
705  * @param   FLASH_FLAG - specifies the FLASH flags to clear.
706  *            FLASH_FLAG_PGERR - FLASH Program error flag
707  *            FLASH_FLAG_WRPRTERR - FLASH Write protected error flag
708  *            FLASH_FLAG_EOP - FLASH End of Operation flag
709  *
710  * @return  none
711  */
FLASH_ClearFlag(uint32_t FLASH_FLAG)712 void FLASH_ClearFlag(uint32_t FLASH_FLAG)
713 {
714     FLASH->STATR = FLASH_FLAG;
715 }
716 
717 /*********************************************************************
718  * @fn      FLASH_GetStatus
719  *
720  * @brief   Returns the FLASH Status.
721  *
722  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
723  *        FLASH_ERROR_WRP or FLASH_COMPLETE.
724  */
FLASH_GetStatus(void)725 FLASH_Status FLASH_GetStatus(void)
726 {
727     FLASH_Status flashstatus = FLASH_COMPLETE;
728 
729     if((FLASH->STATR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
730     {
731         flashstatus = FLASH_BUSY;
732     }
733     else
734     {
735         if((FLASH->STATR & FLASH_FLAG_PGERR) != 0)
736         {
737             flashstatus = FLASH_ERROR_PG;
738         }
739         else
740         {
741             if((FLASH->STATR & FLASH_FLAG_WRPRTERR) != 0)
742             {
743                 flashstatus = FLASH_ERROR_WRP;
744             }
745             else
746             {
747                 flashstatus = FLASH_COMPLETE;
748             }
749         }
750     }
751     return flashstatus;
752 }
753 
754 /*********************************************************************
755  * @fn      FLASH_GetBank1Status
756  *
757  * @brief   Returns the FLASH Bank1 Status.
758  *
759  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
760  *        FLASH_ERROR_WRP or FLASH_COMPLETE.
761  */
FLASH_GetBank1Status(void)762 FLASH_Status FLASH_GetBank1Status(void)
763 {
764     FLASH_Status flashstatus = FLASH_COMPLETE;
765 
766     if((FLASH->STATR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY)
767     {
768         flashstatus = FLASH_BUSY;
769     }
770     else
771     {
772         if((FLASH->STATR & FLASH_FLAG_BANK1_PGERR) != 0)
773         {
774             flashstatus = FLASH_ERROR_PG;
775         }
776         else
777         {
778             if((FLASH->STATR & FLASH_FLAG_BANK1_WRPRTERR) != 0)
779             {
780                 flashstatus = FLASH_ERROR_WRP;
781             }
782             else
783             {
784                 flashstatus = FLASH_COMPLETE;
785             }
786         }
787     }
788     return flashstatus;
789 }
790 
791 /*********************************************************************
792  * @fn      FLASH_WaitForLastOperation
793  *
794  * @brief   Waits for a Flash operation to complete or a TIMEOUT to occur.
795  *
796  * @param   Timeout - FLASH programming Timeout
797  *
798  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
799  *        FLASH_ERROR_WRP or FLASH_COMPLETE.
800  */
FLASH_WaitForLastOperation(uint32_t Timeout)801 FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
802 {
803     FLASH_Status status = FLASH_COMPLETE;
804 
805     status = FLASH_GetBank1Status();
806     while((status == FLASH_BUSY) && (Timeout != 0x00))
807     {
808         status = FLASH_GetBank1Status();
809         Timeout--;
810     }
811     if(Timeout == 0x00)
812     {
813         status = FLASH_TIMEOUT;
814     }
815     return status;
816 }
817 
818 /*********************************************************************
819  * @fn      FLASH_WaitForLastBank1Operation
820  *
821  * @brief   Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur.
822  *
823  * @param   Timeout - FLASH programming Timeout
824  *
825  * @return  FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
826  *        FLASH_ERROR_WRP or FLASH_COMPLETE.
827  */
FLASH_WaitForLastBank1Operation(uint32_t Timeout)828 FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout)
829 {
830     FLASH_Status status = FLASH_COMPLETE;
831 
832     status = FLASH_GetBank1Status();
833     while((status == FLASH_FLAG_BANK1_BSY) && (Timeout != 0x00))
834     {
835         status = FLASH_GetBank1Status();
836         Timeout--;
837     }
838     if(Timeout == 0x00)
839     {
840         status = FLASH_TIMEOUT;
841     }
842     return status;
843 }
844 
845 /*********************************************************************
846  * @fn      FLASH_Unlock_Fast
847  *
848  * @brief   Unlocks the Fast Program Erase Mode.
849  *
850  * @return  none
851  */
FLASH_Unlock_Fast(void)852 void FLASH_Unlock_Fast(void)
853 {
854     /* Authorize the FPEC of Bank1 Access */
855     FLASH->KEYR = FLASH_KEY1;
856     FLASH->KEYR = FLASH_KEY2;
857 
858     /* Fast program mode unlock */
859     FLASH->MODEKEYR = FLASH_KEY1;
860     FLASH->MODEKEYR = FLASH_KEY2;
861 }
862 
863 /*********************************************************************
864  * @fn      FLASH_Unlock_Fast
865  *
866  * @brief   Unlocks the Fast Program Erase Mode.
867  *
868  * @return  none
869  */
FLASH_Lock_Fast(void)870 void FLASH_Lock_Fast(void)
871 {
872     FLASH->CTLR |= CR_LOCK_Set;
873 }
874 
875 /*********************************************************************
876  * @fn      FLASH_BufReset
877  *
878  * @brief   Flash Buffer reset.
879  *
880  * @return  none
881  */
FLASH_BufReset(void)882 void FLASH_BufReset(void)
883 {
884     FLASH->CTLR |= CR_PAGE_PG;
885     FLASH->CTLR |= CR_BUF_RST;
886     while(FLASH->STATR & SR_BSY)
887         ;
888     FLASH->CTLR &= ~CR_PAGE_PG;
889 }
890 
891 /*********************************************************************
892  * @fn      FLASH_BufLoad
893  *
894  * @brief   Flash Buffer load(128 bit).
895  *
896  * @param   Address - specifies the address to be programmed.
897  *          Data0 - specifies the data0 to be programmed.
898  *          Data1 - specifies the data1 to be programmed.
899  *          Data2 - specifies the data2 to be programmed.
900  *          Data3 - specifies the data3 to be programmed.
901  *
902  * @return  none
903  */
FLASH_BufLoad(uint32_t Address,uint32_t Data0,uint32_t Data1,uint32_t Data2,uint32_t Data3)904 void FLASH_BufLoad(uint32_t Address, uint32_t Data0, uint32_t Data1, uint32_t Data2, uint32_t Data3)
905 {
906     if((Address >= ValidAddrStart) && (Address < ValidAddrEnd))
907     {
908         FLASH->CTLR |= CR_PAGE_PG;
909         *(__IO uint32_t *)(Address + 0x00) = Data0;
910         *(__IO uint32_t *)(Address + 0x04) = Data1;
911         *(__IO uint32_t *)(Address + 0x08) = Data2;
912         *(__IO uint32_t *)(Address + 0x0C) = Data3;
913         FLASH->CTLR |= CR_BUF_LOAD;
914         while(FLASH->STATR & SR_BSY)
915             ;
916         FLASH->CTLR &= ~CR_PAGE_PG;
917 
918         *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Address & 0xFFFFFFFC) ^ 0x00001000);
919     }
920 }
921 
922 /*********************************************************************
923  * @fn      FLASH_ErasePage_Fast
924  *
925  * @brief   Erases a specified FLASH page (1page = 256Byte).
926  *
927  * @param   Page_Address - The page address to be erased.
928  *
929  * @return  none
930  */
FLASH_ErasePage_Fast(uint32_t Page_Address)931 void FLASH_ErasePage_Fast(uint32_t Page_Address)
932 {
933     if((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd))
934     {
935         FLASH->CTLR |= CR_PAGE_ER;
936         FLASH->ADDR = Page_Address;
937         FLASH->CTLR |= CR_STRT_Set;
938         while(FLASH->STATR & SR_BSY)
939             ;
940         FLASH->CTLR &= ~CR_PAGE_ER;
941 
942         *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Page_Address & 0xFFFFFFFC) ^ 0x00001000);
943     }
944 }
945 
946 /*********************************************************************
947  * @fn      FLASH_ProgramPage_Fast
948  *
949  * @brief   Program a specified FLASH page (1page = 256Byte).
950  *
951  * @param   Page_Address - The page address to be programed.
952  *
953  * @return  none
954  */
FLASH_ProgramPage_Fast(uint32_t Page_Address)955 void FLASH_ProgramPage_Fast(uint32_t Page_Address)
956 {
957     if((Page_Address >= ValidAddrStart) && (Page_Address < ValidAddrEnd))
958     {
959         FLASH->CTLR |= CR_PAGE_PG;
960         FLASH->ADDR = Page_Address;
961         FLASH->CTLR |= CR_STRT_Set;
962         while(FLASH->STATR & SR_BSY)
963             ;
964         FLASH->CTLR &= ~CR_PAGE_PG;
965 
966         *(__IO uint32_t *)0x40022034 = *(__IO uint32_t *)((Page_Address & 0xFFFFFFFC) ^ 0x00001000);
967     }
968 }
969