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   * Copyright (c) 2017 STMicroelectronics.
142   * All rights reserved.
143   *
144   * This software is licensed under terms that can be found in the LICENSE file in
145   * the root directory of this software component.
146   * If no LICENSE file comes with this software, it is provided AS-IS.
147   ******************************************************************************
148   */
149 
150 /* Includes ------------------------------------------------------------------*/
151 #include "stm32l1xx_hal.h"
152 
153 /** @addtogroup STM32L1xx_HAL_Driver
154   * @{
155   */
156 
157 #ifdef HAL_FLASH_MODULE_ENABLED
158 
159 /** @defgroup FLASH FLASH
160   * @brief FLASH HAL module driver
161   * @{
162   */
163 
164 /* Private typedef -----------------------------------------------------------*/
165 /* Private define ------------------------------------------------------------*/
166 /** @defgroup FLASH_Private_Constants FLASH Private Constants
167   * @{
168   */
169 /**
170   * @}
171   */
172 
173 /* Private macro ---------------------------- ---------------------------------*/
174 /** @defgroup FLASH_Private_Macros FLASH Private Macros
175   * @{
176   */
177 
178 /**
179   * @}
180   */
181 
182 /* Private variables ---------------------------------------------------------*/
183 /** @defgroup FLASH_Private_Variables FLASH Private Variables
184   * @{
185   */
186 /* Variables used for Erase pages under interruption*/
187 FLASH_ProcessTypeDef pFlash;
188 /**
189   * @}
190   */
191 
192 /* Private function prototypes -----------------------------------------------*/
193 /** @defgroup FLASH_Private_Functions FLASH Private Functions
194   * @{
195   */
196 static  void   FLASH_SetErrorCode(void);
197 extern void    FLASH_PageErase(uint32_t PageAddress);
198 /**
199   * @}
200   */
201 
202 /* Exported functions ---------------------------------------------------------*/
203 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
204   * @{
205   */
206 
207 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
208   *  @brief   Programming operation functions
209   *
210 @verbatim
211 @endverbatim
212   * @{
213   */
214 
215 /**
216   * @brief  Program word at a specified address
217   * @note   To correctly run this function, the HAL_FLASH_Unlock() function
218   *         must be called before.
219   *         Call the HAL_FLASH_Lock() to disable the flash memory access
220   *         (recommended to protect the FLASH memory against possible unwanted operation).
221   *
222   * @param  TypeProgram   Indicate the way to program at a specified address.
223   *                       This parameter can be a value of @ref FLASH_Type_Program
224   * @param  Address       Specifie the address to be programmed.
225   * @param  Data          Specifie the data to be programmed
226   *
227   * @retval HAL_StatusTypeDef HAL Status
228   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint32_t Data)229 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
230 {
231   HAL_StatusTypeDef status = HAL_ERROR;
232 
233   /* Process Locked */
234   __HAL_LOCK(&pFlash);
235 
236   /* Check the parameters */
237   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
238   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
239 
240   /* Wait for last operation to be completed */
241   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
242 
243   if(status == HAL_OK)
244   {
245     /* Clean the error context */
246     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
247 
248     /*Program word (32-bit) at a specified address.*/
249     *(__IO uint32_t *)Address = Data;
250 
251     /* Wait for last operation to be completed */
252     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
253   }
254 
255   /* Process Unlocked */
256   __HAL_UNLOCK(&pFlash);
257 
258   return status;
259 }
260 
261 /**
262   * @brief   Program word at a specified address  with interrupt enabled.
263   *
264   * @param  TypeProgram  Indicate the way to program at a specified address.
265   *                      This parameter can be a value of @ref FLASH_Type_Program
266   * @param  Address      Specifie the address to be programmed.
267   * @param  Data         Specifie the data to be programmed
268   *
269   * @retval HAL_StatusTypeDef HAL Status
270   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint32_t Data)271 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
272 {
273   HAL_StatusTypeDef status = HAL_OK;
274 
275   /* Process Locked */
276   __HAL_LOCK(&pFlash);
277 
278   /* Check the parameters */
279   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
280   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
281 
282   /* Enable End of FLASH Operation and Error source interrupts */
283   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
284 
285   pFlash.Address = Address;
286   pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
287   /* Clean the error context */
288   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
289 
290   if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
291   {
292     /* Program word (32-bit) at a specified address. */
293     *(__IO uint32_t *)Address = Data;
294   }
295   return status;
296 }
297 
298 /**
299   * @brief This function handles FLASH interrupt request.
300   * @retval None
301   */
HAL_FLASH_IRQHandler(void)302 void HAL_FLASH_IRQHandler(void)
303 {
304   uint32_t addresstmp = 0U;
305 
306   /* Check FLASH operation error flags */
307   if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)     ||
308       __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)     ||
309       __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)     ||
310 #if defined(FLASH_SR_RDERR)
311       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)      ||
312 #endif /* FLASH_SR_RDERR */
313 #if defined(FLASH_SR_OPTVERRUSR)
314       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR) ||
315 #endif /* FLASH_SR_OPTVERRUSR */
316       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) )
317   {
318     if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
319     {
320       /* Return the faulty sector */
321       addresstmp = pFlash.Page;
322       pFlash.Page = 0xFFFFFFFFU;
323     }
324     else
325     {
326       /* Return the faulty address */
327       addresstmp = pFlash.Address;
328     }
329     /* Save the Error code */
330     FLASH_SetErrorCode();
331 
332     /* FLASH error interrupt user callback */
333     HAL_FLASH_OperationErrorCallback(addresstmp);
334 
335     /* Stop the procedure ongoing */
336     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
337   }
338 
339   /* Check FLASH End of Operation flag  */
340   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
341   {
342     /* Clear FLASH End of Operation pending bit */
343     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
344 
345     /* Process can continue only if no error detected */
346     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
347     {
348       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
349       {
350         /* Nb of pages to erased can be decreased */
351         pFlash.NbPagesToErase--;
352 
353         /* Check if there are still pages to erase */
354         if(pFlash.NbPagesToErase != 0U)
355         {
356           addresstmp = pFlash.Page;
357           /*Indicate user which sector has been erased */
358           HAL_FLASH_EndOfOperationCallback(addresstmp);
359 
360           /*Increment sector number*/
361           addresstmp = pFlash.Page + FLASH_PAGE_SIZE;
362           pFlash.Page = addresstmp;
363 
364           /* If the erase operation is completed, disable the ERASE Bit */
365           CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
366 
367           FLASH_PageErase(addresstmp);
368         }
369         else
370         {
371           /* No more pages to Erase, user callback can be called. */
372           /* Reset Sector and stop Erase pages procedure */
373           pFlash.Page = addresstmp = 0xFFFFFFFFU;
374           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
375           /* FLASH EOP interrupt user callback */
376           HAL_FLASH_EndOfOperationCallback(addresstmp);
377         }
378       }
379       else
380       {
381           /* If the program operation is completed, disable the PROG Bit */
382           CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
383 
384           /* Program ended. Return the selected address */
385           /* FLASH EOP interrupt user callback */
386           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
387 
388           /* Reset Address and stop Program procedure */
389           pFlash.Address = 0xFFFFFFFFU;
390           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
391       }
392     }
393   }
394 
395 
396   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
397   {
398     /* Operation is completed, disable the PROG and ERASE */
399     CLEAR_BIT(FLASH->PECR, (FLASH_PECR_ERASE | FLASH_PECR_PROG));
400 
401     /* Disable End of FLASH Operation and Error source interrupts */
402     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
403 
404     /* Process Unlocked */
405     __HAL_UNLOCK(&pFlash);
406   }
407 }
408 
409 /**
410   * @brief  FLASH end of operation interrupt callback
411   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
412   *                 - Pages Erase: Address of the page which has been erased
413   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
414   *                 - Program: Address which was selected for data program
415   * @retval none
416   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)417 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
418 {
419   /* Prevent unused argument(s) compilation warning */
420   UNUSED(ReturnValue);
421 
422   /* NOTE : This function Should not be modified, when the callback is needed,
423             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
424    */
425 }
426 
427 /**
428   * @brief  FLASH operation error interrupt callback
429   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
430   *                 - Pages Erase: Address of the page which returned an error
431   *                 - Program: Address which was selected for data program
432   * @retval none
433   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)434 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
435 {
436   /* Prevent unused argument(s) compilation warning */
437   UNUSED(ReturnValue);
438 
439   /* NOTE : This function Should not be modified, when the callback is needed,
440             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
441    */
442 }
443 
444 /**
445   * @}
446   */
447 
448 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
449  *  @brief   management functions
450  *
451 @verbatim
452  ===============================================================================
453                       ##### Peripheral Control functions #####
454  ===============================================================================
455     [..]
456     This subsection provides a set of functions allowing to control the FLASH
457     memory operations.
458 
459 @endverbatim
460   * @{
461   */
462 
463 /**
464   * @brief  Unlock the FLASH control register access
465   * @retval HAL Status
466   */
HAL_FLASH_Unlock(void)467 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
468 {
469   if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
470   {
471     /* Unlocking FLASH_PECR register access*/
472     if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
473     {
474       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
475       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
476 
477       /* Verify that PELOCK is unlocked */
478       if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
479       {
480         return HAL_ERROR;
481       }
482     }
483 
484     /* Unlocking the program memory access */
485     WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY1);
486     WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY2);
487 
488     /* Verify that PRGLOCK is unlocked */
489     if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
490     {
491       return HAL_ERROR;
492     }
493   }
494 
495   return HAL_OK;
496 }
497 
498 /**
499   * @brief  Locks the FLASH control register access
500   * @retval HAL Status
501   */
HAL_FLASH_Lock(void)502 HAL_StatusTypeDef HAL_FLASH_Lock(void)
503 {
504   /* Set the PRGLOCK Bit to lock the FLASH Registers access */
505   SET_BIT(FLASH->PECR, FLASH_PECR_PRGLOCK);
506 
507   return HAL_OK;
508 }
509 
510 /**
511   * @brief  Unlock the FLASH Option Control Registers access.
512   * @retval HAL Status
513   */
HAL_FLASH_OB_Unlock(void)514 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
515 {
516   if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_OPTLOCK))
517   {
518     /* Unlocking FLASH_PECR register access*/
519     if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
520     {
521       /* Unlocking FLASH_PECR register access*/
522       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
523       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
524 
525       /* Verify that PELOCK is unlocked */
526       if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
527       {
528         return HAL_ERROR;
529       }
530     }
531 
532     /* Unlocking the option bytes block access */
533     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
534     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
535 
536     /* Verify that OPTLOCK is unlocked */
537     if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_OPTLOCK))
538     {
539       return HAL_ERROR;
540     }
541   }
542 
543   return HAL_OK;
544 }
545 
546 /**
547   * @brief  Lock the FLASH Option Control Registers access.
548   * @retval HAL Status
549   */
HAL_FLASH_OB_Lock(void)550 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
551 {
552   /* Set the OPTLOCK Bit to lock the option bytes block access */
553   SET_BIT(FLASH->PECR, FLASH_PECR_OPTLOCK);
554 
555   return HAL_OK;
556 }
557 
558 /**
559   * @brief  Launch the option byte loading.
560   * @note   This function will reset automatically the MCU.
561   * @retval HAL Status
562   */
HAL_FLASH_OB_Launch(void)563 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
564 {
565   /* Set the OBL_Launch bit to launch the option byte loading */
566   SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH);
567 
568   /* Wait for last operation to be completed */
569   return(FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE));
570 }
571 
572 /**
573   * @}
574   */
575 
576 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
577  *  @brief    Peripheral errors functions
578  *
579 @verbatim
580  ===============================================================================
581                       ##### Peripheral Errors functions #####
582  ===============================================================================
583     [..]
584     This subsection permit to get in run-time errors of  the FLASH peripheral.
585 
586 @endverbatim
587   * @{
588   */
589 
590 /**
591   * @brief  Get the specific FLASH error flag.
592   * @retval FLASH_ErrorCode The returned value can be:
593   *            @ref FLASH_Error_Codes
594   */
HAL_FLASH_GetError(void)595 uint32_t HAL_FLASH_GetError(void)
596 {
597    return pFlash.ErrorCode;
598 }
599 
600 /**
601   * @}
602   */
603 
604 /**
605   * @}
606   */
607 
608 /** @addtogroup FLASH_Private_Functions
609  * @{
610  */
611 
612 /**
613   * @brief  Wait for a FLASH operation to complete.
614   * @param  Timeout  maximum flash operation timeout
615   * @retval HAL Status
616   */
FLASH_WaitForLastOperation(uint32_t Timeout)617 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
618 {
619   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
620      Even if the FLASH operation fails, the BUSY flag will be reset and an error
621      flag will be set */
622 
623   uint32_t tickstart = HAL_GetTick();
624 
625   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
626   {
627     if (Timeout != HAL_MAX_DELAY)
628     {
629       if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
630       {
631         return HAL_TIMEOUT;
632       }
633     }
634   }
635 
636   /* Check FLASH End of Operation flag  */
637   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
638   {
639     /* Clear FLASH End of Operation pending bit */
640     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
641   }
642 
643   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)  ||
644      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
645 #if defined(FLASH_SR_RDERR)
646       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) ||
647 #endif /* FLASH_SR_RDERR */
648 #if defined(FLASH_SR_OPTVERRUSR)
649       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR) ||
650 #endif /* FLASH_SR_OPTVERRUSR */
651      __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) ||
652      __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
653   {
654     /*Save the error code*/
655     FLASH_SetErrorCode();
656     return HAL_ERROR;
657   }
658 
659   /* There is no error flag set */
660   return HAL_OK;
661 }
662 
663 
664 /**
665   * @brief  Set the specific FLASH error flag.
666   * @retval None
667   */
FLASH_SetErrorCode(void)668 static void FLASH_SetErrorCode(void)
669 {
670   uint32_t flags = 0U;
671 
672   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
673   {
674     pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
675     flags |= FLASH_FLAG_WRPERR;
676   }
677   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
678   {
679     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
680     flags |= FLASH_FLAG_PGAERR;
681   }
682   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
683   {
684     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
685     flags |= FLASH_FLAG_OPTVERR;
686   }
687 
688 #if defined(FLASH_SR_RDERR)
689   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
690   {
691     pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
692     flags |= FLASH_FLAG_RDERR;
693   }
694 #endif /* FLASH_SR_RDERR */
695 #if defined(FLASH_SR_OPTVERRUSR)
696   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR))
697   {
698     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTVUSR;
699     flags |= FLASH_FLAG_OPTVERRUSR;
700   }
701 #endif /* FLASH_SR_OPTVERRUSR */
702   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR))
703   {
704     pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE;
705     flags |= FLASH_FLAG_SIZERR;
706   }
707   /* Clear FLASH error pending bits */
708   __HAL_FLASH_CLEAR_FLAG(flags);
709 }
710 /**
711   * @}
712   */
713 
714 /**
715   * @}
716   */
717 
718 #endif /* HAL_FLASH_MODULE_ENABLED */
719 
720 /**
721   * @}
722   */
723 
724