1 /**
2   ******************************************************************************
3   * @file    hk32f0xx_flash.c
4   * @version V1.0.1
5   * @date    2019-08-15
6  ===============================================================================
7                     ##### How to use this driver #####
8  ===============================================================================
9     [..] This driver provides functions to configure and program the Flash
10          memory of all HK32F0xx devices. These functions are split in 4 groups
11          (#) FLASH Interface configuration functions: this group includes the
12              management of following features:
13              (++) Set the latency
14              (++) Enable/Disable the prefetch buffer
15 
16          (#) FLASH Memory Programming functions: this group includes all needed
17              functions to erase and program the main memory:
18              (++) Lock and Unlock the Flash interface.
19              (++) Erase function: Erase Page, erase all pages.
20              (++) Program functions: Half Word and Word write.
21 
22          (#) FLASH Option Bytes Programming functions: this group includes all
23              needed functions to:
24              (++) Lock and Unlock the Flash Option bytes.
25              (++) Launch the Option Bytes loader
26              (++) Erase the Option Bytes
27              (++)Set/Reset the write protection
28              (++) Set the Read protection Level
29              (++) Program the user option Bytes
30              (++) Set/Reset the BOOT1 bit
31              (++) Enable/Disable the VDDA Analog Monitoring
32              (++) Get the user option bytes
33              (++) Get the Write protection
34              (++) Get the read protection status
35 
36          (#) FLASH Interrupts and flag management functions: this group includes
37              all needed functions to:
38              (++) Enable/Disable the flash interrupt sources
39              (++) Get flags status
40              (++) Clear flags
41              (++) Get Flash operation status
42              (++) Wait for last flash operation
43 
44  @endverbatim
45 
46   ******************************************************************************
47   */
48 
49 /* Includes ------------------------------------------------------------------*/
50 #include "hk32f0xx_flash.h"
51 
52 /** @addtogroup HK32F0xx_StdPeriph_Driver
53   * @{
54   */
55 
56 /** @defgroup FLASH
57   * @brief FLASH driver modules
58   * @{
59   */
60 
61 /* Private typedef -----------------------------------------------------------*/
62 /* Private define ------------------------------------------------------------*/
63 /* Private macro -------------------------------------------------------------*/
64 /* Private variables ---------------------------------------------------------*/
65 /* Private function prototypes -----------------------------------------------*/
66 /* Private functions ---------------------------------------------------------*/
67 
68 /** @defgroup FLASH_Private_Functions
69   * @{
70   */
71 
72 /** @defgroup FLASH_Group1 FLASH Interface configuration functions
73   *  @brief   FLASH Interface configuration functions
74  *
75 @verbatim
76  ===============================================================================
77                ##### FLASH Interface configuration functions #####
78  ===============================================================================
79 
80     [..] FLASH_Interface configuration_Functions, includes the following functions:
81        (+) void FLASH_SetLatency(uint32_t FLASH_Latency):
82     [..] To correctly read data from Flash memory, the number of wait states (LATENCY)
83      must be correctly programmed according to the frequency of the CPU clock (HCLK)
84     [..]
85         +--------------------------------------------- +
86         |  Wait states  |   HCLK clock frequency (MHz) |
87         |---------------|------------------------------|
88         |0WS(1CPU cycle)|       0 < HCLK <= 24         |
89         |---------------|------------------------------|
90         |1WS(2CPU cycle)|       24 < HCLK <= 48        |
91         +----------------------------------------------+
92     [..]
93        (+) void FLASH_PrefetchBufferCmd(FunctionalState NewState);
94     [..]
95      All these functions don't need the unlock sequence.
96 
97 @endverbatim
98   * @{
99   */
100 
101 /**
102   * @brief  Sets the code latency value.
103   * @param  FLASH_Latency: specifies the FLASH Latency value.
104   *          This parameter can be one of the following values:
105   *             @arg FLASH_Latency_0: FLASH Zero Latency cycle
106   *             @arg FLASH_Latency_1: FLASH One Latency cycle
107   * @retval None
108   */
FLASH_SetLatency(uint32_t FLASH_Latency)109 void FLASH_SetLatency(uint32_t FLASH_Latency)
110 {
111     uint32_t tmpreg = 0;
112 
113     /* Check the parameters */
114     assert_param(IS_FLASH_LATENCY(FLASH_Latency));
115 
116     /* Read the ACR register */
117     tmpreg = FLASH->ACR;
118 
119     /* Sets the Latency value */
120     tmpreg &= (uint32_t)(~((uint32_t)FLASH_ACR_LATENCY));
121     tmpreg |= FLASH_Latency;
122 
123     /* Write the ACR register */
124     FLASH->ACR = tmpreg;
125 }
126 
127 /**
128   * @brief  Enables or disables the Prefetch Buffer.
129   * @param  NewState: new state of the FLASH prefetch buffer.
130   *          This parameter can be: ENABLE or DISABLE.
131   * @retval None
132   */
FLASH_PrefetchBufferCmd(FunctionalState NewState)133 void FLASH_PrefetchBufferCmd(FunctionalState NewState)
134 {
135     /* Check the parameters */
136     assert_param(IS_FUNCTIONAL_STATE(NewState));
137 
138     if (NewState != DISABLE)
139     {
140         FLASH->ACR |= FLASH_ACR_PRFTBE;
141     }
142     else
143     {
144         FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_PRFTBE));
145     }
146 }
147 
148 /**
149   * @brief  Checks whether the FLASH Prefetch Buffer status is set or not.
150   * @param  None
151   * @retval FLASH Prefetch Buffer Status (SET or RESET).
152   */
FLASH_GetPrefetchBufferStatus(void)153 FlagStatus FLASH_GetPrefetchBufferStatus(void)
154 {
155     FlagStatus bitstatus = RESET;
156 
157     if ((FLASH->ACR & FLASH_ACR_PRFTBS) != (uint32_t)RESET)
158     {
159         bitstatus = SET;
160     }
161     else
162     {
163         bitstatus = RESET;
164     }
165     /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */
166     return bitstatus;
167 }
168 
169 /**
170   * @}
171   */
172 
173 /** @defgroup FLASH_Group2 FLASH Memory Programming functions
174  *  @brief   FLASH Memory Programming functions
175  *
176 @verbatim
177  ===============================================================================
178                 ##### FLASH Memory Programming functions #####
179  ===============================================================================
180 
181     [..] The FLASH Memory Programming functions, includes the following functions:
182        (+) void FLASH_Unlock(void);
183        (+) void FLASH_Lock(void);
184        (+) FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
185        (+) FLASH_Status FLASH_EraseAllPages(void);
186        (+) FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
187        (+) FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
188 
189     [..] Any operation of erase or program should follow these steps:
190 
191        (#) Call the FLASH_Unlock() function to enable the flash control register and
192            program memory access
193        (#) Call the desired function to erase page or program data
194        (#) Call the FLASH_Lock() to disable the flash program memory access
195       (recommended to protect the FLASH memory against possible unwanted operation)
196 
197 @endverbatim
198   * @{
199   */
200 
201 /**
202   * @brief  Unlocks the FLASH control register and program memory access.
203   * @param  None
204   * @retval None
205   */
FLASH_Unlock(void)206 void FLASH_Unlock(void)
207 {
208     if ((FLASH->CR & FLASH_CR_LOCK) != RESET)
209     {
210         /* Unlocking the program memory access */
211         FLASH->KEYR = FLASH_KEY1;
212         FLASH->KEYR = FLASH_KEY2;
213     }
214 }
215 
216 /**
217   * @brief  Locks the Program memory access.
218   * @param  None
219   * @retval None
220   */
FLASH_Lock(void)221 void FLASH_Lock(void)
222 {
223     /* Set the LOCK Bit to lock the FLASH control register and program memory access */
224     FLASH->CR |= FLASH_CR_LOCK;
225 }
226 
227 /**
228   * @brief  Erases a specified page in program memory.
229   * @note   To correctly run this function, the FLASH_Unlock() function must be called before.
230   * @note   Call the FLASH_Lock() to disable the flash memory access (recommended
231   *         to protect the FLASH memory against possible unwanted operation)
232   * @param  Page_Address: The page address in program memory to be erased.
233   * @note   A Page is erased in the Program memory only if the address to load
234   *         is the start address of a page (multiple of 1024 bytes).
235   * @retval FLASH Status: The returned value can be:
236   *         FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
237   */
FLASH_ErasePage(uint32_t Page_Address)238 FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
239 {
240     FLASH_Status status = FLASH_COMPLETE;
241 
242     /* Check the parameters */
243     assert_param(IS_FLASH_PROGRAM_ADDRESS(Page_Address));
244 
245     /* Wait for last operation to be completed */
246     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
247 
248     if (status == FLASH_COMPLETE)
249     {
250         /* If the previous operation is completed, proceed to erase the page */
251         FLASH->CR |= FLASH_CR_PER;
252         FLASH->AR  = Page_Address;
253         FLASH->CR |= FLASH_CR_STRT;
254 
255         /* Wait for last operation to be completed */
256         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
257 
258         /* Disable the PER Bit */
259         FLASH->CR &= ~FLASH_CR_PER;
260     }
261 
262     /* Return the Erase Status */
263     return status;
264 }
265 
266 /**
267   * @brief  Erases all FLASH pages.
268   * @note   To correctly run this function, the FLASH_Unlock() function must be called before.
269   * @note   Call the FLASH_Lock() to disable the flash memory access (recommended
270   *         to protect the FLASH memory against possible unwanted operation)
271   * @param  None
272   * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
273   *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
274   */
FLASH_EraseAllPages(void)275 FLASH_Status FLASH_EraseAllPages(void)
276 {
277     FLASH_Status status = FLASH_COMPLETE;
278 
279     /* Wait for last operation to be completed */
280     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
281 
282     if (status == FLASH_COMPLETE)
283     {
284         /* if the previous operation is completed, proceed to erase all pages */
285         FLASH->CR |= FLASH_CR_MER;
286         FLASH->CR |= FLASH_CR_STRT;
287 
288         /* Wait for last operation to be completed */
289         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
290 
291         /* Disable the MER Bit */
292         FLASH->CR &= ~FLASH_CR_MER;
293     }
294 
295     /* Return the Erase Status */
296     return status;
297 }
298 
299 /**
300   * @brief  Programs a word at a specified address.
301   * @note   To correctly run this function, the FLASH_Unlock() function must be called before.
302   * @note   Call the FLASH_Lock() to disable the flash memory access (recommended
303   *         to protect the FLASH memory against possible unwanted operation)
304   * @param  Address: specifies the address to be programmed.
305   * @param  Data: specifies the data to be programmed.
306   * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
307   *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
308   */
FLASH_ProgramWord(uint32_t Address,uint32_t Data)309 FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
310 {
311     FLASH_Status status = FLASH_COMPLETE;
312     __IO uint32_t tmp = 0;
313 
314     /* Check the parameters */
315     assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
316 
317     /* Wait for last operation to be completed */
318     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
319 
320     if (status == FLASH_COMPLETE)
321     {
322         /* If the previous operation is completed, proceed to program the new first
323         half word */
324         FLASH->CR |= FLASH_CR_PG;
325 
326         *(__IO uint16_t *)Address = (uint16_t)Data;
327 
328         /* Wait for last operation to be completed */
329         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
330 
331         if (status == FLASH_COMPLETE)
332         {
333             /* If the previous operation is completed, proceed to program the new second
334             half word */
335             tmp = Address + 2;
336 
337             *(__IO uint16_t *) tmp = Data >> 16;
338 
339             /* Wait for last operation to be completed */
340             status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
341 
342             /* Disable the PG Bit */
343             FLASH->CR &= ~FLASH_CR_PG;
344         }
345         else
346         {
347             /* Disable the PG Bit */
348             FLASH->CR &= ~FLASH_CR_PG;
349         }
350     }
351 
352     /* Return the Program Status */
353     return status;
354 }
355 
356 /**
357   * @brief  Programs a half word at a specified address.
358   * @note   To correctly run this function, the FLASH_Unlock() function must be called before.
359   * @note   Call the FLASH_Lock() to disable the flash memory access (recommended
360   *         to protect the FLASH memory against possible unwanted operation)
361   * @param  Address: specifies the address to be programmed.
362   * @param  Data: specifies the data to be programmed.
363   * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
364   *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
365   */
FLASH_ProgramHalfWord(uint32_t Address,uint16_t Data)366 FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
367 {
368     FLASH_Status status = FLASH_COMPLETE;
369 
370     /* Check the parameters */
371     assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
372 
373     /* Wait for last operation to be completed */
374     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
375 
376     if (status == FLASH_COMPLETE)
377     {
378         /* If the previous operation is completed, proceed to program the new data */
379         FLASH->CR |= FLASH_CR_PG;
380 
381         *(__IO uint16_t *)Address = Data;
382 
383         /* Wait for last operation to be completed */
384         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
385 
386         /* Disable the PG Bit */
387         FLASH->CR &= ~FLASH_CR_PG;
388     }
389 
390     /* Return the Program Status */
391     return status;
392 }
393 
394 /**
395   * @}
396   */
397 
398 /** @defgroup FLASH_Group3 Option Bytes Programming functions
399  *  @brief   Option Bytes Programming functions
400  *
401 @verbatim
402  ===============================================================================
403                 ##### Option Bytes Programming functions #####
404  ===============================================================================
405 
406     [..] The FLASH_Option Bytes Programming_functions, includes the following functions:
407        (+) void FLASH_OB_Unlock(void);
408        (+) void FLASH_OB_Lock(void);
409        (+) void FLASH_OB_Launch(void);
410        (+) FLASH_Status FLASH_OB_Erase(void);
411        (+) FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState);
412        (+) FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP);
413        (+) FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);
414        (+) FLASH_Status FLASH_OB_BOOTConfig(uint8_t OB_BOOT1);
415        (+) FLASH_Status FLASH_OB_VDDAConfig(uint8_t OB_VDDA_ANALOG);
416        (+) FLASH_Status FLASH_OB_WriteUser(uint8_t OB_USER);
417        (+) FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
418        (+) uint8_t FLASH_OB_GetUser(void);
419        (+) uint32_t FLASH_OB_GetWRP(void);
420        (+) FlagStatus FLASH_OB_GetRDP(void);
421 
422     [..] Any operation of erase or program should follow these steps:
423 
424    (#) Call the FLASH_OB_Unlock() function to enable the Option Bytes registers access
425 
426    (#) Call one or several functions to program the desired option bytes
427       (++) FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level
428       (++) FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
429            => to Enable/Disable the desired sector write protection
430       (++) FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
431            => to configure the user option Bytes: IWDG, STOP and the Standby.
432       (++) FLASH_Status FLASH_OB_BOOTConfig(uint8_t OB_BOOT1)
433            => to set or reset BOOT1
434       (++) FLASH_Status FLASH_OB_VDDAConfig(uint8_t OB_VDDA_ANALOG)
435            => to enable or disable the VDDA Analog Monitoring
436       (++) You can write all User Options bytes at once using a single function
437            by calling FLASH_Status FLASH_OB_WriteUser(uint8_t OB_USER)
438       (++) FLASH_OB_ProgramData(uint32_t Address, uint8_t Data) to program the
439            two half word in the option bytes
440 
441    (#) Once all needed option bytes to be programmed are correctly written, call the
442       FLASH_OB_Launch(void) function to launch the Option Bytes programming process.
443 
444    (#) Call the FLASH_OB_Lock() to disable the Option Bytes registers access (recommended
445       to protect the option Bytes against possible unwanted operations)
446 
447 @endverbatim
448   * @{
449   */
450 
451 /**
452   * @brief  Unlocks the option bytes block access.
453   * @param  None
454   * @retval None
455   */
FLASH_OB_Unlock(void)456 void FLASH_OB_Unlock(void)
457 {
458     if ((FLASH->CR & FLASH_CR_OPTWRE) == RESET)
459     {
460         /* Unlocking the option bytes block access */
461         FLASH->OPTKEYR = FLASH_OPTKEY1;
462         FLASH->OPTKEYR = FLASH_OPTKEY2;
463     }
464 }
465 
466 /**
467   * @brief  Locks the option bytes block access.
468   * @param  None
469   * @retval None
470   */
FLASH_OB_Lock(void)471 void FLASH_OB_Lock(void)
472 {
473     /* Set the OPTWREN Bit to lock the option bytes block access */
474     FLASH->CR &= ~FLASH_CR_OPTWRE;
475 
476 }
477 
478 /**
479   * @brief  Launch the option byte loading.
480   * @param  None
481   * @retval None
482   */
FLASH_OB_Launch(void)483 void FLASH_OB_Launch(void)
484 {
485     /* Set the OBL_Launch bit to launch the option byte loading */
486     FLASH->CR |= FLASH_CR_OBL_LAUNCH;
487 }
488 
489 /**
490   * @brief  Erases the FLASH option bytes.
491   * @note   To correctly run this function, the FLASH_OB_Unlock() function must be called before.
492   * @note   Call the FLASH_OB_Lock() to disable the flash control register access and the option
493   *         bytes (recommended to protect the FLASH memory against possible unwanted operation)
494   * @note   This functions erases all option bytes except the Read protection (RDP).
495   * @param  None
496   * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
497   *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
498   */
FLASH_OB_Erase(void)499 FLASH_Status FLASH_OB_Erase(void)
500 {
501     uint16_t rdptmp = OB_RDP_Level_0;
502 
503     FLASH_Status status = FLASH_COMPLETE;
504 
505     /* Get the actual read protection Option Byte value */
506     if (FLASH_OB_GetRDP() != RESET)
507     {
508         rdptmp = 0x00;
509     }
510 
511     /* Wait for last operation to be completed */
512     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
513 
514     if (status == FLASH_COMPLETE)
515     {
516         /* If the previous operation is completed, proceed to erase the option bytes */
517         FLASH->CR |= FLASH_CR_OPTER;
518         FLASH->CR |= FLASH_CR_STRT;
519 
520         /* Wait for last operation to be completed */
521         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
522 
523         if (status == FLASH_COMPLETE)
524         {
525             /* If the erase operation is completed, disable the OPTER Bit */
526             FLASH->CR &= ~FLASH_CR_OPTER;
527 
528             /* Enable the Option Bytes Programming operation */
529             FLASH->CR |= FLASH_CR_OPTPG;
530 
531             /* Restore the last read protection Option Byte value */
532             OB->RDP = (uint16_t)rdptmp;
533 
534             /* Wait for last operation to be completed */
535             status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
536 
537             if (status != FLASH_TIMEOUT)
538             {
539                 /* if the program operation is completed, disable the OPTPG Bit */
540                 FLASH->CR &= ~FLASH_CR_OPTPG;
541             }
542         }
543         else
544         {
545             if (status != FLASH_TIMEOUT)
546             {
547                 /* Disable the OPTPG Bit */
548                 FLASH->CR &= ~FLASH_CR_OPTPG;
549             }
550         }
551     }
552     /* Return the erase status */
553     return status;
554 }
555 
556 /**
557   * @brief  Write protects the desired pages
558   * @note   To correctly run this function, the FLASH_OB_Unlock() function must be called before.
559   * @note   Call the FLASH_OB_Lock() to disable the flash control register access and the option
560   *         bytes (recommended to protect the FLASH memory against possible unwanted operation)
561   * @param  OB_WRP: specifies the address of the pages to be write protected.
562   *          This parameter can be:
563   *             @arg OB_WRP_Pages0to3..OB_WRP_Pages60to63
564   *             @arg OB_WRP_AllPages
565   * @retval FLASH Status: The returned value can be:
566   *         FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
567   */
FLASH_OB_EnableWRP(uint32_t OB_WRP)568 FLASH_Status FLASH_OB_EnableWRP(uint32_t OB_WRP)
569 {
570     uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF;
571 
572     FLASH_Status status = FLASH_COMPLETE;
573 
574     /* Check the parameters */
575     assert_param(IS_OB_WRP(OB_WRP));
576 
577     OB_WRP = (uint32_t)(~OB_WRP);
578     WRP0_Data = (uint16_t)(OB_WRP & OB_WRP0_WRP0);
579     WRP1_Data = (uint16_t)((OB_WRP >> 8) & OB_WRP0_WRP0);
580 
581     /* Wait for last operation to be completed */
582     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
583 
584     if (status == FLASH_COMPLETE)
585     {
586         FLASH->CR |= FLASH_CR_OPTPG;
587 
588         if (WRP0_Data != 0xFF)
589         {
590             OB->WRP0 = WRP0_Data;
591 
592             /* Wait for last operation to be completed */
593             status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
594         }
595         if ((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
596         {
597             OB->WRP1 = WRP1_Data;
598 
599             /* Wait for last operation to be completed */
600             status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
601         }
602         if (status != FLASH_TIMEOUT)
603         {
604             /* if the program operation is completed, disable the OPTPG Bit */
605             FLASH->CR &= ~FLASH_CR_OPTPG;
606         }
607     }
608     /* Return the write protection operation Status */
609     return status;
610 }
611 
612 /**
613   * @brief  Enables or disables the read out protection.
614   * @note   To correctly run this function, the FLASH_OB_Unlock() function must be called before.
615   * @note   Call the FLASH_OB_Lock() to disable the flash control register access and the option
616   *         bytes (recommended to protect the FLASH memory against possible unwanted operation)
617   * @param  FLASH_ReadProtection_Level: specifies the read protection level.
618   *          This parameter can be:
619   *             @arg OB_RDP_Level_0: No protection
620   *             @arg OB_RDP_Level_1: Read protection of the memory
621   *             @arg OB_RDP_Level_2: Chip protection
622   * @note   When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
623   * @retval FLASH Status: The returned value can be:
624   *         FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
625   */
FLASH_OB_RDPConfig(uint8_t OB_RDP)626 FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP)
627 {
628     FLASH_Status status = FLASH_COMPLETE;
629 
630     /* Check the parameters */
631     assert_param(IS_OB_RDP(OB_RDP));
632     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
633 
634     if (status == FLASH_COMPLETE)
635     {
636         FLASH->CR |= FLASH_CR_OPTER;
637         FLASH->CR |= FLASH_CR_STRT;
638 
639         /* Wait for last operation to be completed */
640         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
641 
642         if (status == FLASH_COMPLETE)
643         {
644             /* If the erase operation is completed, disable the OPTER Bit */
645             FLASH->CR &= ~FLASH_CR_OPTER;
646 
647             /* Enable the Option Bytes Programming operation */
648             FLASH->CR |= FLASH_CR_OPTPG;
649 
650             OB->RDP = OB_RDP;
651 
652             /* Wait for last operation to be completed */
653             status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
654 
655             if (status != FLASH_TIMEOUT)
656             {
657                 /* if the program operation is completed, disable the OPTPG Bit */
658                 FLASH->CR &= ~FLASH_CR_OPTPG;
659             }
660         }
661         else
662         {
663             if (status != FLASH_TIMEOUT)
664             {
665                 /* Disable the OPTER Bit */
666                 FLASH->CR &= ~FLASH_CR_OPTER;
667             }
668         }
669     }
670     /* Return the protection operation Status */
671     return status;
672 }
673 
674 /**
675   * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
676   * @note   To correctly run this function, the FLASH_OB_Unlock() function must be called before.
677   * @note   Call the FLASH_OB_Lock() to disable the flash control register access and the option
678   *         bytes (recommended to protect the FLASH memory against possible unwanted operation)
679   * @param  OB_IWDG: Selects the WDG mode
680   *          This parameter can be one of the following values:
681   *             @arg OB_IWDG_SW: Software WDG selected
682   *             @arg OB_IWDG_HW: Hardware WDG selected
683   * @param  OB_STOP: Reset event when entering STOP mode.
684   *          This parameter can be one of the following values:
685   *             @arg OB_STOP_NoRST: No reset generated when entering in STOP
686   *             @arg OB_STOP_RST: Reset generated when entering in STOP
687   * @param  OB_STDBY: Reset event when entering Standby mode.
688   *          This parameter can be one of the following values:
689   *             @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY
690   *             @arg OB_STDBY_RST: Reset generated when entering in STANDBY
691   * @retval FLASH Status: The returned value can be:
692   *         FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
693   */
FLASH_OB_UserConfig(uint8_t OB_IWDG,uint8_t OB_STOP,uint8_t OB_STDBY)694 FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
695 {
696     FLASH_Status status = FLASH_COMPLETE;
697 
698     /* Check the parameters */
699     assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
700     assert_param(IS_OB_STOP_SOURCE(OB_STOP));
701     assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
702 
703     /* Wait for last operation to be completed */
704     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
705 
706     if (status == FLASH_COMPLETE)
707     {
708         /* Enable the Option Bytes Programming operation */
709         FLASH->CR |= FLASH_CR_OPTPG;
710 
711         OB->USER = (uint16_t)((uint16_t)(OB_IWDG | OB_STOP) | (uint16_t)(OB_STDBY | 0xF8));
712 
713         /* Wait for last operation to be completed */
714         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
715 
716         if (status != FLASH_TIMEOUT)
717         {
718             /* If the program operation is completed, disable the OPTPG Bit */
719             FLASH->CR &= ~FLASH_CR_OPTPG;
720         }
721     }
722     /* Return the Option Byte program Status */
723     return status;
724 }
725 
726 /**
727   * @brief  Sets or resets the BOOT1 option bit.
728   * @param  OB_BOOT1: Set or Reset the BOOT1 option bit.
729   *          This parameter can be one of the following values:
730   *             @arg OB_BOOT1_RESET: BOOT1 option bit reset
731   *             @arg OB_BOOT1_SET: BOOT1 option bit set
732   * @retval None
733   */
FLASH_OB_BOOTConfig(uint8_t OB_BOOT1)734 FLASH_Status FLASH_OB_BOOTConfig(uint8_t OB_BOOT1)
735 {
736     FLASH_Status status = FLASH_COMPLETE;
737 
738     /* Check the parameters */
739     assert_param(IS_OB_BOOT1(OB_BOOT1));
740 
741     /* Wait for last operation to be completed */
742     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
743 
744     if (status == FLASH_COMPLETE)
745     {
746         /* Enable the Option Bytes Programming operation */
747         FLASH->CR |= FLASH_CR_OPTPG;
748 
749         OB->USER = OB_BOOT1 | 0xEF;
750 
751         /* Wait for last operation to be completed */
752         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
753 
754         if (status != FLASH_TIMEOUT)
755         {
756             /* If the program operation is completed, disable the OPTPG Bit */
757             FLASH->CR &= ~FLASH_CR_OPTPG;
758         }
759     }
760     /* Return the Option Byte program Status */
761     return status;
762 }
763 
764 /**
765   * @brief  Sets or resets the BOOT0 option bit.
766   * @note   This function is applicable only for the HK32F042 devices.
767   * @param  OB_BOOT0: Set or Reset the BOOT0 option bit.
768   *          This parameter can be one of the following values:
769   *             @arg OB_BOOT0_RESET: BOOT0 option bit reset
770   *             @arg OB_BOOT0_SET: BOOT0 option bit set
771   * @retval None
772   */
FLASH_OB_BOOT0Config(uint8_t OB_BOOT0)773 FLASH_Status FLASH_OB_BOOT0Config(uint8_t OB_BOOT0)
774 {
775     FLASH_Status status = FLASH_COMPLETE;
776 
777     /* Check the parameters */
778     assert_param(IS_OB_BOOT0(OB_BOOT0));
779 
780     /* Wait for last operation to be completed */
781     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
782 
783     if (status == FLASH_COMPLETE)
784     {
785         /* Enable the Option Bytes Programming operation */
786         FLASH->CR |= FLASH_CR_OPTPG;
787 
788         OB->USER = OB_BOOT0 | 0xF7;
789 
790         /* Wait for last operation to be completed */
791         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
792 
793         if (status != FLASH_TIMEOUT)
794         {
795             /* If the program operation is completed, disable the OPTPG Bit */
796             FLASH->CR &= ~FLASH_CR_OPTPG;
797         }
798     }
799     /* Return the Option Byte program Status */
800     return status;
801 }
802 
803 /**
804   * @brief  Sets or resets the BOOT0SW option bit.
805   * @note   This function is applicable only for the HK32F042 devices.
806   * @param  OB_BOOT0SW: Set or Reset the BOOT0_SW option bit.
807   *          This parameter can be one of the following values:
808   *             @arg OB_BOOT0_SW: BOOT0_SW option bit reset
809   *             @arg OB_BOOT0_HW: BOOT0_SW option bit set
810   * @retval None
811   */
FLASH_OB_BOOT0SWConfig(uint8_t OB_BOOT0SW)812 FLASH_Status FLASH_OB_BOOT0SWConfig(uint8_t OB_BOOT0SW)
813 {
814     FLASH_Status status = FLASH_COMPLETE;
815 
816     /* Check the parameters */
817     assert_param(IS_OB_BOOT0SW(OB_BOOT0SW));
818 
819     /* Wait for last operation to be completed */
820     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
821 
822     if (status == FLASH_COMPLETE)
823     {
824         /* Enable the Option Bytes Programming operation */
825         FLASH->CR |= FLASH_CR_OPTPG;
826 
827         OB->USER = OB_BOOT0SW | 0x7F;
828 
829         /* Wait for last operation to be completed */
830         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
831 
832         if (status != FLASH_TIMEOUT)
833         {
834             /* If the program operation is completed, disable the OPTPG Bit */
835             FLASH->CR &= ~FLASH_CR_OPTPG;
836         }
837     }
838     /* Return the Option Byte program Status */
839     return status;
840 }
841 
842 /**
843   * @brief  Sets or resets the analogue monitoring on VDDA Power source.
844   * @param  OB_VDDA_ANALOG: Selects the analog monitoring on VDDA Power source.
845   *          This parameter can be one of the following values:
846   *             @arg OB_VDDA_ANALOG_ON: Analog monitoring on VDDA Power source ON
847   *             @arg OB_VDDA_ANALOG_OFF: Analog monitoring on VDDA Power source OFF
848   * @retval None
849   */
FLASH_OB_VDDAConfig(uint8_t OB_VDDA_ANALOG)850 FLASH_Status FLASH_OB_VDDAConfig(uint8_t OB_VDDA_ANALOG)
851 {
852     FLASH_Status status = FLASH_COMPLETE;
853 
854     /* Check the parameters */
855     assert_param(IS_OB_VDDA_ANALOG(OB_VDDA_ANALOG));
856 
857     /* Wait for last operation to be completed */
858     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
859 
860     if (status == FLASH_COMPLETE)
861     {
862         /* Enable the Option Bytes Programming operation */
863         FLASH->CR |= FLASH_CR_OPTPG;
864 
865         OB->USER = OB_VDDA_ANALOG | 0xDF;
866 
867         /* Wait for last operation to be completed */
868         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
869 
870         if (status != FLASH_TIMEOUT)
871         {
872             /* if the program operation is completed, disable the OPTPG Bit */
873             FLASH->CR &= ~FLASH_CR_OPTPG;
874         }
875     }
876     /* Return the Option Byte program Status */
877     return status;
878 }
879 
880 /**
881   * @brief  Sets or resets the SRAM parity.
882   * @param  OB_SRAM_Parity: Set or Reset the SRAM parity enable bit.
883   *          This parameter can be one of the following values:
884   *             @arg OB_SRAM_PARITY_SET: Set SRAM parity.
885   *             @arg OB_SRAM_PARITY_RESET: Reset SRAM parity.
886   * @retval None
887   */
FLASH_OB_SRAMParityConfig(uint8_t OB_SRAM_Parity)888 FLASH_Status FLASH_OB_SRAMParityConfig(uint8_t OB_SRAM_Parity)
889 {
890     FLASH_Status status = FLASH_COMPLETE;
891 
892     /* Check the parameters */
893     assert_param(IS_OB_SRAM_PARITY(OB_SRAM_Parity));
894 
895     /* Wait for last operation to be completed */
896     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
897 
898     if (status == FLASH_COMPLETE)
899     {
900         /* Enable the Option Bytes Programming operation */
901         FLASH->CR |= FLASH_CR_OPTPG;
902 
903         OB->USER = OB_SRAM_Parity | 0xBF;
904 
905         /* Wait for last operation to be completed */
906         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
907 
908         if (status != FLASH_TIMEOUT)
909         {
910             /* if the program operation is completed, disable the OPTPG Bit */
911             FLASH->CR &= ~FLASH_CR_OPTPG;
912         }
913     }
914     /* Return the Option Byte program Status */
915     return status;
916 }
917 
918 /**
919   * @brief  Programs the FLASH User Option Byte: IWDG_SW, RST_STOP, RST_STDBY,
920   *         BOOT1 and VDDA ANALOG monitoring.
921   * @note   To correctly run this function, the FLASH_OB_Unlock() function must be called before.
922   * @note   Call the FLASH_OB_Lock() to disable the flash control register access and the option
923   *         bytes (recommended to protect the FLASH memory against possible unwanted operation)
924   * @param  OB_USER: Selects all user option bytes
925   *          This parameter is a combination of the following values:
926   *             @arg OB_IWDG_SW / OB_IWDG_HW: Software / Hardware WDG selected
927   *             @arg OB_STOP_NoRST / OB_STOP_RST: No reset / Reset generated when entering in STOP
928   *             @arg OB_STDBY_NoRST / OB_STDBY_RST: No reset / Reset generated when entering in STANDBY
929   *             @arg OB_BOOT1_RESET / OB_BOOT1_SET: BOOT1 Reset / Set
930   *             @arg OB_VDDA_ANALOG_ON / OB_VDDA_ANALOG_OFF: Analog monitoring on VDDA Power source ON / OFF
931   *             @arg OB_SRAM_PARITY_SET / OB_SRAM_PARITY_RESET: SRAM Parity SET / RESET
932   *             @arg OB_BOOT0_RESET / OB_BOOT0_SET: BOOT0 Reset / Set
933   *             @arg OB_BOOT0_SW / OB_BOOT0_SW: BOOT0 pin disabled / BOOT0 pin bonded with GPIO
934   * @retval FLASH Status: The returned value can be:
935   *         FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
936   */
FLASH_OB_WriteUser(uint8_t OB_USER)937 FLASH_Status FLASH_OB_WriteUser(uint8_t OB_USER)
938 {
939     FLASH_Status status = FLASH_COMPLETE;
940 
941     /* Wait for last operation to be completed */
942     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
943 
944     if (status == FLASH_COMPLETE)
945     {
946         /* Enable the Option Bytes Programming operation */
947         FLASH->CR |= FLASH_CR_OPTPG;
948 
949         OB->USER = OB_USER;
950 
951         /* Wait for last operation to be completed */
952         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
953 
954         if (status != FLASH_TIMEOUT)
955         {
956             /* If the program operation is completed, disable the OPTPG Bit */
957             FLASH->CR &= ~FLASH_CR_OPTPG;
958         }
959     }
960     /* Return the Option Byte program Status */
961     return status;
962 
963 }
964 
965 /**
966   * @brief  Programs a half word at a specified Option Byte Data address.
967   * @note   To correctly run this function, the FLASH_OB_Unlock() function must be called before.
968   * @note   Call the FLASH_OB_Lock() to disable the flash control register access and the option
969   *         bytes (recommended to protect the FLASH memory against possible unwanted operation)
970   * @param  Address: specifies the address to be programmed.
971   *          This parameter can be 0x1FFFF804 or 0x1FFFF806.
972   * @param  Data: specifies the data to be programmed.
973   * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
974   *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
975   */
FLASH_OB_ProgramData(uint32_t Address,uint8_t Data)976 FLASH_Status FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
977 {
978     FLASH_Status status = FLASH_COMPLETE;
979     /* Check the parameters */
980     assert_param(IS_OB_DATA_ADDRESS(Address));
981     status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
982 
983     if (status == FLASH_COMPLETE)
984     {
985         /* Enables the Option Bytes Programming operation */
986         FLASH->CR |= FLASH_CR_OPTPG;
987         *(__IO uint16_t *)Address = Data;
988 
989         /* Wait for last operation to be completed */
990         status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
991 
992         if (status != FLASH_TIMEOUT)
993         {
994             /* If the program operation is completed, disable the OPTPG Bit */
995             FLASH->CR &= ~FLASH_CR_OPTPG;
996         }
997     }
998     /* Return the Option Byte Data Program Status */
999     return status;
1000 }
1001 
1002 /**
1003   * @brief  Returns the FLASH User Option Bytes values.
1004   * @param  None
1005   * @retval The FLASH User Option Bytes .
1006   */
FLASH_OB_GetUser(void)1007 uint8_t FLASH_OB_GetUser(void)
1008 {
1009     /* Return the User Option Byte */
1010     return (uint8_t)(FLASH->OBR >> 8);
1011 }
1012 
1013 /**
1014   * @brief  Returns the FLASH Write Protection Option Bytes value.
1015   * @param  None
1016   * @retval The FLASH Write Protection Option Bytes value
1017   */
FLASH_OB_GetWRP(void)1018 uint32_t FLASH_OB_GetWRP(void)
1019 {
1020     /* Return the FLASH write protection Register value */
1021     return (uint32_t)(FLASH->WRPR);
1022 }
1023 
1024 /**
1025   * @brief  Checks whether the FLASH Read out Protection Status is set or not.
1026   * @param  None
1027   * @retval FLASH ReadOut Protection Status(SET or RESET)
1028   */
FLASH_OB_GetRDP(void)1029 FlagStatus FLASH_OB_GetRDP(void)
1030 {
1031     FlagStatus readstatus = RESET;
1032 
1033     if ((uint8_t)(FLASH->OBR & (FLASH_OBR_RDPRT1 | FLASH_OBR_RDPRT2)) != RESET)
1034     {
1035         readstatus = SET;
1036     }
1037     else
1038     {
1039         readstatus = RESET;
1040     }
1041     return readstatus;
1042 }
1043 
1044 /**
1045   * @}
1046   */
1047 
1048 /** @defgroup FLASH_Group4 Interrupts and flags management functions
1049  *  @brief   Interrupts and flags management functions
1050  *
1051 @verbatim
1052  ===============================================================================
1053              ##### Interrupts and flags management functions #####
1054  ===============================================================================
1055 
1056 @endverbatim
1057   * @{
1058   */
1059 
1060 /**
1061   * @brief  Enables or disables the specified FLASH interrupts.
1062   * @param  FLASH_IT: specifies the FLASH interrupt sources to be enabled or
1063   *         disabled.
1064   *          This parameter can be any combination of the following values:
1065   *             @arg FLASH_IT_EOP: FLASH end of programming Interrupt
1066   *             @arg FLASH_IT_ERR: FLASH Error Interrupt
1067   * @retval None
1068   */
FLASH_ITConfig(uint32_t FLASH_IT,FunctionalState NewState)1069 void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
1070 {
1071     /* Check the parameters */
1072     assert_param(IS_FLASH_IT(FLASH_IT));
1073     assert_param(IS_FUNCTIONAL_STATE(NewState));
1074 
1075     if (NewState != DISABLE)
1076     {
1077         /* Enable the interrupt sources */
1078         FLASH->CR |= FLASH_IT;
1079     }
1080     else
1081     {
1082         /* Disable the interrupt sources */
1083         FLASH->CR &= ~(uint32_t)FLASH_IT;
1084     }
1085 }
1086 
1087 /**
1088   * @brief  Checks whether the specified FLASH flag is set or not.
1089   * @param  FLASH_FLAG: specifies the FLASH flag to check.
1090   *          This parameter can be one of the following values:
1091   *             @arg FLASH_FLAG_BSY: FLASH write/erase operations in progress flag
1092   *             @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
1093   *             @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
1094   *             @arg FLASH_FLAG_EOP: FLASH End of Programming flag
1095   * @retval The new state of FLASH_FLAG (SET or RESET).
1096   */
FLASH_GetFlagStatus(uint32_t FLASH_FLAG)1097 FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
1098 {
1099     FlagStatus bitstatus = RESET;
1100 
1101     /* Check the parameters */
1102     assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG));
1103 
1104     if ((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
1105     {
1106         bitstatus = SET;
1107     }
1108     else
1109     {
1110         bitstatus = RESET;
1111     }
1112     /* Return the new state of FLASH_FLAG (SET or RESET) */
1113     return bitstatus;
1114 }
1115 
1116 /**
1117   * @brief  Clears the FLASH's pending flags.
1118   * @param  FLASH_FLAG: specifies the FLASH flags to clear.
1119   *          This parameter can be any combination of the following values:
1120   *             @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
1121   *             @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
1122   *             @arg FLASH_FLAG_EOP: FLASH End of Programming flag
1123   * @retval None
1124   */
FLASH_ClearFlag(uint32_t FLASH_FLAG)1125 void FLASH_ClearFlag(uint32_t FLASH_FLAG)
1126 {
1127     /* Check the parameters */
1128     assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG));
1129     // unlock the flash to reset the falsh_cr_lock
1130     if ((FLASH->CR & FLASH_CR_LOCK)  != RESET)
1131     {
1132         /* Unlocking the program memory access */
1133         FLASH->KEYR = FLASH_KEY1;
1134         FLASH->KEYR = FLASH_KEY2;
1135 
1136         /* Clear the flags */
1137         FLASH->SR = FLASH_FLAG;
1138         // set the FLASH_CR_LOCK bit
1139         FLASH->CR |= FLASH_CR_LOCK;
1140 
1141     }
1142     else
1143     {
1144         /* Clear the flags */
1145         FLASH->SR = FLASH_FLAG;
1146     }
1147 
1148 }
1149 
1150 /**
1151   * @brief  Returns the FLASH Status.
1152   * @param  None
1153   * @retval FLASH Status: The returned value can be:
1154   *         FLASH_BUSY, FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP or FLASH_COMPLETE.
1155   */
FLASH_GetStatus(void)1156 FLASH_Status FLASH_GetStatus(void)
1157 {
1158     FLASH_Status FLASHstatus = FLASH_COMPLETE;
1159 
1160     if ((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
1161     {
1162         FLASHstatus = FLASH_BUSY;
1163     }
1164     else
1165     {
1166         if ((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR) != (uint32_t)0x00)
1167         {
1168             FLASHstatus = FLASH_ERROR_WRP;
1169         }
1170         else
1171         {
1172             if ((FLASH->SR & (uint32_t)(FLASH_SR_PGERR)) != (uint32_t)0x00)
1173             {
1174                 FLASHstatus = FLASH_ERROR_PROGRAM;
1175             }
1176             else
1177             {
1178                 FLASHstatus = FLASH_COMPLETE;
1179             }
1180         }
1181     }
1182     /* Return the FLASH Status */
1183     return FLASHstatus;
1184 }
1185 
1186 
1187 /**
1188   * @brief  Waits for a FLASH operation to complete or a TIMEOUT to occur.
1189   * @param  Timeout: FLASH programming Timeout
1190   * @retval FLASH Status: The returned value can be: FLASH_BUSY,
1191   *         FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
1192   */
FLASH_WaitForLastOperation(uint32_t Timeout)1193 FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
1194 {
1195     FLASH_Status status = FLASH_COMPLETE;
1196 
1197     /* Check for the FLASH Status */
1198     status = FLASH_GetStatus();
1199 
1200     /* Wait for a FLASH operation to complete or a TIMEOUT to occur */
1201     while ((status == FLASH_BUSY) && (Timeout != 0x00))
1202     {
1203         status = FLASH_GetStatus();
1204         Timeout--;
1205     }
1206 
1207     if (Timeout == 0x00)
1208     {
1209         status = FLASH_TIMEOUT;
1210     }
1211     /* Return the operation status */
1212     return status;
1213 }
1214 
1215