1 /**
2   ******************************************************************************
3   * @file    stm32f3xx_hal_flash_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended FLASH HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the FLASH peripheral:
9   *           + Extended Initialization/de-initialization functions
10   *           + Extended I/O operation functions
11   *           + Extended Peripheral Control functions
12   *
13   @verbatim
14   ==============================================================================
15                ##### Flash peripheral extended features  #####
16   ==============================================================================
17 
18                       ##### How to use this driver #####
19   ==============================================================================
20   [..] This driver provides functions to configure and program the FLASH memory
21        of all STM32F3xxx devices. It includes
22 
23         (++) Set/Reset the write protection
24         (++) Program the user Option Bytes
25         (++) Get the Read protection Level
26 
27   @endverbatim
28   ******************************************************************************
29   * @attention
30   *
31   * Copyright (c) 2016 STMicroelectronics.
32   * All rights reserved.
33   *
34   * This software is licensed under terms that can be found in the LICENSE file in
35   * the root directory of this software component.
36   * If no LICENSE file comes with this software, it is provided AS-IS.
37   ******************************************************************************
38   */
39 
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32f3xx_hal.h"
42 
43 /** @addtogroup STM32F3xx_HAL_Driver
44   * @{
45   */
46 #ifdef HAL_FLASH_MODULE_ENABLED
47 
48 /** @addtogroup FLASH
49   * @{
50   */
51 /** @addtogroup FLASH_Private_Variables
52  * @{
53  */
54 /* Variables used for Erase pages under interruption*/
55 extern FLASH_ProcessTypeDef pFlash;
56 /**
57   * @}
58   */
59 
60 /**
61   * @}
62   */
63 
64 /** @defgroup FLASHEx FLASHEx
65   * @brief FLASH HAL Extension module driver
66   * @{
67   */
68 
69 /* Private typedef -----------------------------------------------------------*/
70 /* Private define ------------------------------------------------------------*/
71 /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
72  * @{
73  */
74 #define FLASH_POSITION_IWDGSW_BIT        (uint32_t)POSITION_VAL(FLASH_OBR_IWDG_SW)
75 #define FLASH_POSITION_OB_USERDATA0_BIT  (uint32_t)POSITION_VAL(FLASH_OBR_DATA0)
76 #define FLASH_POSITION_OB_USERDATA1_BIT  (uint32_t)POSITION_VAL(FLASH_OBR_DATA1)
77 /**
78   * @}
79   */
80 
81 /* Private macro -------------------------------------------------------------*/
82 /** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
83   * @{
84   */
85 /**
86   * @}
87   */
88 
89 /* Private variables ---------------------------------------------------------*/
90 /* Private function prototypes -----------------------------------------------*/
91 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
92  * @{
93  */
94 /* Erase operations */
95 static void              FLASH_MassErase(void);
96 void    FLASH_PageErase(uint32_t PageAddress);
97 
98 /* Option bytes control */
99 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage);
100 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage);
101 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel);
102 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
103 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
104 static uint32_t          FLASH_OB_GetWRP(void);
105 static uint32_t          FLASH_OB_GetRDP(void);
106 static uint8_t           FLASH_OB_GetUser(void);
107 
108 /**
109   * @}
110   */
111 
112 /* Exported functions ---------------------------------------------------------*/
113 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
114   * @{
115   */
116 
117 /** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
118  *  @brief   FLASH Memory Erasing functions
119   *
120 @verbatim
121   ==============================================================================
122                 ##### FLASH Erasing Programming functions #####
123   ==============================================================================
124 
125     [..] The FLASH Memory Erasing functions, includes the following functions:
126     (+) HAL_FLASHEx_Erase: return only when erase has been done
127     (+) HAL_FLASHEx_Erase_IT: end of erase is done when HAL_FLASH_EndOfOperationCallback
128         is called with parameter 0xFFFFFFFF
129 
130     [..] Any operation of erase should follow these steps:
131     (#) Call the HAL_FLASH_Unlock() function to enable the flash control register and
132         program memory access.
133     (#) Call the desired function to erase page.
134     (#) Call the HAL_FLASH_Lock() to disable the flash program memory access
135        (recommended to protect the FLASH memory against possible unwanted operation).
136 
137 @endverbatim
138   * @{
139   */
140 
141 
142 /**
143   * @brief  Perform a mass erase or erase the specified FLASH memory pages
144   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
145   *         must be called before.
146   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
147   *         (recommended to protect the FLASH memory against possible unwanted operation)
148   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
149   *         contains the configuration information for the erasing.
150   *
151   * @param[out]  PageError pointer to variable  that
152   *         contains the configuration information on faulty page in case of error
153   *         (0xFFFFFFFF means that all the pages have been correctly erased)
154   *
155   * @retval HAL_StatusTypeDef HAL Status
156   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)157 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
158 {
159   HAL_StatusTypeDef status = HAL_ERROR;
160   uint32_t address = 0U;
161 
162   /* Process Locked */
163   __HAL_LOCK(&pFlash);
164 
165   /* Check the parameters */
166   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
167 
168   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
169   {
170       /* Mass Erase requested for Bank1 */
171       /* Wait for last operation to be completed */
172       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
173       {
174         /*Mass erase to be done*/
175         FLASH_MassErase();
176 
177         /* Wait for last operation to be completed */
178         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
179 
180         /* If the erase operation is completed, disable the MER Bit */
181         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
182       }
183   }
184   else
185   {
186     /* Page Erase is requested */
187     /* Check the parameters */
188     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
189     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
190 
191       /* Page Erase requested on address located on bank1 */
192       /* Wait for last operation to be completed */
193       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
194       {
195         /*Initialization of PageError variable*/
196         *PageError = 0xFFFFFFFFU;
197 
198         /* Erase page by page to be done*/
199         for(address = pEraseInit->PageAddress;
200             address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
201             address += FLASH_PAGE_SIZE)
202         {
203           FLASH_PageErase(address);
204 
205           /* Wait for last operation to be completed */
206           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
207 
208           /* If the erase operation is completed, disable the PER Bit */
209           CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
210 
211           if (status != HAL_OK)
212           {
213             /* In case of error, stop erase procedure and return the faulty address */
214             *PageError = address;
215             break;
216           }
217         }
218       }
219   }
220 
221   /* Process Unlocked */
222   __HAL_UNLOCK(&pFlash);
223 
224   return status;
225 }
226 
227 /**
228   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
229   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
230   *         must be called before.
231   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
232   *         (recommended to protect the FLASH memory against possible unwanted operation)
233   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
234   *         contains the configuration information for the erasing.
235   *
236   * @retval HAL_StatusTypeDef HAL Status
237   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)238 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
239 {
240   HAL_StatusTypeDef status = HAL_OK;
241 
242   /* Process Locked */
243   __HAL_LOCK(&pFlash);
244 
245   /* If procedure already ongoing, reject the next one */
246   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
247   {
248     return HAL_ERROR;
249   }
250 
251   /* Check the parameters */
252   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
253 
254   /* Enable End of FLASH Operation and Error source interrupts */
255   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
256 
257   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
258   {
259     /*Mass erase to be done*/
260     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
261         FLASH_MassErase();
262   }
263   else
264   {
265     /* Erase by page to be done*/
266 
267     /* Check the parameters */
268     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
269     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
270 
271     pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
272     pFlash.DataRemaining = pEraseInit->NbPages;
273     pFlash.Address = pEraseInit->PageAddress;
274 
275     /*Erase 1st page and wait for IT*/
276     FLASH_PageErase(pEraseInit->PageAddress);
277   }
278 
279   return status;
280 }
281 
282 /**
283   * @}
284   */
285 
286 /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
287  *  @brief   Option Bytes Programming functions
288   *
289 @verbatim
290   ==============================================================================
291                 ##### Option Bytes Programming functions #####
292   ==============================================================================
293     [..]
294     This subsection provides a set of functions allowing to control the FLASH
295     option bytes operations.
296 
297 @endverbatim
298   * @{
299   */
300 
301 /**
302   * @brief  Erases the FLASH option bytes.
303   * @note   This functions erases all option bytes except the Read protection (RDP).
304   *         The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
305   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
306   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
307   *         (system reset will occur)
308   * @retval HAL status
309   */
310 
HAL_FLASHEx_OBErase(void)311 HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
312 {
313   uint8_t rdptmp = OB_RDP_LEVEL_0;
314   HAL_StatusTypeDef status = HAL_ERROR;
315 
316   /* Get the actual read protection Option Byte value */
317   rdptmp = FLASH_OB_GetRDP();
318 
319   /* Wait for last operation to be completed */
320   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
321 
322   if(status == HAL_OK)
323   {
324     /* Clean the error context */
325     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
326 
327     /* If the previous operation is completed, proceed to erase the option bytes */
328     SET_BIT(FLASH->CR, FLASH_CR_OPTER);
329     SET_BIT(FLASH->CR, FLASH_CR_STRT);
330 
331     /* Wait for last operation to be completed */
332     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
333 
334     /* If the erase operation is completed, disable the OPTER Bit */
335     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
336 
337     if(status == HAL_OK)
338     {
339       /* Restore the last read protection Option Byte value */
340       status = FLASH_OB_RDP_LevelConfig(rdptmp);
341     }
342   }
343 
344   /* Return the erase status */
345   return status;
346 }
347 
348 /**
349   * @brief  Program option bytes
350   * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
351   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
352   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
353   *         (system reset will occur)
354   *
355   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
356   *         contains the configuration information for the programming.
357   *
358   * @retval HAL_StatusTypeDef HAL Status
359   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)360 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
361 {
362   HAL_StatusTypeDef status = HAL_ERROR;
363 
364   /* Process Locked */
365   __HAL_LOCK(&pFlash);
366 
367   /* Check the parameters */
368   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
369 
370   /* Write protection configuration */
371   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
372   {
373     assert_param(IS_WRPSTATE(pOBInit->WRPState));
374     if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
375     {
376       /* Enable of Write protection on the selected page */
377       status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
378     }
379     else
380     {
381       /* Disable of Write protection on the selected page */
382       status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
383     }
384     if (status != HAL_OK)
385     {
386       /* Process Unlocked */
387       __HAL_UNLOCK(&pFlash);
388       return status;
389     }
390   }
391 
392   /* Read protection configuration */
393   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
394   {
395     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
396     if (status != HAL_OK)
397     {
398       /* Process Unlocked */
399       __HAL_UNLOCK(&pFlash);
400       return status;
401     }
402   }
403 
404   /* USER configuration */
405   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
406   {
407     status = FLASH_OB_UserConfig(pOBInit->USERConfig);
408     if (status != HAL_OK)
409     {
410       /* Process Unlocked */
411       __HAL_UNLOCK(&pFlash);
412       return status;
413     }
414   }
415 
416   /* DATA configuration*/
417   if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
418   {
419     status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
420     if (status != HAL_OK)
421     {
422       /* Process Unlocked */
423       __HAL_UNLOCK(&pFlash);
424       return status;
425     }
426   }
427 
428   /* Process Unlocked */
429   __HAL_UNLOCK(&pFlash);
430 
431   return status;
432 }
433 
434 /**
435   * @brief  Get the Option byte configuration
436   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
437   *         contains the configuration information for the programming.
438   *
439   * @retval None
440   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)441 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
442 {
443   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
444 
445   /*Get WRP*/
446   pOBInit->WRPPage = FLASH_OB_GetWRP();
447 
448   /*Get RDP Level*/
449   pOBInit->RDPLevel = FLASH_OB_GetRDP();
450 
451   /*Get USER*/
452   pOBInit->USERConfig = FLASH_OB_GetUser();
453 }
454 
455 /**
456   * @brief  Get the Option byte user data
457   * @param  DATAAdress Address of the option byte DATA
458   *          This parameter can be one of the following values:
459   *            @arg @ref OB_DATA_ADDRESS_DATA0
460   *            @arg @ref OB_DATA_ADDRESS_DATA1
461   * @retval Value programmed in USER data
462   */
HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)463 uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
464 {
465   uint32_t value = 0U;
466 
467   if (DATAAdress == OB_DATA_ADDRESS_DATA0)
468   {
469     /* Get value programmed in OB USER Data0 */
470     value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
471   }
472   else
473   {
474     /* Get value programmed in OB USER Data1 */
475     value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
476   }
477 
478   return value;
479 }
480 
481 /**
482   * @}
483   */
484 
485 /**
486   * @}
487   */
488 
489 /** @addtogroup FLASHEx_Private_Functions
490  * @{
491  */
492 
493 /**
494   * @brief  Full erase of FLASH memory Bank
495   *
496   * @retval None
497   */
FLASH_MassErase(void)498 static void FLASH_MassErase(void)
499 {
500   /* Clean the error context */
501   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
502 
503     /* Only bank1 will be erased*/
504     SET_BIT(FLASH->CR, FLASH_CR_MER);
505     SET_BIT(FLASH->CR, FLASH_CR_STRT);
506 }
507 
508 /**
509   * @brief  Enable the write protection of the desired pages
510   * @note   An option byte erase is done automatically in this function.
511   * @note   When the memory read protection level is selected (RDP level = 1),
512   *         it is not possible to program or erase the flash page i if
513   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
514   *
515   * @param  WriteProtectPage specifies the page(s) to be write protected.
516   *         The value of this parameter depend on device used within the same series
517   * @retval HAL status
518   */
FLASH_OB_EnableWRP(uint32_t WriteProtectPage)519 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
520 {
521   HAL_StatusTypeDef status = HAL_OK;
522   uint16_t WRP0_Data = 0xFFFFU;
523 #if defined(OB_WRP1_WRP1)
524   uint16_t WRP1_Data = 0xFFFFU;
525 #endif /* OB_WRP1_WRP1 */
526 #if defined(OB_WRP2_WRP2)
527   uint16_t WRP2_Data = 0xFFFFU;
528 #endif /* OB_WRP2_WRP2 */
529 #if defined(OB_WRP3_WRP3)
530   uint16_t WRP3_Data = 0xFFFFU;
531 #endif /* OB_WRP3_WRP3 */
532 
533   /* Check the parameters */
534   assert_param(IS_OB_WRP(WriteProtectPage));
535 
536   /* Get current write protected pages and the new pages to be protected ******/
537   WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
538 
539 #if defined(OB_WRP_PAGES0TO15MASK)
540   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
541 #endif /* OB_WRP_PAGES0TO31MASK */
542 
543 #if defined(OB_WRP_PAGES16TO31MASK)
544   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
545 #endif /* OB_WRP_PAGES32TO63MASK */
546 
547 #if defined(OB_WRP_PAGES32TO47MASK)
548   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
549 #endif /* OB_WRP_PAGES32TO47MASK */
550 
551 #if defined(OB_WRP_PAGES48TO127MASK)
552   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
553 #elif defined(OB_WRP_PAGES48TO255MASK)
554   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
555 #endif /* OB_WRP_PAGES48TO63MASK */
556 
557   /* Wait for last operation to be completed */
558   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
559 
560   if(status == HAL_OK)
561   {
562     /* Clean the error context */
563     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
564 
565     /* To be able to write again option byte, need to perform a option byte erase */
566     status = HAL_FLASHEx_OBErase();
567     if (status == HAL_OK)
568     {
569       /* Enable write protection */
570       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
571 
572 #if defined(OB_WRP0_WRP0)
573       if(WRP0_Data != 0xFFU)
574       {
575         OB->WRP0 &= WRP0_Data;
576 
577         /* Wait for last operation to be completed */
578         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
579       }
580 #endif /* OB_WRP0_WRP0 */
581 
582 #if defined(OB_WRP1_WRP1)
583       if((status == HAL_OK) && (WRP1_Data != 0xFFU))
584       {
585         OB->WRP1 &= WRP1_Data;
586 
587         /* Wait for last operation to be completed */
588         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
589       }
590 #endif /* OB_WRP1_WRP1 */
591 
592 #if defined(OB_WRP2_WRP2)
593       if((status == HAL_OK) && (WRP2_Data != 0xFFU))
594       {
595         OB->WRP2 &= WRP2_Data;
596 
597         /* Wait for last operation to be completed */
598         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
599       }
600 #endif /* OB_WRP2_WRP2 */
601 
602 #if defined(OB_WRP3_WRP3)
603       if((status == HAL_OK) && (WRP3_Data != 0xFFU))
604       {
605         OB->WRP3 &= WRP3_Data;
606 
607         /* Wait for last operation to be completed */
608         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
609       }
610 #endif /* OB_WRP3_WRP3 */
611 
612       /* if the program operation is completed, disable the OPTPG Bit */
613       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
614     }
615   }
616 
617   return status;
618 }
619 
620 /**
621   * @brief  Disable the write protection of the desired pages
622   * @note   An option byte erase is done automatically in this function.
623   * @note   When the memory read protection level is selected (RDP level = 1),
624   *         it is not possible to program or erase the flash page i if
625   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
626   *
627   * @param  WriteProtectPage specifies the page(s) to be write unprotected.
628   *         The value of this parameter depend on device used within the same series
629   * @retval HAL status
630   */
FLASH_OB_DisableWRP(uint32_t WriteProtectPage)631 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
632 {
633   HAL_StatusTypeDef status = HAL_OK;
634   uint16_t WRP0_Data = 0xFFFFU;
635 #if defined(OB_WRP1_WRP1)
636   uint16_t WRP1_Data = 0xFFFFU;
637 #endif /* OB_WRP1_WRP1 */
638 #if defined(OB_WRP2_WRP2)
639   uint16_t WRP2_Data = 0xFFFFU;
640 #endif /* OB_WRP2_WRP2 */
641 #if defined(OB_WRP3_WRP3)
642   uint16_t WRP3_Data = 0xFFFFU;
643 #endif /* OB_WRP3_WRP3 */
644 
645   /* Check the parameters */
646   assert_param(IS_OB_WRP(WriteProtectPage));
647 
648   /* Get current write protected pages and the new pages to be unprotected ******/
649   WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
650 
651 #if defined(OB_WRP_PAGES0TO15MASK)
652   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
653 #endif /* OB_WRP_PAGES0TO31MASK */
654 
655 #if defined(OB_WRP_PAGES16TO31MASK)
656   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
657 #endif /* OB_WRP_PAGES32TO63MASK */
658 
659 #if defined(OB_WRP_PAGES32TO47MASK)
660   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
661 #endif /* OB_WRP_PAGES32TO47MASK */
662 
663 #if defined(OB_WRP_PAGES48TO127MASK)
664   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
665 #elif defined(OB_WRP_PAGES48TO255MASK)
666   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
667 #endif /* OB_WRP_PAGES48TO63MASK */
668 
669 
670   /* Wait for last operation to be completed */
671   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
672 
673   if(status == HAL_OK)
674   {
675     /* Clean the error context */
676     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
677 
678     /* To be able to write again option byte, need to perform a option byte erase */
679     status = HAL_FLASHEx_OBErase();
680     if (status == HAL_OK)
681     {
682       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
683 
684 #if defined(OB_WRP0_WRP0)
685       if(WRP0_Data != 0xFFU)
686       {
687         OB->WRP0 |= WRP0_Data;
688 
689         /* Wait for last operation to be completed */
690         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
691       }
692 #endif /* OB_WRP0_WRP0 */
693 
694 #if defined(OB_WRP1_WRP1)
695       if((status == HAL_OK) && (WRP1_Data != 0xFFU))
696       {
697         OB->WRP1 |= WRP1_Data;
698 
699         /* Wait for last operation to be completed */
700         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
701       }
702 #endif /* OB_WRP1_WRP1 */
703 
704 #if defined(OB_WRP2_WRP2)
705       if((status == HAL_OK) && (WRP2_Data != 0xFFU))
706       {
707         OB->WRP2 |= WRP2_Data;
708 
709         /* Wait for last operation to be completed */
710         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
711       }
712 #endif /* OB_WRP2_WRP2 */
713 
714 #if defined(OB_WRP3_WRP3)
715       if((status == HAL_OK) && (WRP3_Data != 0xFFU))
716       {
717         OB->WRP3 |= WRP3_Data;
718 
719         /* Wait for last operation to be completed */
720         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
721       }
722 #endif /* OB_WRP3_WRP3 */
723 
724       /* if the program operation is completed, disable the OPTPG Bit */
725       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
726     }
727   }
728   return status;
729 }
730 
731 /**
732   * @brief  Set the read protection level.
733   * @param  ReadProtectLevel specifies the read protection level.
734   *         This parameter can be one of the following values:
735   *            @arg @ref OB_RDP_LEVEL_0 No protection
736   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
737   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
738   * @note   Warning: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
739   * @retval HAL status
740   */
FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)741 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
742 {
743   HAL_StatusTypeDef status = HAL_OK;
744 
745   /* Check the parameters */
746   assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
747 
748   /* Wait for last operation to be completed */
749   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
750 
751   if(status == HAL_OK)
752   {
753     /* Clean the error context */
754     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
755 
756     /* If the previous operation is completed, proceed to erase the option bytes */
757     SET_BIT(FLASH->CR, FLASH_CR_OPTER);
758     SET_BIT(FLASH->CR, FLASH_CR_STRT);
759 
760     /* Wait for last operation to be completed */
761     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
762 
763     /* If the erase operation is completed, disable the OPTER Bit */
764     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
765 
766     if(status == HAL_OK)
767     {
768       /* Enable the Option Bytes Programming operation */
769       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
770 
771       WRITE_REG(OB->RDP, ReadProtectLevel);
772 
773       /* Wait for last operation to be completed */
774       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
775 
776       /* if the program operation is completed, disable the OPTPG Bit */
777       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
778     }
779   }
780 
781   return status;
782 }
783 
784 /**
785   * @brief  Program the FLASH User Option Byte.
786   * @note   Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
787   * @param  UserConfig The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1), RST_STDBY(Bit2), nBOOT1(Bit4),
788   *         VDDA_Analog_Monitoring(Bit5) and SRAM_Parity_Enable(Bit6).
789   *         And SDADC12_VDD_MONITOR(Bit7) for STM32F373 or STM32F378 .
790   * @retval HAL status
791   */
FLASH_OB_UserConfig(uint8_t UserConfig)792 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
793 {
794   HAL_StatusTypeDef status = HAL_OK;
795 
796   /* Check the parameters */
797   assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
798   assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
799   assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
800   assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
801   assert_param(IS_OB_VDDA_ANALOG((UserConfig&OB_VDDA_ANALOG_ON)));
802   assert_param(IS_OB_SRAM_PARITY((UserConfig&OB_SRAM_PARITY_RESET)));
803 #if defined(FLASH_OBR_SDADC12_VDD_MONITOR)
804   assert_param(IS_OB_SDACD_VDD_MONITOR((UserConfig&OB_SDACD_VDD_MONITOR_SET)));
805 #endif /* FLASH_OBR_SDADC12_VDD_MONITOR */
806 
807   /* Wait for last operation to be completed */
808   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
809 
810   if(status == HAL_OK)
811   {
812     /* Clean the error context */
813     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
814 
815     /* Enable the Option Bytes Programming operation */
816     SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
817 
818 #if   defined(FLASH_OBR_SDADC12_VDD_MONITOR)
819     OB->USER = (UserConfig | 0x08U);
820 #else
821     OB->USER = (UserConfig | 0x88U);
822 #endif
823 
824     /* Wait for last operation to be completed */
825     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
826 
827     /* if the program operation is completed, disable the OPTPG Bit */
828     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
829   }
830 
831   return status;
832 }
833 
834 /**
835   * @brief  Programs a half word at a specified Option Byte Data address.
836   * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
837   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
838   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
839   *         (system reset will occur)
840   *         Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
841   * @param  Address specifies the address to be programmed.
842   *         This parameter can be 0x1FFFF804 or 0x1FFFF806.
843   * @param  Data specifies the data to be programmed.
844   * @retval HAL status
845   */
FLASH_OB_ProgramData(uint32_t Address,uint8_t Data)846 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
847 {
848   HAL_StatusTypeDef status = HAL_ERROR;
849 
850   /* Check the parameters */
851   assert_param(IS_OB_DATA_ADDRESS(Address));
852 
853   /* Wait for last operation to be completed */
854   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
855 
856   if(status == HAL_OK)
857   {
858     /* Clean the error context */
859     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
860 
861     /* Enables the Option Bytes Programming operation */
862     SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
863     *(__IO uint16_t*)Address = Data;
864 
865     /* Wait for last operation to be completed */
866     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
867 
868     /* If the program operation is completed, disable the OPTPG Bit */
869     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
870   }
871   /* Return the Option Byte Data Program Status */
872   return status;
873 }
874 
875 /**
876   * @brief  Return the FLASH Write Protection Option Bytes value.
877   * @retval The FLASH Write Protection Option Bytes value
878   */
FLASH_OB_GetWRP(void)879 static uint32_t FLASH_OB_GetWRP(void)
880 {
881   /* Return the FLASH write protection Register value */
882   return (uint32_t)(READ_REG(FLASH->WRPR));
883 }
884 
885 /**
886   * @brief  Returns the FLASH Read Protection level.
887   * @retval FLASH RDP level
888   *         This parameter can be one of the following values:
889   *            @arg @ref OB_RDP_LEVEL_0 No protection
890   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
891   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
892   */
FLASH_OB_GetRDP(void)893 static uint32_t FLASH_OB_GetRDP(void)
894 {
895   uint32_t tmp_reg = 0U;
896 
897   /* Read RDP level bits */
898 #if defined(FLASH_OBR_RDPRT)
899   tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
900 #elif defined(FLASH_OBR_LEVEL1_PROT)
901   tmp_reg = READ_BIT(FLASH->OBR, (FLASH_OBR_LEVEL1_PROT | FLASH_OBR_LEVEL2_PROT));
902 #endif /* FLASH_OBR_RDPRT */
903 
904 #if defined(FLASH_OBR_RDPRT)
905   if (tmp_reg == FLASH_OBR_RDPRT_2)
906 #elif defined(FLASH_OBR_LEVEL1_PROT)
907   if (tmp_reg == FLASH_OBR_LEVEL2_PROT)
908 #endif /* FLASH_OBR_RDPRT */
909   {
910     return OB_RDP_LEVEL_2;
911   }
912   else if (tmp_reg == 0U)
913   {
914     return OB_RDP_LEVEL_0;
915   }
916   else
917   {
918     return OB_RDP_LEVEL_1;
919   }
920 }
921 
922 /**
923   * @brief  Return the FLASH User Option Byte value.
924   * @retval  The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1), RST_STDBY(Bit2), nBOOT1(Bit4),
925   *         VDDA_Analog_Monitoring(Bit5) and SRAM_Parity_Enable(Bit6).
926   *         And SDADC12_VDD_MONITOR(Bit7) for STM32F373 or STM32F378 .
927   */
FLASH_OB_GetUser(void)928 static uint8_t FLASH_OB_GetUser(void)
929 {
930   /* Return the User Option Byte */
931   return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
932 }
933 
934 /**
935   * @}
936   */
937 
938 /**
939   * @}
940   */
941 
942 /** @addtogroup FLASH
943   * @{
944   */
945 
946 /** @addtogroup FLASH_Private_Functions
947  * @{
948  */
949 
950 /**
951   * @brief  Erase the specified FLASH memory page
952   * @param  PageAddress FLASH page to erase
953   *         The value of this parameter depend on device used within the same series
954   *
955   * @retval None
956   */
FLASH_PageErase(uint32_t PageAddress)957 void FLASH_PageErase(uint32_t PageAddress)
958 {
959   /* Clean the error context */
960   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
961 
962     /* Proceed to erase the page */
963     SET_BIT(FLASH->CR, FLASH_CR_PER);
964     WRITE_REG(FLASH->AR, PageAddress);
965     SET_BIT(FLASH->CR, FLASH_CR_STRT);
966 }
967 
968 /**
969   * @}
970   */
971 
972 /**
973   * @}
974   */
975 
976 #endif /* HAL_FLASH_MODULE_ENABLED */
977 /**
978   * @}
979   */
980 
981