1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_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 STM32F1xxx 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 "stm32f1xx_hal.h"
42 
43 /** @addtogroup STM32F1xx_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        FLASH_OBR_IWDG_SW_Pos
75 #define FLASH_POSITION_OB_USERDATA0_BIT  FLASH_OBR_DATA0_Pos
76 #define FLASH_POSITION_OB_USERDATA1_BIT  FLASH_OBR_DATA1_Pos
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(uint32_t Banks);
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 #if defined(FLASH_BANK2_END)
171     if (pEraseInit->Banks == FLASH_BANK_BOTH)
172     {
173       /* Mass Erase requested for Bank1 and Bank2 */
174       /* Wait for last operation to be completed */
175       if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
176           (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
177       {
178         /*Mass erase to be done*/
179         FLASH_MassErase(FLASH_BANK_BOTH);
180 
181         /* Wait for last operation to be completed */
182         if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
183             (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
184         {
185           status = HAL_OK;
186         }
187 
188         /* If the erase operation is completed, disable the MER Bit */
189         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
190         CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
191       }
192     }
193     else if (pEraseInit->Banks == FLASH_BANK_2)
194     {
195       /* Mass Erase requested for Bank2 */
196       /* Wait for last operation to be completed */
197       if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
198       {
199         /*Mass erase to be done*/
200         FLASH_MassErase(FLASH_BANK_2);
201 
202         /* Wait for last operation to be completed */
203         status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
204 
205         /* If the erase operation is completed, disable the MER Bit */
206         CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
207       }
208     }
209     else
210 #endif /* FLASH_BANK2_END */
211     {
212       /* Mass Erase requested for Bank1 */
213       /* Wait for last operation to be completed */
214       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
215       {
216         /*Mass erase to be done*/
217         FLASH_MassErase(FLASH_BANK_1);
218 
219         /* Wait for last operation to be completed */
220         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
221 
222         /* If the erase operation is completed, disable the MER Bit */
223         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
224       }
225     }
226   }
227   else
228   {
229     /* Page Erase is requested */
230     /* Check the parameters */
231     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
232     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
233 
234 #if defined(FLASH_BANK2_END)
235     /* Page Erase requested on address located on bank2 */
236     if(pEraseInit->PageAddress > FLASH_BANK1_END)
237     {
238       /* Wait for last operation to be completed */
239       if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
240       {
241         /*Initialization of PageError variable*/
242         *PageError = 0xFFFFFFFFU;
243 
244         /* Erase by page by page to be done*/
245         for(address = pEraseInit->PageAddress;
246             address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
247             address += FLASH_PAGE_SIZE)
248         {
249           FLASH_PageErase(address);
250 
251           /* Wait for last operation to be completed */
252           status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
253 
254           /* If the erase operation is completed, disable the PER Bit */
255           CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
256 
257           if (status != HAL_OK)
258           {
259             /* In case of error, stop erase procedure and return the faulty address */
260             *PageError = address;
261             break;
262           }
263         }
264       }
265     }
266     else
267 #endif /* FLASH_BANK2_END */
268    {
269       /* Page Erase requested on address located on bank1 */
270       /* Wait for last operation to be completed */
271       if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
272       {
273         /*Initialization of PageError variable*/
274         *PageError = 0xFFFFFFFFU;
275 
276         /* Erase page by page to be done*/
277         for(address = pEraseInit->PageAddress;
278             address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
279             address += FLASH_PAGE_SIZE)
280         {
281           FLASH_PageErase(address);
282 
283           /* Wait for last operation to be completed */
284           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
285 
286           /* If the erase operation is completed, disable the PER Bit */
287           CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
288 
289           if (status != HAL_OK)
290           {
291             /* In case of error, stop erase procedure and return the faulty address */
292             *PageError = address;
293             break;
294           }
295         }
296       }
297     }
298   }
299 
300   /* Process Unlocked */
301   __HAL_UNLOCK(&pFlash);
302 
303   return status;
304 }
305 
306 /**
307   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
308   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
309   *         must be called before.
310   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
311   *         (recommended to protect the FLASH memory against possible unwanted operation)
312   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
313   *         contains the configuration information for the erasing.
314   *
315   * @retval HAL_StatusTypeDef HAL Status
316   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)317 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
318 {
319   HAL_StatusTypeDef status = HAL_OK;
320 
321   /* If procedure already ongoing, reject the next one */
322   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
323   {
324     return HAL_ERROR;
325   }
326 
327   /* Check the parameters */
328   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
329 
330   /* Enable End of FLASH Operation and Error source interrupts */
331   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
332 
333 #if defined(FLASH_BANK2_END)
334   /* Enable End of FLASH Operation and Error source interrupts */
335   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
336 
337 #endif
338   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
339   {
340     /*Mass erase to be done*/
341     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
342         FLASH_MassErase(pEraseInit->Banks);
343   }
344   else
345   {
346     /* Erase by page to be done*/
347 
348     /* Check the parameters */
349     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
350     assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
351 
352     pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
353     pFlash.DataRemaining = pEraseInit->NbPages;
354     pFlash.Address = pEraseInit->PageAddress;
355 
356     /*Erase 1st page and wait for IT*/
357     FLASH_PageErase(pEraseInit->PageAddress);
358   }
359 
360   return status;
361 }
362 
363 /**
364   * @}
365   */
366 
367 /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
368  *  @brief   Option Bytes Programming functions
369   *
370 @verbatim
371   ==============================================================================
372                 ##### Option Bytes Programming functions #####
373   ==============================================================================
374     [..]
375     This subsection provides a set of functions allowing to control the FLASH
376     option bytes operations.
377 
378 @endverbatim
379   * @{
380   */
381 
382 /**
383   * @brief  Erases the FLASH option bytes.
384   * @note   This functions erases all option bytes except the Read protection (RDP).
385   *         The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
386   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
387   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
388   *         (system reset will occur)
389   * @retval HAL status
390   */
391 
HAL_FLASHEx_OBErase(void)392 HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
393 {
394   uint8_t rdptmp = OB_RDP_LEVEL_0;
395   HAL_StatusTypeDef status = HAL_ERROR;
396 
397   /* Get the actual read protection Option Byte value */
398   rdptmp = FLASH_OB_GetRDP();
399 
400   /* Wait for last operation to be completed */
401   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
402 
403   if(status == HAL_OK)
404   {
405     /* Clean the error context */
406     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
407 
408     /* If the previous operation is completed, proceed to erase the option bytes */
409     SET_BIT(FLASH->CR, FLASH_CR_OPTER);
410     SET_BIT(FLASH->CR, FLASH_CR_STRT);
411 
412     /* Wait for last operation to be completed */
413     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
414 
415     /* If the erase operation is completed, disable the OPTER Bit */
416     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
417 
418     if(status == HAL_OK)
419     {
420       /* Restore the last read protection Option Byte value */
421       status = FLASH_OB_RDP_LevelConfig(rdptmp);
422     }
423   }
424 
425   /* Return the erase status */
426   return status;
427 }
428 
429 /**
430   * @brief  Program option bytes
431   * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
432   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
433   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
434   *         (system reset will occur)
435   *
436   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
437   *         contains the configuration information for the programming.
438   *
439   * @retval HAL_StatusTypeDef HAL Status
440   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)441 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
442 {
443   HAL_StatusTypeDef status = HAL_ERROR;
444 
445   /* Process Locked */
446   __HAL_LOCK(&pFlash);
447 
448   /* Check the parameters */
449   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
450 
451   /* Write protection configuration */
452   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
453   {
454     assert_param(IS_WRPSTATE(pOBInit->WRPState));
455     if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
456     {
457       /* Enable of Write protection on the selected page */
458       status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
459     }
460     else
461     {
462       /* Disable of Write protection on the selected page */
463       status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
464     }
465     if (status != HAL_OK)
466     {
467       /* Process Unlocked */
468       __HAL_UNLOCK(&pFlash);
469       return status;
470     }
471   }
472 
473   /* Read protection configuration */
474   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
475   {
476     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
477     if (status != HAL_OK)
478     {
479       /* Process Unlocked */
480       __HAL_UNLOCK(&pFlash);
481       return status;
482     }
483   }
484 
485   /* USER configuration */
486   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
487   {
488     status = FLASH_OB_UserConfig(pOBInit->USERConfig);
489     if (status != HAL_OK)
490     {
491       /* Process Unlocked */
492       __HAL_UNLOCK(&pFlash);
493       return status;
494     }
495   }
496 
497   /* DATA configuration*/
498   if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
499   {
500     status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
501     if (status != HAL_OK)
502     {
503       /* Process Unlocked */
504       __HAL_UNLOCK(&pFlash);
505       return status;
506     }
507   }
508 
509   /* Process Unlocked */
510   __HAL_UNLOCK(&pFlash);
511 
512   return status;
513 }
514 
515 /**
516   * @brief  Get the Option byte configuration
517   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
518   *         contains the configuration information for the programming.
519   *
520   * @retval None
521   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)522 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
523 {
524   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
525 
526   /*Get WRP*/
527   pOBInit->WRPPage = FLASH_OB_GetWRP();
528 
529   /*Get RDP Level*/
530   pOBInit->RDPLevel = FLASH_OB_GetRDP();
531 
532   /*Get USER*/
533   pOBInit->USERConfig = FLASH_OB_GetUser();
534 }
535 
536 /**
537   * @brief  Get the Option byte user data
538   * @param  DATAAdress Address of the option byte DATA
539   *          This parameter can be one of the following values:
540   *            @arg @ref OB_DATA_ADDRESS_DATA0
541   *            @arg @ref OB_DATA_ADDRESS_DATA1
542   * @retval Value programmed in USER data
543   */
HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)544 uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
545 {
546   uint32_t value = 0;
547 
548   if (DATAAdress == OB_DATA_ADDRESS_DATA0)
549   {
550     /* Get value programmed in OB USER Data0 */
551     value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
552   }
553   else
554   {
555     /* Get value programmed in OB USER Data1 */
556     value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
557   }
558 
559   return value;
560 }
561 
562 /**
563   * @}
564   */
565 
566 /**
567   * @}
568   */
569 
570 /** @addtogroup FLASHEx_Private_Functions
571  * @{
572  */
573 
574 /**
575   * @brief  Full erase of FLASH memory Bank
576   * @param  Banks Banks to be erased
577   *          This parameter can be one of the following values:
578   *            @arg @ref FLASH_BANK_1 Bank1 to be erased
579   @if STM32F101xG
580   *            @arg @ref FLASH_BANK_2 Bank2 to be erased
581   *            @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
582   @endif
583   @if STM32F103xG
584   *            @arg @ref FLASH_BANK_2 Bank2 to be erased
585   *            @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
586   @endif
587   *
588   * @retval None
589   */
FLASH_MassErase(uint32_t Banks)590 static void FLASH_MassErase(uint32_t Banks)
591 {
592   /* Check the parameters */
593   assert_param(IS_FLASH_BANK(Banks));
594 
595   /* Clean the error context */
596   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
597 
598 #if defined(FLASH_BANK2_END)
599   if(Banks == FLASH_BANK_BOTH)
600   {
601     /* bank1 & bank2 will be erased*/
602     SET_BIT(FLASH->CR, FLASH_CR_MER);
603     SET_BIT(FLASH->CR2, FLASH_CR2_MER);
604     SET_BIT(FLASH->CR, FLASH_CR_STRT);
605     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
606   }
607   else if(Banks == FLASH_BANK_2)
608   {
609     /*Only bank2 will be erased*/
610     SET_BIT(FLASH->CR2, FLASH_CR2_MER);
611     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
612   }
613   else
614   {
615 #endif /* FLASH_BANK2_END */
616 #if !defined(FLASH_BANK2_END)
617   /* Prevent unused argument(s) compilation warning */
618   UNUSED(Banks);
619 #endif /* FLASH_BANK2_END */
620     /* Only bank1 will be erased*/
621     SET_BIT(FLASH->CR, FLASH_CR_MER);
622     SET_BIT(FLASH->CR, FLASH_CR_STRT);
623 #if defined(FLASH_BANK2_END)
624   }
625 #endif /* FLASH_BANK2_END */
626 }
627 
628 /**
629   * @brief  Enable the write protection of the desired pages
630   * @note   An option byte erase is done automatically in this function.
631   * @note   When the memory read protection level is selected (RDP level = 1),
632   *         it is not possible to program or erase the flash page i if
633   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
634   *
635   * @param  WriteProtectPage specifies the page(s) to be write protected.
636   *         The value of this parameter depend on device used within the same series
637   * @retval HAL status
638   */
FLASH_OB_EnableWRP(uint32_t WriteProtectPage)639 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
640 {
641   HAL_StatusTypeDef status = HAL_OK;
642   uint16_t WRP0_Data = 0xFFFF;
643 #if defined(FLASH_WRP1_WRP1)
644   uint16_t WRP1_Data = 0xFFFF;
645 #endif /* FLASH_WRP1_WRP1 */
646 #if defined(FLASH_WRP2_WRP2)
647   uint16_t WRP2_Data = 0xFFFF;
648 #endif /* FLASH_WRP2_WRP2 */
649 #if defined(FLASH_WRP3_WRP3)
650   uint16_t WRP3_Data = 0xFFFF;
651 #endif /* FLASH_WRP3_WRP3 */
652 
653   /* Check the parameters */
654   assert_param(IS_OB_WRP(WriteProtectPage));
655 
656   /* Get current write protected pages and the new pages to be protected ******/
657   WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
658 
659 #if defined(OB_WRP_PAGES0TO15MASK)
660   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
661 #elif defined(OB_WRP_PAGES0TO31MASK)
662   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
663 #endif /* OB_WRP_PAGES0TO31MASK */
664 
665 #if defined(OB_WRP_PAGES16TO31MASK)
666   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
667 #elif defined(OB_WRP_PAGES32TO63MASK)
668   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
669 #endif /* OB_WRP_PAGES32TO63MASK */
670 
671 #if defined(OB_WRP_PAGES64TO95MASK)
672   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
673 #endif /* OB_WRP_PAGES64TO95MASK */
674 #if defined(OB_WRP_PAGES32TO47MASK)
675   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
676 #endif /* OB_WRP_PAGES32TO47MASK */
677 
678 #if defined(OB_WRP_PAGES96TO127MASK)
679   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
680 #elif defined(OB_WRP_PAGES48TO255MASK)
681   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
682 #elif defined(OB_WRP_PAGES48TO511MASK)
683   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
684 #elif defined(OB_WRP_PAGES48TO127MASK)
685   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
686 #endif /* OB_WRP_PAGES96TO127MASK */
687 
688   /* Wait for last operation to be completed */
689   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
690 
691   if(status == HAL_OK)
692   {
693     /* Clean the error context */
694     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
695 
696     /* To be able to write again option byte, need to perform a option byte erase */
697     status = HAL_FLASHEx_OBErase();
698     if (status == HAL_OK)
699     {
700       /* Enable write protection */
701       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
702 
703 #if defined(FLASH_WRP0_WRP0)
704       if(WRP0_Data != 0xFFU)
705       {
706         OB->WRP0 &= WRP0_Data;
707 
708         /* Wait for last operation to be completed */
709         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
710       }
711 #endif /* FLASH_WRP0_WRP0 */
712 
713 #if defined(FLASH_WRP1_WRP1)
714       if((status == HAL_OK) && (WRP1_Data != 0xFFU))
715       {
716         OB->WRP1 &= WRP1_Data;
717 
718         /* Wait for last operation to be completed */
719         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
720       }
721 #endif /* FLASH_WRP1_WRP1 */
722 
723 #if defined(FLASH_WRP2_WRP2)
724       if((status == HAL_OK) && (WRP2_Data != 0xFFU))
725       {
726         OB->WRP2 &= WRP2_Data;
727 
728         /* Wait for last operation to be completed */
729         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
730       }
731 #endif /* FLASH_WRP2_WRP2 */
732 
733 #if defined(FLASH_WRP3_WRP3)
734       if((status == HAL_OK) && (WRP3_Data != 0xFFU))
735       {
736         OB->WRP3 &= WRP3_Data;
737 
738         /* Wait for last operation to be completed */
739         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
740       }
741 #endif /* FLASH_WRP3_WRP3 */
742 
743       /* if the program operation is completed, disable the OPTPG Bit */
744       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
745     }
746   }
747 
748   return status;
749 }
750 
751 /**
752   * @brief  Disable the write protection of the desired pages
753   * @note   An option byte erase is done automatically in this function.
754   * @note   When the memory read protection level is selected (RDP level = 1),
755   *         it is not possible to program or erase the flash page i if
756   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
757   *
758   * @param  WriteProtectPage specifies the page(s) to be write unprotected.
759   *         The value of this parameter depend on device used within the same series
760   * @retval HAL status
761   */
FLASH_OB_DisableWRP(uint32_t WriteProtectPage)762 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
763 {
764   HAL_StatusTypeDef status = HAL_OK;
765   uint16_t WRP0_Data = 0xFFFF;
766 #if defined(FLASH_WRP1_WRP1)
767   uint16_t WRP1_Data = 0xFFFF;
768 #endif /* FLASH_WRP1_WRP1 */
769 #if defined(FLASH_WRP2_WRP2)
770   uint16_t WRP2_Data = 0xFFFF;
771 #endif /* FLASH_WRP2_WRP2 */
772 #if defined(FLASH_WRP3_WRP3)
773   uint16_t WRP3_Data = 0xFFFF;
774 #endif /* FLASH_WRP3_WRP3 */
775 
776   /* Check the parameters */
777   assert_param(IS_OB_WRP(WriteProtectPage));
778 
779   /* Get current write protected pages and the new pages to be unprotected ******/
780   WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
781 
782 #if defined(OB_WRP_PAGES0TO15MASK)
783   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
784 #elif defined(OB_WRP_PAGES0TO31MASK)
785   WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
786 #endif /* OB_WRP_PAGES0TO31MASK */
787 
788 #if defined(OB_WRP_PAGES16TO31MASK)
789   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
790 #elif defined(OB_WRP_PAGES32TO63MASK)
791   WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
792 #endif /* OB_WRP_PAGES32TO63MASK */
793 
794 #if defined(OB_WRP_PAGES64TO95MASK)
795   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
796 #endif /* OB_WRP_PAGES64TO95MASK */
797 #if defined(OB_WRP_PAGES32TO47MASK)
798   WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
799 #endif /* OB_WRP_PAGES32TO47MASK */
800 
801 #if defined(OB_WRP_PAGES96TO127MASK)
802   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
803 #elif defined(OB_WRP_PAGES48TO255MASK)
804   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
805 #elif defined(OB_WRP_PAGES48TO511MASK)
806   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
807 #elif defined(OB_WRP_PAGES48TO127MASK)
808   WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
809 #endif /* OB_WRP_PAGES96TO127MASK */
810 
811 
812   /* Wait for last operation to be completed */
813   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
814 
815   if(status == HAL_OK)
816   {
817     /* Clean the error context */
818     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
819 
820     /* To be able to write again option byte, need to perform a option byte erase */
821     status = HAL_FLASHEx_OBErase();
822     if (status == HAL_OK)
823     {
824       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
825 
826 #if defined(FLASH_WRP0_WRP0)
827       if(WRP0_Data != 0xFFU)
828       {
829         OB->WRP0 |= WRP0_Data;
830 
831         /* Wait for last operation to be completed */
832         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
833       }
834 #endif /* FLASH_WRP0_WRP0 */
835 
836 #if defined(FLASH_WRP1_WRP1)
837       if((status == HAL_OK) && (WRP1_Data != 0xFFU))
838       {
839         OB->WRP1 |= WRP1_Data;
840 
841         /* Wait for last operation to be completed */
842         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
843       }
844 #endif /* FLASH_WRP1_WRP1 */
845 
846 #if defined(FLASH_WRP2_WRP2)
847       if((status == HAL_OK) && (WRP2_Data != 0xFFU))
848       {
849         OB->WRP2 |= WRP2_Data;
850 
851         /* Wait for last operation to be completed */
852         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
853       }
854 #endif /* FLASH_WRP2_WRP2 */
855 
856 #if defined(FLASH_WRP3_WRP3)
857       if((status == HAL_OK) && (WRP3_Data != 0xFFU))
858       {
859         OB->WRP3 |= WRP3_Data;
860 
861         /* Wait for last operation to be completed */
862         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
863       }
864 #endif /* FLASH_WRP3_WRP3 */
865 
866       /* if the program operation is completed, disable the OPTPG Bit */
867       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
868     }
869   }
870   return status;
871 }
872 
873 /**
874   * @brief  Set the read protection level.
875   * @param  ReadProtectLevel specifies the read protection level.
876   *         This parameter can be one of the following values:
877   *            @arg @ref OB_RDP_LEVEL_0 No protection
878   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
879   * @retval HAL status
880   */
FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)881 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
882 {
883   HAL_StatusTypeDef status = HAL_OK;
884 
885   /* Check the parameters */
886   assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
887 
888   /* Wait for last operation to be completed */
889   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
890 
891   if(status == HAL_OK)
892   {
893     /* Clean the error context */
894     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
895 
896     /* If the previous operation is completed, proceed to erase the option bytes */
897     SET_BIT(FLASH->CR, FLASH_CR_OPTER);
898     SET_BIT(FLASH->CR, FLASH_CR_STRT);
899 
900     /* Wait for last operation to be completed */
901     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
902 
903     /* If the erase operation is completed, disable the OPTER Bit */
904     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
905 
906     if(status == HAL_OK)
907     {
908       /* Enable the Option Bytes Programming operation */
909       SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
910 
911       WRITE_REG(OB->RDP, ReadProtectLevel);
912 
913       /* Wait for last operation to be completed */
914       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
915 
916       /* if the program operation is completed, disable the OPTPG Bit */
917       CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
918     }
919   }
920 
921   return status;
922 }
923 
924 /**
925   * @brief  Program the FLASH User Option Byte.
926   * @note   Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
927   * @param  UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2),
928   *         FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
929   *         And BFBF2(Bit5) for STM32F101xG and STM32F103xG .
930   * @retval HAL status
931   */
FLASH_OB_UserConfig(uint8_t UserConfig)932 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
933 {
934   HAL_StatusTypeDef status = HAL_OK;
935 
936   /* Check the parameters */
937   assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
938   assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
939   assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
940 #if defined(FLASH_BANK2_END)
941   assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
942 #endif /* FLASH_BANK2_END */
943 
944   /* Wait for last operation to be completed */
945   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
946 
947   if(status == HAL_OK)
948   {
949     /* Clean the error context */
950     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
951 
952     /* Enable the Option Bytes Programming operation */
953     SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
954 
955 #if defined(FLASH_BANK2_END)
956     OB->USER = (UserConfig | 0xF0U);
957 #else
958     OB->USER = (UserConfig | 0x88U);
959 #endif /* FLASH_BANK2_END */
960 
961     /* Wait for last operation to be completed */
962     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
963 
964     /* if the program operation is completed, disable the OPTPG Bit */
965     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
966   }
967 
968   return status;
969 }
970 
971 /**
972   * @brief  Programs a half word at a specified Option Byte Data address.
973   * @note   The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
974   *         The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
975   *         The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
976   *         (system reset will occur)
977   *         Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
978   * @param  Address specifies the address to be programmed.
979   *         This parameter can be 0x1FFFF804 or 0x1FFFF806.
980   * @param  Data specifies the data to be programmed.
981   * @retval HAL status
982   */
FLASH_OB_ProgramData(uint32_t Address,uint8_t Data)983 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
984 {
985   HAL_StatusTypeDef status = HAL_ERROR;
986 
987   /* Check the parameters */
988   assert_param(IS_OB_DATA_ADDRESS(Address));
989 
990   /* Wait for last operation to be completed */
991   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
992 
993   if(status == HAL_OK)
994   {
995     /* Clean the error context */
996     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
997 
998     /* Enables the Option Bytes Programming operation */
999     SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
1000     *(__IO uint16_t*)Address = Data;
1001 
1002     /* Wait for last operation to be completed */
1003     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1004 
1005     /* If the program operation is completed, disable the OPTPG Bit */
1006     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
1007   }
1008   /* Return the Option Byte Data Program Status */
1009   return status;
1010 }
1011 
1012 /**
1013   * @brief  Return the FLASH Write Protection Option Bytes value.
1014   * @retval The FLASH Write Protection Option Bytes value
1015   */
FLASH_OB_GetWRP(void)1016 static uint32_t FLASH_OB_GetWRP(void)
1017 {
1018   /* Return the FLASH write protection Register value */
1019   return (uint32_t)(READ_REG(FLASH->WRPR));
1020 }
1021 
1022 /**
1023   * @brief  Returns the FLASH Read Protection level.
1024   * @retval FLASH RDP level
1025   *         This parameter can be one of the following values:
1026   *            @arg @ref OB_RDP_LEVEL_0 No protection
1027   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
1028   */
FLASH_OB_GetRDP(void)1029 static uint32_t FLASH_OB_GetRDP(void)
1030 {
1031   uint32_t readstatus = OB_RDP_LEVEL_0;
1032   uint32_t tmp_reg = 0U;
1033 
1034   /* Read RDP level bits */
1035   tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
1036 
1037   if (tmp_reg == FLASH_OBR_RDPRT)
1038   {
1039     readstatus = OB_RDP_LEVEL_1;
1040   }
1041   else
1042   {
1043     readstatus = OB_RDP_LEVEL_0;
1044   }
1045 
1046   return readstatus;
1047 }
1048 
1049 /**
1050   * @brief  Return the FLASH User Option Byte value.
1051   * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2),
1052   *         FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
1053   *         And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG .
1054   */
FLASH_OB_GetUser(void)1055 static uint8_t FLASH_OB_GetUser(void)
1056 {
1057   /* Return the User Option Byte */
1058   return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
1059 }
1060 
1061 /**
1062   * @}
1063   */
1064 
1065 /**
1066   * @}
1067   */
1068 
1069 /** @addtogroup FLASH
1070   * @{
1071   */
1072 
1073 /** @addtogroup FLASH_Private_Functions
1074  * @{
1075  */
1076 
1077 /**
1078   * @brief  Erase the specified FLASH memory page
1079   * @param  PageAddress FLASH page to erase
1080   *         The value of this parameter depend on device used within the same series
1081   *
1082   * @retval None
1083   */
FLASH_PageErase(uint32_t PageAddress)1084 void FLASH_PageErase(uint32_t PageAddress)
1085 {
1086   /* Clean the error context */
1087   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1088 
1089 #if defined(FLASH_BANK2_END)
1090   if(PageAddress > FLASH_BANK1_END)
1091   {
1092     /* Proceed to erase the page */
1093     SET_BIT(FLASH->CR2, FLASH_CR2_PER);
1094     WRITE_REG(FLASH->AR2, PageAddress);
1095     SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
1096   }
1097   else
1098   {
1099 #endif /* FLASH_BANK2_END */
1100     /* Proceed to erase the page */
1101     SET_BIT(FLASH->CR, FLASH_CR_PER);
1102     WRITE_REG(FLASH->AR, PageAddress);
1103     SET_BIT(FLASH->CR, FLASH_CR_STRT);
1104 #if defined(FLASH_BANK2_END)
1105   }
1106 #endif /* FLASH_BANK2_END */
1107 }
1108 
1109 /**
1110   * @}
1111   */
1112 
1113 /**
1114   * @}
1115   */
1116 
1117 #endif /* HAL_FLASH_MODULE_ENABLED */
1118 /**
1119   * @}
1120   */
1121 
1122