1 /**
2 ******************************************************************************
3 * @file    HAL_flash.c
4 * @author  AE Team
5 * @version V1.1.0
6 * @date    28/08/2019
7 * @brief   This file provides all the FLASH firmware functions.
8 ******************************************************************************
9 * @copy
10 *
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, MindMotion SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 *
18 * <h2><center>&copy; COPYRIGHT 2019 MindMotion</center></h2>
19 */
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include "HAL_flash.h"
23 
24 /** @addtogroup StdPeriph_Driver
25 * @{
26 */
27 
28 /** @defgroup FLASH
29 * @brief FLASH driver modules
30 * @{
31 */
32 
33 /** @defgroup FLASH_Private_TypesDefinitions
34 * @{
35 */
36 
37 /**
38 * @}
39 */
40 
41 /** @defgroup FLASH_Private_Defines
42 * @{
43 */
44 
45 /* Flash Access Control Register bits */
46 #define ACR_LATENCY_Mask         ((uint32_t)0x00000038)
47 #define ACR_HLFCYA_Mask          ((uint32_t)0xFFFFFFF7)
48 #define ACR_PRFTBE_Mask          ((uint32_t)0xFFFFFFEF)
49 
50 /* Flash Access Control Register bits */
51 #define ACR_PRFTBS_Mask          ((uint32_t)0x00000020)
52 
53 /* Flash Control Register bits */
54 #define CR_PG_Set                ((uint32_t)0x00000001)
55 #define CR_PG_Reset              ((uint32_t)0x00001FFE)
56 #define CR_PER_Set               ((uint32_t)0x00000002)
57 #define CR_PER_Reset             ((uint32_t)0x00001FFD)
58 #define CR_MER_Set               ((uint32_t)0x00000004)
59 #define CR_MER_Reset             ((uint32_t)0x00001FFB)
60 #define CR_OPTPG_Set             ((uint32_t)0x00000010)
61 #define CR_OPTPG_Reset           ((uint32_t)0x00001FEF)
62 #define CR_OPTER_Set             ((uint32_t)0x00000020)
63 #define CR_OPTER_Reset           ((uint32_t)0x00001FDF)
64 #define CR_STRT_Set              ((uint32_t)0x00000040)
65 #define CR_LOCK_Set              ((uint32_t)0x00000080)
66 
67 /* FLASH Mask */
68 #define RDPRT_Mask               ((uint32_t)0x00000002)
69 #define WRP0_Mask                ((uint32_t)0x000000FF)
70 #define WRP1_Mask                ((uint32_t)0x0000FF00)
71 #define WRP2_Mask                ((uint32_t)0x00FF0000)
72 #define WRP3_Mask                ((uint32_t)0xFF000000)
73 
74 /* FLASH Keys */
75 #define RDP_Key                  ((uint16_t)0x00A5)
76 #define FLASH_KEY1               ((uint32_t)0x45670123)
77 #define FLASH_KEY2               ((uint32_t)0xCDEF89AB)
78 
79 /* Delay definition */
80 #define EraseTimeout             ((uint32_t)0x00000FFF)
81 #define ProgramTimeout           ((uint32_t)0x0000000F)
82 
83 /**
84 * @}
85 */
86 
87 /** @defgroup FLASH_Private_Macros
88 * @{
89 */
90 
91 /**
92 * @}
93 */
94 
95 /** @defgroup FLASH_Private_Variables
96 * @{
97 */
98 
99 /**
100 * @}
101 */
102 
103 /** @defgroup FLASH_Private_FunctionPrototypes
104 * @{
105 */
106 
107 static void delay(void);
108 /**
109 * @}
110 */
111 
112 /** @defgroup FLASH_Private_Functions
113 * @{
114 */
115 
116 /**
117 * @brief  Sets the code latency value.
118 * @param FLASH_Latency: specifies the FLASH Latency value.
119 *   This parameter can be one of the following values:
120 * @arg FLASH_Latency_0: FLASH Zero Latency cycle
121 * @arg FLASH_Latency_1: FLASH One Latency cycle
122 * @arg FLASH_Latency_2: FLASH Two Latency cycles
123 * @arg FLASH_Latency_3: FLASH Three Latency cycles
124 * @retval : None
125 */
FLASH_SetLatency(uint32_t FLASH_Latency)126 void FLASH_SetLatency(uint32_t FLASH_Latency)
127 {
128     uint32_t tmpreg = 0;
129 
130     /* Check the parameters */
131     assert_param(IS_FLASH_LATENCY(FLASH_Latency));
132 
133     /* Read the ACR register */
134     tmpreg = FLASH->ACR;
135 
136     /* Sets the Latency value */
137     tmpreg &= ACR_LATENCY_Mask;
138     tmpreg |= FLASH_Latency;
139 
140     /* Write the ACR register */
141     FLASH->ACR = tmpreg;
142 }
143 
144 /**
145 * @brief  Enables or disables the Half cycle flash access.
146 * @param FLASH_HalfCycleAccess: specifies the FLASH Half cycle Access mode.
147 *   This parameter can be one of the following values:
148 * @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable
149 * @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable
150 * @retval : None
151 */
FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)152 void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)
153 {
154     /* Check the parameters */
155     assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess));
156 
157     /* Enable or disable the Half cycle access */
158     FLASH->ACR &= ACR_HLFCYA_Mask;
159     FLASH->ACR |= FLASH_HalfCycleAccess;
160 }
161 
162 /**
163 * @brief  Enables or disables the Prefetch Buffer.
164 * @param FLASH_PrefetchBuffer: specifies the Prefetch buffer status.
165 *   This parameter can be one of the following values:
166 * @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable
167 * @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable
168 * @retval : None
169 */
FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)170 void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)
171 {
172     /* Check the parameters */
173     assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer));
174 
175     /* Enable or disable the Prefetch Buffer */
176     FLASH->ACR &= ACR_PRFTBE_Mask;
177     FLASH->ACR |= FLASH_PrefetchBuffer;
178 }
179 
180 /**
181 * @brief  Unlocks the FLASH Program Erase Controller.
182 * @param  None
183 * @retval : None
184 */
FLASH_Unlock(void)185 void FLASH_Unlock(void)
186 {
187     /* Authorize the FPEC Access */
188     FLASH->KEYR = FLASH_KEY1;
189     FLASH->KEYR = FLASH_KEY2;
190 }
191 
192 /**
193 * @brief  Locks the FLASH Program Erase Controller.
194 * @param  None
195 * @retval : None
196 */
FLASH_Lock(void)197 void FLASH_Lock(void)
198 {
199     /* Set the Lock Bit to lock the FPEC and the FCR */
200     FLASH->CR |= CR_LOCK_Set;
201 }
202 
203 /**
204 * @brief  Erases a specified FLASH page.
205 * @param Page_Address: The page address to be erased.
206 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
207 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
208 *   FLASH_TIMEOUT.
209 */
FLASH_ErasePage(uint32_t Page_Address)210 FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
211 {
212     FLASH_Status status = FLASH_COMPLETE;
213     /* Check the parameters */
214     assert_param(IS_FLASH_ADDRESS(Page_Address));
215 
216     /* Wait for last operation to be completed */
217     status = FLASH_WaitForLastOperation(EraseTimeout);
218 
219     if(status == FLASH_COMPLETE)
220     {
221         /* if the previous operation is completed, proceed to erase the page */
222         FLASH->CR |= CR_PER_Set;
223         FLASH->AR = Page_Address;
224         FLASH->CR |= CR_STRT_Set;
225 
226         /* Wait for last operation to be completed */
227         status = FLASH_WaitForLastOperation(EraseTimeout);
228         if(status != FLASH_BUSY)
229         {
230             /* if the erase operation is completed, disable the PER Bit */
231             FLASH->CR &= CR_PER_Reset;
232         }
233     }
234 
235     /* Return the Erase Status */
236     return status;
237 }
238 
239 /**
240 * @brief  Erases all FLASH pages.
241 * @param  None
242 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
243 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
244 *   FLASH_TIMEOUT.
245 */
FLASH_EraseAllPages(void)246 FLASH_Status FLASH_EraseAllPages(void)
247 {
248     FLASH_Status status = FLASH_COMPLETE;
249 
250     /* Wait for last operation to be completed */
251     status = FLASH_WaitForLastOperation(EraseTimeout);
252 
253     if(status == FLASH_COMPLETE)
254     {
255         /* if the previous operation is completed, proceed to erase all pages */
256         FLASH->AR = 0x08000000;
257         FLASH->CR |= CR_MER_Set;
258         FLASH->CR |= CR_STRT_Set;
259 
260         /* Wait for last operation to be completed */
261         status = FLASH_WaitForLastOperation(EraseTimeout);
262         if(status != FLASH_BUSY)
263         {
264             /* if the erase operation is completed, disable the MER Bit */
265             FLASH->CR &= CR_MER_Reset;
266         }
267     }
268 
269     /* Return the Erase Status */
270     return status;
271 }
272 
273 /**
274 * @brief  Erases the FLASH option bytes.
275 * @param  None
276 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
277 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
278 *   FLASH_TIMEOUT.
279 */
FLASH_EraseOptionBytes(void)280 FLASH_Status FLASH_EraseOptionBytes(void)
281 {
282     FLASH_Status status = FLASH_COMPLETE;
283 
284     /* Wait for last operation to be completed */
285     status = FLASH_WaitForLastOperation(EraseTimeout);
286     if(status == FLASH_COMPLETE)
287     {
288         /* Authorize the small information block programming */
289         FLASH->OPTKEYR = FLASH_KEY1;
290         FLASH->OPTKEYR = FLASH_KEY2;
291 
292         /* if the previous operation is completed, proceed to erase the option bytes */
293         FLASH->CR |= CR_OPTER_Set;
294         FLASH->AR = 0x1FFFF800;
295         FLASH->CR |= CR_STRT_Set;
296         /* Wait for last operation to be completed */
297         status = FLASH_WaitForLastOperation(EraseTimeout);
298 
299         if(status == FLASH_COMPLETE)
300         {
301             /* if the erase operation is completed, disable the OPTER Bit */
302             FLASH->CR &= CR_OPTER_Reset;
303 
304             /* Enable the Option Bytes Programming operation */
305             FLASH->CR |= CR_OPTPG_Set;
306 
307             /* Enable the readout access */
308             OB->RDP = RDP_Key;
309 
310             /* Wait for last operation to be completed */
311             status = FLASH_WaitForLastOperation(ProgramTimeout);
312 
313             if(status != FLASH_BUSY)
314             {
315                 /* if the program operation is completed, disable the OPTPG Bit */
316                 FLASH->CR &= CR_OPTPG_Reset;
317             }
318         }
319         else
320         {
321             if (status != FLASH_BUSY)
322             {
323                 /* Disable the OPTPG Bit */
324                 FLASH->CR &= CR_OPTPG_Reset;
325             }
326         }
327     }
328     /* Return the erase status */
329     return status;
330 }
331 
332 /**
333 * @brief  Programs a word at a specified address.
334 * @param Address: specifies the address to be programmed.
335 * @param Data: specifies the data to be programmed.
336 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
337 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
338 *   FLASH_TIMEOUT.
339 */
FLASH_ProgramWord(uint32_t Address,uint32_t Data)340 FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
341 {
342     FLASH_Status status = FLASH_COMPLETE;
343     /* Check the parameters */
344     assert_param(IS_FLASH_ADDRESS(Address));
345 
346 
347 
348 
349     /* Wait for last operation to be completed */
350     status = FLASH_WaitForLastOperation(ProgramTimeout);
351 
352     if(status == FLASH_COMPLETE)
353     {
354         /* if the previous operation is completed, proceed to program the new first
355         half word */
356         FLASH->CR |= CR_PG_Set;
357 
358         *(__IO uint16_t*)Address = (uint16_t)Data;
359         /* Wait for last operation to be completed */
360         status = FLASH_WaitForLastOperation(ProgramTimeout);
361 
362         if(status == FLASH_COMPLETE)
363         {
364             /* if the previous operation is completed, proceed to program the new second
365             half word */
366             *(__IO uint16_t*)(Address + 2) = Data >> 16;
367 
368             /* Wait for last operation to be completed */
369             status = FLASH_WaitForLastOperation(ProgramTimeout);
370 
371             if(status != FLASH_BUSY)
372             {
373                 /* Disable the PG Bit */
374                 FLASH->CR &= CR_PG_Reset;
375             }
376         }
377         else
378         {
379             if (status != FLASH_BUSY)
380             {
381                 /* Disable the PG Bit */
382                 FLASH->CR &= CR_PG_Reset;
383             }
384         }
385     }
386 
387 
388     /* Return the Program Status */
389     return status;
390 }
391 
392 /**
393 * @brief  Programs a half word at a specified address.
394 * @param Address: specifies the address to be programmed.
395 * @param Data: specifies the data to be programmed.
396 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
397 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
398 *   FLASH_TIMEOUT.
399 */
FLASH_ProgramHalfWord(uint32_t Address,uint16_t Data)400 FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
401 {
402     FLASH_Status status = FLASH_COMPLETE;
403     /* Check the parameters */
404     assert_param(IS_FLASH_ADDRESS(Address));
405 
406 
407 
408     /* Wait for last operation to be completed */
409     status = FLASH_WaitForLastOperation(ProgramTimeout);
410 
411     if(status == FLASH_COMPLETE)
412     {
413         /* if the previous operation is completed, proceed to program the new data */
414         FLASH->CR |= CR_PG_Set;
415 
416         *(__IO uint16_t*)Address = Data;
417         /* Wait for last operation to be completed */
418         status = FLASH_WaitForLastOperation(ProgramTimeout);
419         if(status != FLASH_BUSY)
420         {
421             /* if the program operation is completed, disable the PG Bit */
422             FLASH->CR &= CR_PG_Reset;
423         }
424     }
425 
426 
427     /* Return the Program Status */
428     return status;
429 }
430 
431 /**
432 * @brief  Programs a half word at a specified Option Byte Data address.
433 * @param Address: specifies the address to be programmed.
434 *   This parameter can be 0x1FFFF804 or 0x1FFFF806.
435 * @param Data: specifies the data to be programmed.
436 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
437 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
438 *   FLASH_TIMEOUT.
439 */
FLASH_ProgramOptionByteData(uint32_t Address,uint8_t Data)440 FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)
441 {
442     FLASH_Status status = FLASH_COMPLETE;
443     /* Check the parameters */
444     assert_param(IS_OB_DATA_ADDRESS(Address));
445 
446 
447 
448     status = FLASH_WaitForLastOperation(ProgramTimeout);
449     if(status == FLASH_COMPLETE)
450     {
451         /* Authorize the small information block programming */
452         FLASH->OPTKEYR = FLASH_KEY1;
453         FLASH->OPTKEYR = FLASH_KEY2;
454         /* Enables the Option Bytes Programming operation */
455         FLASH->CR |= CR_OPTPG_Set;
456         *(__IO uint16_t*)Address = Data;
457 
458         /* Wait for last operation to be completed */
459         status = FLASH_WaitForLastOperation(ProgramTimeout);
460         if(status != FLASH_BUSY)
461         {
462             /* if the program operation is completed, disable the OPTPG Bit */
463             FLASH->CR &= CR_OPTPG_Reset;
464         }
465     }
466 
467 
468 
469     /* Return the Option Byte Data Program Status */
470     return status;
471 }
472 
473 /**
474 * @brief  Write protects the desired pages
475 * @param FLASH_Pages: specifies the address of the pages to be
476 *   write protected. This parameter can be:
477 * @arg For microcontroller Medium-density devices (FLASH page size equal to 1 KB)
478 * A value between FLASH_WRProt_Pages0to3 and FLASH_WRProt_Pages124to127
479 * @arg For microcontroller High-density devices (FLASH page size equal to 2 KB)
480 * A value between FLASH_WRProt_Pages0to1 and  FLASH_WRProt_Pages60to61
481 * or FLASH_WRProt_Pages62to255
482 * @arg FLASH_WRProt_AllPages
483 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
484 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
485 *   FLASH_TIMEOUT.
486 */
FLASH_EnableWriteProtection(uint32_t FLASH_Pages)487 FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
488 {
489     uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
490 
491     FLASH_Status status = FLASH_COMPLETE;
492 
493     /* Check the parameters */
494     assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));
495 
496 
497 
498     FLASH_Pages = (uint32_t)(~FLASH_Pages);
499     WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
500     WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
501     WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
502     WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);
503 
504     /* Wait for last operation to be completed */
505     status = FLASH_WaitForLastOperation(ProgramTimeout);
506 
507     if(status == FLASH_COMPLETE)
508     {
509         /* Authorizes the small information block programming */
510         FLASH->OPTKEYR = FLASH_KEY1;
511         FLASH->OPTKEYR = FLASH_KEY2;
512         FLASH->CR |= CR_OPTPG_Set;
513         if(WRP0_Data != 0xFF)
514         {
515             OB->WRP0 = WRP0_Data;
516 
517             /* Wait for last operation to be completed */
518             status = FLASH_WaitForLastOperation(ProgramTimeout);
519         }
520         if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
521         {
522             OB->WRP1 = WRP1_Data;
523 
524             /* Wait for last operation to be completed */
525             status = FLASH_WaitForLastOperation(ProgramTimeout);
526         }
527         if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))
528         {
529             OB->WRP2 = WRP2_Data;
530 
531             /* Wait for last operation to be completed */
532             status = FLASH_WaitForLastOperation(ProgramTimeout);
533         }
534 
535         if((status == FLASH_COMPLETE) && (WRP3_Data != 0xFF))
536         {
537             OB->WRP3 = WRP3_Data;
538 
539             /* Wait for last operation to be completed */
540             status = FLASH_WaitForLastOperation(ProgramTimeout);
541         }
542 
543         if(status != FLASH_BUSY)
544         {
545             /* if the program operation is completed, disable the OPTPG Bit */
546             FLASH->CR &= CR_OPTPG_Reset;
547         }
548     }
549 
550 
551 
552     /* Return the write protection operation Status */
553     return status;
554 }
555 
556 /**
557 * @brief  Enables or disables the read out protection.
558 *   If the user has already programmed the other option bytes before
559 *   calling this function, he must re-program them since this
560 *   function erases all option bytes.
561 * @param Newstate: new state of the ReadOut Protection.
562 *   This parameter can be: ENABLE or DISABLE.
563 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
564 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
565 *   FLASH_TIMEOUT.
566 */
FLASH_ReadOutProtection(FunctionalState NewState)567 FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
568 {
569     FLASH_Status status = FLASH_COMPLETE;
570     /* Check the parameters */
571     assert_param(IS_FUNCTIONAL_STATE(NewState));
572 
573 
574 
575     status = FLASH_WaitForLastOperation(EraseTimeout);
576     if(status == FLASH_COMPLETE)
577     {
578         /* Authorizes the small information block programming */
579         FLASH->OPTKEYR = FLASH_KEY1;
580         FLASH->OPTKEYR = FLASH_KEY2;
581         FLASH->AR = 0x1ffff800;
582         FLASH->CR |= CR_OPTER_Set;
583         FLASH->CR |= CR_STRT_Set;
584         /* Wait for last operation to be completed */
585         status = FLASH_WaitForLastOperation(EraseTimeout);
586         if(status == FLASH_COMPLETE)
587         {
588             /* if the erase operation is completed, disable the OPTER Bit */
589             FLASH->CR &= CR_OPTER_Reset;
590             /* Enable the Option Bytes Programming operation */
591             FLASH->CR |= CR_OPTPG_Set;
592             if(NewState != DISABLE)
593             {
594                 OB->RDP = 0x00;
595             }
596             else
597             {
598                 OB->RDP = RDP_Key;
599             }
600             /* Wait for last operation to be completed */
601             status = FLASH_WaitForLastOperation(EraseTimeout);
602 
603             if(status != FLASH_BUSY)
604             {
605                 /* if the program operation is completed, disable the OPTPG Bit */
606                 FLASH->CR &= CR_OPTPG_Reset;
607             }
608         }
609         else
610         {
611             if(status != FLASH_BUSY)
612             {
613                 /* Disable the OPTER Bit */
614                 FLASH->CR &= CR_OPTER_Reset;
615             }
616         }
617     }
618 
619 
620 
621     /* Return the protection operation Status */
622     return status;
623 }
624 
625 /**
626 * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP /
627 *   RST_STDBY.
628 * @param OB_IWDG: Selects the IWDG mode
629 *   This parameter can be one of the following values:
630 * @arg OB_IWDG_SW: Software IWDG selected
631 * @arg OB_IWDG_HW: Hardware IWDG selected
632 * @param OB_STOP: Reset event when entering STOP mode.
633 *   This parameter can be one of the following values:
634 * @arg OB_STOP_NoRST: No reset generated when entering in STOP
635 * @arg OB_STOP_RST: Reset generated when entering in STOP
636 * @param OB_STDBY: Reset event when entering Standby mode.
637 *   This parameter can be one of the following values:
638 * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY
639 * @arg OB_STDBY_RST: Reset generated when entering in STANDBY
640 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
641 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
642 *   FLASH_TIMEOUT.
643 */
FLASH_UserOptionByteConfig(uint16_t OB_IWDG,uint16_t OB_STOP,uint16_t OB_STDBY)644 FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY)
645 {
646     FLASH_Status status = FLASH_COMPLETE;
647     /* Check the parameters */
648     assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
649     assert_param(IS_OB_STOP_SOURCE(OB_STOP));
650     assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
651 
652 
653 
654     /* Authorize the small information block programming */
655     FLASH->OPTKEYR = FLASH_KEY1;
656     FLASH->OPTKEYR = FLASH_KEY2;
657 
658     /* Wait for last operation to be completed */
659     status = FLASH_WaitForLastOperation(ProgramTimeout);
660 
661     if(status == FLASH_COMPLETE)
662     {
663         /* Enable the Option Bytes Programming operation */
664         FLASH->CR |= CR_OPTPG_Set;
665 
666         OB->USER = ( OB_IWDG | OB_STOP | OB_STDBY) | (uint16_t)0xF8;
667 
668         /* Wait for last operation to be completed */
669         status = FLASH_WaitForLastOperation(ProgramTimeout);
670         if(status != FLASH_BUSY)
671         {
672             /* if the program operation is completed, disable the OPTPG Bit */
673             FLASH->CR &= CR_OPTPG_Reset;
674         }
675     }
676 
677 
678 
679     /* Return the Option Byte program Status */
680     return status;
681 }
682 
683 /**
684 * @brief  Returns the FLASH User Option Bytes values.
685 * @param  None
686 * @retval : The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
687 *   and RST_STDBY(Bit2).
688 */
FLASH_GetUserOptionByte(void)689 uint32_t FLASH_GetUserOptionByte(void)
690 {
691     /* Return the User Option Byte */
692     return (uint32_t)(FLASH->OBR >> 2);
693 }
694 
695 /**
696 * @brief  Returns the FLASH Write Protection Option Bytes Register value.
697 * @param  None
698 * @retval : The FLASH Write Protection  Option Bytes Register value
699 */
FLASH_GetWriteProtectionOptionByte(void)700 uint32_t FLASH_GetWriteProtectionOptionByte(void)
701 {
702     /* Return the Falsh write protection Register value */
703     return (uint32_t)(FLASH->WRPR);
704 }
705 
706 /**
707 * @brief  Checks whether the FLASH Read Out Protection Status is set
708 *   or not.
709 * @param  None
710 * @retval : FLASH ReadOut Protection Status(SET or RESET)
711 */
FLASH_GetReadOutProtectionStatus(void)712 FlagStatus FLASH_GetReadOutProtectionStatus(void)
713 {
714     FlagStatus readoutstatus = RESET;
715     if ((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)
716     {
717         readoutstatus = SET;
718     }
719     else
720     {
721         readoutstatus = RESET;
722     }
723     return readoutstatus;
724 }
725 
726 /**
727 * @brief  Checks whether the FLASH Prefetch Buffer status is set or not.
728 * @param  None
729 * @retval : FLASH Prefetch Buffer Status (SET or RESET).
730 */
FLASH_GetPrefetchBufferStatus(void)731 FlagStatus FLASH_GetPrefetchBufferStatus(void)
732 {
733     FlagStatus bitstatus = RESET;
734 
735     if ((FLASH->ACR & ACR_PRFTBS_Mask) != (uint32_t)RESET)
736     {
737         bitstatus = SET;
738     }
739     else
740     {
741         bitstatus = RESET;
742     }
743     /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */
744     return bitstatus;
745 }
746 
747 /**
748 * @brief  Enables or disables the specified FLASH interrupts.
749 * @param FLASH_IT: specifies the FLASH interrupt sources to be
750 *   enabled or disabled.
751 *   This parameter can be any combination of the following values:
752 * @arg FLASH_IT_ERROR: FLASH Error Interrupt
753 * @arg FLASH_IT_EOP: FLASH end of operation Interrupt
754 * @param NewState: new state of the specified Flash interrupts.
755 *   This parameter can be: ENABLE or DISABLE.
756 * @retval : None
757 */
FLASH_ITConfig(uint16_t FLASH_IT,FunctionalState NewState)758 void FLASH_ITConfig(uint16_t FLASH_IT, FunctionalState NewState)
759 {
760     /* Check the parameters */
761     assert_param(IS_FLASH_IT(FLASH_IT));
762     assert_param(IS_FUNCTIONAL_STATE(NewState));
763     if(NewState != DISABLE)
764     {
765         /* Enable the interrupt sources */
766         FLASH->CR |= FLASH_IT;
767     }
768     else
769     {
770         /* Disable the interrupt sources */
771         FLASH->CR &= ~(uint32_t)FLASH_IT;
772     }
773 }
774 
775 /**
776 * @brief  Checks whether the specified FLASH flag is set or not.
777 * @param FLASH_FLAG: specifies the FLASH flag to check.
778 *   This parameter can be one of the following values:
779 * @arg FLASH_FLAG_BSY: FLASH Busy flag
780 * @arg FLASH_FLAG_PGERR: FLASH Program error flag
781 * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
782 * @arg FLASH_FLAG_EOP: FLASH End of Operation flag
783 * @arg FLASH_FLAG_OPTERR:  FLASH Option Byte error flag
784 * @retval : The new state of FLASH_FLAG (SET or RESET).
785 */
FLASH_GetFlagStatus(uint16_t FLASH_FLAG)786 FlagStatus FLASH_GetFlagStatus(uint16_t FLASH_FLAG)
787 {
788     FlagStatus bitstatus = RESET;
789     /* Check the parameters */
790     assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ;
791     if(FLASH_FLAG == FLASH_FLAG_OPTERR)
792     {
793         if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)
794         {
795             bitstatus = SET;
796         }
797         else
798         {
799             bitstatus = RESET;
800         }
801     }
802     else
803     {
804         if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
805         {
806             bitstatus = SET;
807         }
808         else
809         {
810             bitstatus = RESET;
811         }
812     }
813     /* Return the new state of FLASH_FLAG (SET or RESET) */
814     return bitstatus;
815 }
816 
817 /**
818 * @brief  Clears the FLASH�s pending flags.
819 * @param FLASH_FLAG: specifies the FLASH flags to clear.
820 *   This parameter can be any combination of the following values:
821 * @arg FLASH_FLAG_BSY: FLASH Busy flag
822 * @arg FLASH_FLAG_PGERR: FLASH Program error flag
823 * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
824 * @arg FLASH_FLAG_EOP: FLASH End of Operation flag
825 * @retval : None
826 */
FLASH_ClearFlag(uint16_t FLASH_FLAG)827 void FLASH_ClearFlag(uint16_t FLASH_FLAG)
828 {
829     /* Check the parameters */
830     assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;
831 
832     /* Clear the flags */
833     FLASH->SR = FLASH_FLAG;
834 }
835 
836 /**
837 * @brief  Returns the FLASH Status.
838 * @param  None
839 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
840 *   FLASH_ERROR_PG, FLASH_ERROR_WRP or FLASH_COMPLETE
841 */
FLASH_GetStatus(void)842 FLASH_Status FLASH_GetStatus(void)
843 {
844     FLASH_Status flashstatus = FLASH_COMPLETE;
845 
846     if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
847     {
848         flashstatus = FLASH_BUSY;
849     }
850     else
851     {
852         if(FLASH->SR & FLASH_FLAG_PGERR)
853         {
854             flashstatus = FLASH_ERROR_PG;
855         }
856         else
857         {
858             if(FLASH->SR & FLASH_FLAG_WRPRTERR)
859             {
860                 flashstatus = FLASH_ERROR_WRP;
861             }
862             else
863             {
864                 flashstatus = FLASH_COMPLETE;
865             }
866         }
867     }
868     /* Return the Flash Status */
869     return flashstatus;
870 }
871 
872 /**
873 * @brief  Waits for a Flash operation to complete or a TIMEOUT to occur.
874 * @param Timeout: FLASH progamming Timeout
875 * @retval : FLASH Status: The returned value can be: FLASH_BUSY,
876 *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or
877 *   FLASH_TIMEOUT.
878 */
FLASH_WaitForLastOperation(uint32_t Timeout)879 FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
880 {
881     FLASH_Status status = FLASH_COMPLETE;
882 
883 
884 
885     /* Check for the Flash Status */
886     status = FLASH_GetStatus();
887     /* Wait for a Flash operation to complete or a TIMEOUT to occur */
888     while((status == FLASH_BUSY) && (Timeout != 0x00))
889     {
890         delay();
891         status = FLASH_GetStatus();
892         Timeout--;
893     }
894     if(Timeout == 0x00 )
895     {
896         status = FLASH_TIMEOUT;
897     }
898 
899 
900 
901     /* Return the operation status */
902     return status;
903 }
904 
905 /**
906 * @brief  Inserts a time delay.
907 * @param  None
908 * @retval : None
909 */
delay(void)910 static void delay(void)
911 {
912     __IO uint32_t i = 0;
913     for(i = 0xFF; i != 0; i--)
914     {
915     }
916 }
917 
918 /**
919 * @}
920 */
921 
922 /**
923 * @}
924 */
925 
926 /**
927 * @}
928 */
929 
930 /*-------------------------(C) COPYRIGHT 2019 MindMotion ----------------------*/
931