1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_hal_flash.c
4   * @author  MCD Application Team
5   * @brief   FLASH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the internal FLASH memory:
8   *           + Program operations functions
9   *           + Memory Control functions
10   *           + Peripheral State functions
11   *
12   @verbatim
13   ==============================================================================
14                         ##### FLASH peripheral features #####
15   ==============================================================================
16   [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
17        to the Flash memory. It implements the erase and program Flash memory operations
18        and the read and write protection mechanisms.
19 
20   [..] The Flash memory interface accelerates code execution with a system of instruction
21       prefetch.
22 
23   [..] The FLASH main features are:
24       (+) Flash memory read operations
25       (+) Flash memory program/erase operations
26       (+) Read / write protections
27       (+) Prefetch on I-Code
28       (+) Option Bytes programming
29 
30 
31                      ##### How to use this driver #####
32   ==============================================================================
33   [..]
34       This driver provides functions and macros to configure and program the FLASH
35       memory of all STM32L1xx devices.
36 
37       (#) FLASH Memory I/O Programming functions: this group includes all needed
38           functions to erase and program the main memory:
39         (++) Lock and Unlock the FLASH interface
40         (++) Erase function: Erase page
41         (++) Program functions: Fast Word and Half Page(should be
42         executed from internal SRAM).
43 
44       (#) DATA EEPROM Programming functions: this group includes all
45           needed functions to erase and program the DATA EEPROM memory:
46         (++) Lock and Unlock the DATA EEPROM interface.
47         (++) Erase function: Erase Byte, erase HalfWord, erase Word, erase
48              Double Word (should be executed from internal SRAM).
49         (++) Program functions: Fast Program Byte, Fast Program Half-Word,
50              FastProgramWord, Program Byte, Program Half-Word,
51              Program Word and Program Double-Word (should be executed
52              from internal SRAM).
53 
54       (#) FLASH Option Bytes Programming functions: this group includes all needed
55           functions to manage the Option Bytes:
56         (++) Lock and Unlock the Option Bytes
57         (++) Set/Reset the write protection
58         (++) Set the Read protection Level
59         (++) Program the user Option Bytes
60         (++) Launch the Option Bytes loader
61         (++) Set/Get the Read protection Level.
62         (++) Set/Get the BOR level.
63         (++) Get the Write protection.
64         (++) Get the user option bytes.
65 
66       (#) Interrupts and flags management functions : this group
67           includes all needed functions to:
68         (++) Handle FLASH interrupts
69         (++) Wait for last FLASH operation according to its status
70         (++) Get error flag status
71 
72     (#) FLASH Interface configuration functions: this group includes
73       the management of following features:
74       (++) Enable/Disable the RUN PowerDown mode.
75       (++) Enable/Disable the SLEEP PowerDown mode.
76 
77     (#) FLASH Peripheral State methods: this group includes
78       the management of following features:
79       (++) Wait for the FLASH operation
80       (++)  Get the specific FLASH error flag
81 
82   [..] In addition to these function, this driver includes a set of macros allowing
83        to handle the following operations:
84 
85       (+) Set/Get the latency
86       (+) Enable/Disable the prefetch buffer
87       (+) Enable/Disable the 64 bit Read Access.
88       (+) Enable/Disable the Flash power-down
89       (+) Enable/Disable the FLASH interrupts
90       (+) Monitor the FLASH flags status
91 
92                  ##### Programming operation functions #####
93   ===============================================================================
94      [..]
95      This subsection provides a set of functions allowing to manage the FLASH
96      program operations.
97 
98     [..] The FLASH Memory Programming functions, includes the following functions:
99      (+) HAL_FLASH_Unlock(void);
100      (+) HAL_FLASH_Lock(void);
101      (+) HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
102      (+) HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
103 
104      [..] Any operation of erase or program should follow these steps:
105      (#) Call the HAL_FLASH_Unlock() function to enable the flash control register and
106          program memory access.
107      (#) Call the desired function to erase page or program data.
108      (#) Call the HAL_FLASH_Lock() to disable the flash program memory access
109         (recommended to protect the FLASH memory against possible unwanted operation).
110 
111                ##### Option Bytes Programming functions #####
112    ==============================================================================
113 
114      [..] The FLASH_Option Bytes Programming_functions, includes the following functions:
115      (+) HAL_FLASH_OB_Unlock(void);
116      (+) HAL_FLASH_OB_Lock(void);
117      (+) HAL_FLASH_OB_Launch(void);
118      (+) HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
119      (+) HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit);
120 
121      [..] Any operation of erase or program should follow these steps:
122      (#) Call the HAL_FLASH_OB_Unlock() function to enable the Flash option control
123          register access.
124      (#) Call the following functions to program the desired option bytes.
125          (++) HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
126      (#) Once all needed option bytes to be programmed are correctly written, call the
127          HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process.
128      (#) Call the HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended
129          to protect the option Bytes against possible unwanted operations).
130 
131     [..] Proprietary code Read Out Protection (PcROP):
132     (#) The PcROP sector is selected by using the same option bytes as the Write
133         protection. As a result, these 2 options are exclusive each other.
134     (#) To activate PCROP mode for Flash sectors(s), you need to follow the sequence below:
135         (++) Use this function HAL_FLASHEx_AdvOBProgram with PCROPState = OB_PCROP_STATE_ENABLE.
136 
137   @endverbatim
138   ******************************************************************************
139   * @attention
140   *
141   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
142   * All rights reserved.</center></h2>
143   *
144   * This software component is licensed by ST under BSD 3-Clause license,
145   * the "License"; You may not use this file except in compliance with the
146   * License. You may obtain a copy of the License at:
147   *                        opensource.org/licenses/BSD-3-Clause
148   *
149   ******************************************************************************
150   */
151 
152 /* Includes ------------------------------------------------------------------*/
153 #include "stm32l1xx_hal.h"
154 
155 /** @addtogroup STM32L1xx_HAL_Driver
156   * @{
157   */
158 
159 #ifdef HAL_FLASH_MODULE_ENABLED
160 
161 /** @defgroup FLASH FLASH
162   * @brief FLASH HAL module driver
163   * @{
164   */
165 
166 /* Private typedef -----------------------------------------------------------*/
167 /* Private define ------------------------------------------------------------*/
168 /** @defgroup FLASH_Private_Constants FLASH Private Constants
169   * @{
170   */
171 /**
172   * @}
173   */
174 
175 /* Private macro ---------------------------- ---------------------------------*/
176 /** @defgroup FLASH_Private_Macros FLASH Private Macros
177   * @{
178   */
179 
180 /**
181   * @}
182   */
183 
184 /* Private variables ---------------------------------------------------------*/
185 /** @defgroup FLASH_Private_Variables FLASH Private Variables
186   * @{
187   */
188 /* Variables used for Erase pages under interruption*/
189 FLASH_ProcessTypeDef pFlash;
190 /**
191   * @}
192   */
193 
194 /* Private function prototypes -----------------------------------------------*/
195 /** @defgroup FLASH_Private_Functions FLASH Private Functions
196   * @{
197   */
198 static  void   FLASH_SetErrorCode(void);
199 extern void    FLASH_PageErase(uint32_t PageAddress);
200 /**
201   * @}
202   */
203 
204 /* Exported functions ---------------------------------------------------------*/
205 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
206   * @{
207   */
208 
209 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
210   *  @brief   Programming operation functions
211   *
212 @verbatim
213 @endverbatim
214   * @{
215   */
216 
217 /**
218   * @brief  Program word at a specified address
219   * @note   To correctly run this function, the HAL_FLASH_Unlock() function
220   *         must be called before.
221   *         Call the HAL_FLASH_Lock() to disable the flash memory access
222   *         (recommended to protect the FLASH memory against possible unwanted operation).
223   *
224   * @param  TypeProgram   Indicate the way to program at a specified address.
225   *                       This parameter can be a value of @ref FLASH_Type_Program
226   * @param  Address       Specifie the address to be programmed.
227   * @param  Data          Specifie the data to be programmed
228   *
229   * @retval HAL_StatusTypeDef HAL Status
230   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint32_t Data)231 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
232 {
233   HAL_StatusTypeDef status = HAL_ERROR;
234 
235   /* Process Locked */
236   __HAL_LOCK(&pFlash);
237 
238   /* Check the parameters */
239   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
240   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
241 
242   /* Wait for last operation to be completed */
243   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
244 
245   if(status == HAL_OK)
246   {
247     /* Clean the error context */
248     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
249 
250     /*Program word (32-bit) at a specified address.*/
251     *(__IO uint32_t *)Address = Data;
252 
253     /* Wait for last operation to be completed */
254     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
255   }
256 
257   /* Process Unlocked */
258   __HAL_UNLOCK(&pFlash);
259 
260   return status;
261 }
262 
263 /**
264   * @brief   Program word at a specified address  with interrupt enabled.
265   *
266   * @param  TypeProgram  Indicate the way to program at a specified address.
267   *                      This parameter can be a value of @ref FLASH_Type_Program
268   * @param  Address      Specifie the address to be programmed.
269   * @param  Data         Specifie the data to be programmed
270   *
271   * @retval HAL_StatusTypeDef HAL Status
272   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint32_t Data)273 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
274 {
275   HAL_StatusTypeDef status = HAL_OK;
276 
277   /* Process Locked */
278   __HAL_LOCK(&pFlash);
279 
280   /* Check the parameters */
281   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
282   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
283 
284   /* Enable End of FLASH Operation and Error source interrupts */
285   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
286 
287   pFlash.Address = Address;
288   pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
289   /* Clean the error context */
290   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
291 
292   if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
293   {
294     /* Program word (32-bit) at a specified address. */
295     *(__IO uint32_t *)Address = Data;
296   }
297   return status;
298 }
299 
300 /**
301   * @brief This function handles FLASH interrupt request.
302   * @retval None
303   */
HAL_FLASH_IRQHandler(void)304 void HAL_FLASH_IRQHandler(void)
305 {
306   uint32_t addresstmp = 0U;
307 
308   /* Check FLASH operation error flags */
309   if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)     ||
310       __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)     ||
311       __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)     ||
312 #if defined(FLASH_SR_RDERR)
313       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)      ||
314 #endif /* FLASH_SR_RDERR */
315 #if defined(FLASH_SR_OPTVERRUSR)
316       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR) ||
317 #endif /* FLASH_SR_OPTVERRUSR */
318       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) )
319   {
320     if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
321     {
322       /* Return the faulty sector */
323       addresstmp = pFlash.Page;
324       pFlash.Page = 0xFFFFFFFFU;
325     }
326     else
327     {
328       /* Return the faulty address */
329       addresstmp = pFlash.Address;
330     }
331     /* Save the Error code */
332     FLASH_SetErrorCode();
333 
334     /* FLASH error interrupt user callback */
335     HAL_FLASH_OperationErrorCallback(addresstmp);
336 
337     /* Stop the procedure ongoing */
338     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
339   }
340 
341   /* Check FLASH End of Operation flag  */
342   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
343   {
344     /* Clear FLASH End of Operation pending bit */
345     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
346 
347     /* Process can continue only if no error detected */
348     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
349     {
350       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
351       {
352         /* Nb of pages to erased can be decreased */
353         pFlash.NbPagesToErase--;
354 
355         /* Check if there are still pages to erase */
356         if(pFlash.NbPagesToErase != 0U)
357         {
358           addresstmp = pFlash.Page;
359           /*Indicate user which sector has been erased */
360           HAL_FLASH_EndOfOperationCallback(addresstmp);
361 
362           /*Increment sector number*/
363           addresstmp = pFlash.Page + FLASH_PAGE_SIZE;
364           pFlash.Page = addresstmp;
365 
366           /* If the erase operation is completed, disable the ERASE Bit */
367           CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
368 
369           FLASH_PageErase(addresstmp);
370         }
371         else
372         {
373           /* No more pages to Erase, user callback can be called. */
374           /* Reset Sector and stop Erase pages procedure */
375           pFlash.Page = addresstmp = 0xFFFFFFFFU;
376           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
377           /* FLASH EOP interrupt user callback */
378           HAL_FLASH_EndOfOperationCallback(addresstmp);
379         }
380       }
381       else
382       {
383           /* If the program operation is completed, disable the PROG Bit */
384           CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
385 
386           /* Program ended. Return the selected address */
387           /* FLASH EOP interrupt user callback */
388           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
389 
390           /* Reset Address and stop Program procedure */
391           pFlash.Address = 0xFFFFFFFFU;
392           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
393       }
394     }
395   }
396 
397 
398   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
399   {
400     /* Operation is completed, disable the PROG and ERASE */
401     CLEAR_BIT(FLASH->PECR, (FLASH_PECR_ERASE | FLASH_PECR_PROG));
402 
403     /* Disable End of FLASH Operation and Error source interrupts */
404     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
405 
406     /* Process Unlocked */
407     __HAL_UNLOCK(&pFlash);
408   }
409 }
410 
411 /**
412   * @brief  FLASH end of operation interrupt callback
413   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
414   *                 - Pages Erase: Address of the page which has been erased
415   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
416   *                 - Program: Address which was selected for data program
417   * @retval none
418   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)419 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
420 {
421   /* Prevent unused argument(s) compilation warning */
422   UNUSED(ReturnValue);
423 
424   /* NOTE : This function Should not be modified, when the callback is needed,
425             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
426    */
427 }
428 
429 /**
430   * @brief  FLASH operation error interrupt callback
431   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
432   *                 - Pages Erase: Address of the page which returned an error
433   *                 - Program: Address which was selected for data program
434   * @retval none
435   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)436 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
437 {
438   /* Prevent unused argument(s) compilation warning */
439   UNUSED(ReturnValue);
440 
441   /* NOTE : This function Should not be modified, when the callback is needed,
442             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
443    */
444 }
445 
446 /**
447   * @}
448   */
449 
450 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
451  *  @brief   management functions
452  *
453 @verbatim
454  ===============================================================================
455                       ##### Peripheral Control functions #####
456  ===============================================================================
457     [..]
458     This subsection provides a set of functions allowing to control the FLASH
459     memory operations.
460 
461 @endverbatim
462   * @{
463   */
464 
465 /**
466   * @brief  Unlock the FLASH control register access
467   * @retval HAL Status
468   */
HAL_FLASH_Unlock(void)469 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
470 {
471   if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
472   {
473     /* Unlocking FLASH_PECR register access*/
474     if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
475     {
476       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
477       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
478 
479       /* Verify that PELOCK is unlocked */
480       if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
481       {
482         return HAL_ERROR;
483       }
484     }
485 
486     /* Unlocking the program memory access */
487     WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY1);
488     WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY2);
489 
490     /* Verify that PRGLOCK is unlocked */
491     if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
492     {
493       return HAL_ERROR;
494     }
495   }
496 
497   return HAL_OK;
498 }
499 
500 /**
501   * @brief  Locks the FLASH control register access
502   * @retval HAL Status
503   */
HAL_FLASH_Lock(void)504 HAL_StatusTypeDef HAL_FLASH_Lock(void)
505 {
506   /* Set the PRGLOCK Bit to lock the FLASH Registers access */
507   SET_BIT(FLASH->PECR, FLASH_PECR_PRGLOCK);
508 
509   return HAL_OK;
510 }
511 
512 /**
513   * @brief  Unlock the FLASH Option Control Registers access.
514   * @retval HAL Status
515   */
HAL_FLASH_OB_Unlock(void)516 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
517 {
518   if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_OPTLOCK))
519   {
520     /* Unlocking FLASH_PECR register access*/
521     if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
522     {
523       /* Unlocking FLASH_PECR register access*/
524       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
525       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
526 
527       /* Verify that PELOCK is unlocked */
528       if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
529       {
530         return HAL_ERROR;
531       }
532     }
533 
534     /* Unlocking the option bytes block access */
535     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
536     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
537 
538     /* Verify that OPTLOCK is unlocked */
539     if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_OPTLOCK))
540     {
541       return HAL_ERROR;
542     }
543   }
544 
545   return HAL_OK;
546 }
547 
548 /**
549   * @brief  Lock the FLASH Option Control Registers access.
550   * @retval HAL Status
551   */
HAL_FLASH_OB_Lock(void)552 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
553 {
554   /* Set the OPTLOCK Bit to lock the option bytes block access */
555   SET_BIT(FLASH->PECR, FLASH_PECR_OPTLOCK);
556 
557   return HAL_OK;
558 }
559 
560 /**
561   * @brief  Launch the option byte loading.
562   * @note   This function will reset automatically the MCU.
563   * @retval HAL Status
564   */
HAL_FLASH_OB_Launch(void)565 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
566 {
567   /* Set the OBL_Launch bit to launch the option byte loading */
568   SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH);
569 
570   /* Wait for last operation to be completed */
571   return(FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE));
572 }
573 
574 /**
575   * @}
576   */
577 
578 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
579  *  @brief    Peripheral errors functions
580  *
581 @verbatim
582  ===============================================================================
583                       ##### Peripheral Errors functions #####
584  ===============================================================================
585     [..]
586     This subsection permit to get in run-time errors of  the FLASH peripheral.
587 
588 @endverbatim
589   * @{
590   */
591 
592 /**
593   * @brief  Get the specific FLASH error flag.
594   * @retval FLASH_ErrorCode The returned value can be:
595   *            @ref FLASH_Error_Codes
596   */
HAL_FLASH_GetError(void)597 uint32_t HAL_FLASH_GetError(void)
598 {
599    return pFlash.ErrorCode;
600 }
601 
602 /**
603   * @}
604   */
605 
606 /**
607   * @}
608   */
609 
610 /** @addtogroup FLASH_Private_Functions
611  * @{
612  */
613 
614 /**
615   * @brief  Wait for a FLASH operation to complete.
616   * @param  Timeout  maximum flash operation timeout
617   * @retval HAL Status
618   */
FLASH_WaitForLastOperation(uint32_t Timeout)619 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
620 {
621   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
622      Even if the FLASH operation fails, the BUSY flag will be reset and an error
623      flag will be set */
624 
625   uint32_t tickstart = HAL_GetTick();
626 
627   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
628   {
629     if (Timeout != HAL_MAX_DELAY)
630     {
631       if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
632       {
633         return HAL_TIMEOUT;
634       }
635     }
636   }
637 
638   /* Check FLASH End of Operation flag  */
639   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
640   {
641     /* Clear FLASH End of Operation pending bit */
642     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
643   }
644 
645   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)  ||
646      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
647 #if defined(FLASH_SR_RDERR)
648       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) ||
649 #endif /* FLASH_SR_RDERR */
650 #if defined(FLASH_SR_OPTVERRUSR)
651       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR) ||
652 #endif /* FLASH_SR_OPTVERRUSR */
653      __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) ||
654      __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
655   {
656     /*Save the error code*/
657     FLASH_SetErrorCode();
658     return HAL_ERROR;
659   }
660 
661   /* There is no error flag set */
662   return HAL_OK;
663 }
664 
665 
666 /**
667   * @brief  Set the specific FLASH error flag.
668   * @retval None
669   */
FLASH_SetErrorCode(void)670 static void FLASH_SetErrorCode(void)
671 {
672   uint32_t flags = 0U;
673 
674   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
675   {
676     pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
677     flags |= FLASH_FLAG_WRPERR;
678   }
679   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
680   {
681     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
682     flags |= FLASH_FLAG_PGAERR;
683   }
684   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
685   {
686     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
687     flags |= FLASH_FLAG_OPTVERR;
688   }
689 
690 #if defined(FLASH_SR_RDERR)
691   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
692   {
693     pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
694     flags |= FLASH_FLAG_RDERR;
695   }
696 #endif /* FLASH_SR_RDERR */
697 #if defined(FLASH_SR_OPTVERRUSR)
698   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR))
699   {
700     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTVUSR;
701     flags |= FLASH_FLAG_OPTVERRUSR;
702   }
703 #endif /* FLASH_SR_OPTVERRUSR */
704   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR))
705   {
706     pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE;
707     flags |= FLASH_FLAG_SIZERR;
708   }
709   /* Clear FLASH error pending bits */
710   __HAL_FLASH_CLEAR_FLAG(flags);
711 }
712 /**
713   * @}
714   */
715 
716 /**
717   * @}
718   */
719 
720 #endif /* HAL_FLASH_MODULE_ENABLED */
721 
722 /**
723   * @}
724   */
725 
726 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
727