xref: /btstack/port/stm32-l073rz-nucleo-em9304/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_flash.c (revision e838079242074edcbcbb400962776e15fe6ca6cb)
1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_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 STM32L0xx 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 preread buffer
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) 2016 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 "stm32l0xx_hal.h"
154 
155 /** @addtogroup STM32L0xx_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 = 0;
307 
308   /* Check FLASH operation error flags */
309 
310   /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
311    *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
312    *           as expected. If the user run an application using the first
313    *           cut of the STM32L031xx device or the first cut of the STM32L041xx
314    *           device, the check on the FLASH_FLAG_OPTVERR bit should be ignored.
315    *
316    *           Note :The revId of the device can be retrieved via the HAL_GetREVID()
317    *           function.
318    *
319    */
320 
321   if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)     ||
322       __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)     ||
323       __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)     ||
324       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)    ||
325       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)      ||
326       __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR)     ||
327       __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) )
328   {
329     if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
330     {
331       /* Return the faulty sector */
332       addresstmp = pFlash.Page;
333       pFlash.Page = 0xFFFFFFFFU;
334     }
335     else
336     {
337       /* Return the faulty address */
338       addresstmp = pFlash.Address;
339     }
340     /* Save the Error code */
341     FLASH_SetErrorCode();
342 
343     /* FLASH error interrupt user callback */
344     HAL_FLASH_OperationErrorCallback(addresstmp);
345 
346     /* Stop the procedure ongoing */
347     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
348   }
349 
350   /* Check FLASH End of Operation flag  */
351   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
352   {
353     /* Clear FLASH End of Operation pending bit */
354     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
355 
356     /* Process can continue only if no error detected */
357     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
358     {
359       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
360       {
361         /* Nb of pages to erased can be decreased */
362         pFlash.NbPagesToErase--;
363 
364         /* Check if there are still pages to erase */
365         if(pFlash.NbPagesToErase != 0U)
366         {
367           addresstmp = pFlash.Page;
368           /*Indicate user which sector has been erased */
369           HAL_FLASH_EndOfOperationCallback(addresstmp);
370 
371           /*Increment sector number*/
372           addresstmp = pFlash.Page + FLASH_PAGE_SIZE;
373           pFlash.Page = addresstmp;
374 
375           /* If the erase operation is completed, disable the ERASE Bit */
376           CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
377 
378           FLASH_PageErase(addresstmp);
379         }
380         else
381         {
382           /* No more pages to Erase, user callback can be called. */
383           /* Reset Sector and stop Erase pages procedure */
384           pFlash.Page = addresstmp = 0xFFFFFFFFU;
385           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
386           /* FLASH EOP interrupt user callback */
387           HAL_FLASH_EndOfOperationCallback(addresstmp);
388         }
389       }
390       else
391       {
392           /* If the program operation is completed, disable the PROG Bit */
393           CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
394 
395           /* Program ended. Return the selected address */
396           /* FLASH EOP interrupt user callback */
397           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
398 
399           /* Reset Address and stop Program procedure */
400           pFlash.Address = 0xFFFFFFFFU;
401           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
402       }
403     }
404   }
405 
406 
407   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
408   {
409     /* Operation is completed, disable the PROG and ERASE */
410     CLEAR_BIT(FLASH->PECR, (FLASH_PECR_ERASE | FLASH_PECR_PROG));
411 
412     /* Disable End of FLASH Operation and Error source interrupts */
413     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
414 
415     /* Process Unlocked */
416     __HAL_UNLOCK(&pFlash);
417   }
418 }
419 
420 /**
421   * @brief  FLASH end of operation interrupt callback
422   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
423   *                 - Pages Erase: Address of the page which has been erased
424   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
425   *                 - Program: Address which was selected for data program
426   * @retval none
427   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)428 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
429 {
430   /* Prevent unused argument(s) compilation warning */
431   UNUSED(ReturnValue);
432 
433   /* NOTE : This function Should not be modified, when the callback is needed,
434             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
435    */
436 }
437 
438 /**
439   * @brief  FLASH operation error interrupt callback
440   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
441   *                 - Pages Erase: Address of the page which returned an error
442   *                 - Program: Address which was selected for data program
443   * @retval none
444   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)445 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
446 {
447   /* Prevent unused argument(s) compilation warning */
448   UNUSED(ReturnValue);
449 
450   /* NOTE : This function Should not be modified, when the callback is needed,
451             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
452    */
453 }
454 
455 /**
456   * @}
457   */
458 
459 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
460  *  @brief   management functions
461  *
462 @verbatim
463  ===============================================================================
464                       ##### Peripheral Control functions #####
465  ===============================================================================
466     [..]
467     This subsection provides a set of functions allowing to control the FLASH
468     memory operations.
469 
470 @endverbatim
471   * @{
472   */
473 
474 /**
475   * @brief  Unlock the FLASH control register access
476   * @retval HAL Status
477   */
HAL_FLASH_Unlock(void)478 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
479 {
480   uint32_t primask_bit;
481 
482   /* Unlocking FLASH_PECR register access*/
483   if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
484   {
485     /* Disable interrupts to avoid any interruption during unlock sequence */
486     primask_bit = __get_PRIMASK();
487     __disable_irq();
488 
489     WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
490     WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
491 
492     /* Re-enable the interrupts: restore previous priority mask */
493     __set_PRIMASK(primask_bit);
494 
495     if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
496     {
497       return HAL_ERROR;
498     }
499   }
500 
501   if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
502   {
503     /* Disable interrupts to avoid any interruption during unlock sequence */
504     primask_bit = __get_PRIMASK();
505     __disable_irq();
506 
507     /* Unlocking the program memory access */
508     WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY1);
509     WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY2);
510 
511     /* Re-enable the interrupts: restore previous priority mask */
512     __set_PRIMASK(primask_bit);
513 
514     if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
515     {
516       return HAL_ERROR;
517     }
518   }
519 
520   return HAL_OK;
521 }
522 
523 /**
524   * @brief  Locks the FLASH control register access
525   * @retval HAL Status
526   */
HAL_FLASH_Lock(void)527 HAL_StatusTypeDef HAL_FLASH_Lock(void)
528 {
529   /* Set the PRGLOCK Bit to lock the FLASH Registers access */
530   SET_BIT(FLASH->PECR, FLASH_PECR_PRGLOCK);
531 
532   /* Set the PELOCK Bit to lock the PECR Register access */
533   SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);
534 
535   return HAL_OK;
536 }
537 
538 /**
539   * @brief  Unlock the FLASH Option Control Registers access.
540   * @retval HAL Status
541   */
HAL_FLASH_OB_Unlock(void)542 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
543 {
544   uint32_t primask_bit;
545 
546   if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_OPTLOCK))
547   {
548     /* Disable interrupts to avoid any interruption during unlock sequence */
549     primask_bit = __get_PRIMASK();
550     __disable_irq();
551 
552     /* Unlocking FLASH_PECR register access*/
553     if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
554     {
555       /* Unlocking FLASH_PECR register access*/
556       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
557       WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
558     }
559 
560     /* Unlocking the option bytes block access */
561     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
562     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
563 
564     /* Re-enable the interrupts: restore previous priority mask */
565     __set_PRIMASK(primask_bit);
566   }
567   else
568   {
569     return HAL_ERROR;
570   }
571 
572   return HAL_OK;
573 }
574 
575 /**
576   * @brief  Lock the FLASH Option Control Registers access.
577   * @retval HAL Status
578   */
HAL_FLASH_OB_Lock(void)579 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
580 {
581   /* Set the OPTLOCK Bit to lock the option bytes block access */
582   SET_BIT(FLASH->PECR, FLASH_PECR_OPTLOCK);
583 
584   return HAL_OK;
585 }
586 
587 /**
588   * @brief  Launch the option byte loading.
589   * @note   This function will reset automatically the MCU.
590   * @retval HAL Status
591   */
HAL_FLASH_OB_Launch(void)592 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
593 {
594   /* Set the OBL_Launch bit to launch the option byte loading */
595   SET_BIT(FLASH->PECR, FLASH_PECR_OBL_LAUNCH);
596 
597   /* Wait for last operation to be completed */
598   return(FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE));
599 }
600 
601 /**
602   * @}
603   */
604 
605 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
606  *  @brief    Peripheral errors functions
607  *
608 @verbatim
609  ===============================================================================
610                       ##### Peripheral Errors functions #####
611  ===============================================================================
612     [..]
613     This subsection permit to get in run-time errors of  the FLASH peripheral.
614 
615 @endverbatim
616   * @{
617   */
618 
619 /**
620   * @brief  Get the specific FLASH error flag.
621   * @retval FLASH_ErrorCode The returned value can be:
622   *            @ref FLASH_Error_Codes
623   */
HAL_FLASH_GetError(void)624 uint32_t HAL_FLASH_GetError(void)
625 {
626    return pFlash.ErrorCode;
627 }
628 
629 /**
630   * @}
631   */
632 
633 /**
634   * @}
635   */
636 
637 /** @addtogroup FLASH_Private_Functions
638  * @{
639  */
640 
641 /**
642   * @brief  Wait for a FLASH operation to complete.
643   * @param  Timeout  maximum flash operation timeout
644   * @retval HAL Status
645   */
FLASH_WaitForLastOperation(uint32_t Timeout)646 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
647 {
648   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
649      Even if the FLASH operation fails, the BUSY flag will be reset and an error
650      flag will be set */
651 
652   uint32_t tickstart = HAL_GetTick();
653 
654   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
655   {
656     if (Timeout != HAL_MAX_DELAY)
657     {
658       if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
659       {
660         return HAL_TIMEOUT;
661       }
662     }
663   }
664 
665   /* Check FLASH End of Operation flag  */
666   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
667   {
668     /* Clear FLASH End of Operation pending bit */
669     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
670   }
671 
672   if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)     ||
673       __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)     ||
674       __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)     ||
675       __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)    ||
676       __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)      ||
677       __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR)     ||
678       __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) )
679   {
680     /*Save the error code*/
681 
682     /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
683      *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
684      *           as expected. If the user run an application using the first
685      *           cut of the STM32L031xx device or the first cut of the STM32L041xx
686      *           device, this error should be ignored. The revId of the device
687      *           can be retrieved via the HAL_GetREVID() function.
688      *
689      */
690     FLASH_SetErrorCode();
691     return HAL_ERROR;
692   }
693 
694   /* There is no error flag set */
695   return HAL_OK;
696 }
697 
698 
699 /**
700   * @brief  Set the specific FLASH error flag.
701   * @retval None
702   */
FLASH_SetErrorCode(void)703 static void FLASH_SetErrorCode(void)
704 {
705   uint32_t flags = 0;
706 
707   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
708   {
709     pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
710     flags |= FLASH_FLAG_WRPERR;
711   }
712   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
713   {
714     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
715     flags |= FLASH_FLAG_PGAERR;
716   }
717   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR))
718   {
719     pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE;
720     flags |= FLASH_FLAG_SIZERR;
721   }
722   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
723   {
724     /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
725      *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
726      *           as expected. If the user run an application using the first
727      *           cut of the STM32L031xx device or the first cut of the STM32L041xx
728      *           device, this error should be ignored. The revId of the device
729      *           can be retrieved via the HAL_GetREVID() function.
730      *
731      */
732     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
733     flags |= FLASH_FLAG_OPTVERR;
734   }
735 
736   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
737   {
738     pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
739     flags |= FLASH_FLAG_RDERR;
740   }
741   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR))
742   {
743     pFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR;
744     flags |= HAL_FLASH_ERROR_FWWERR;
745   }
746   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR))
747   {
748     pFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO;
749     flags |= FLASH_FLAG_NOTZEROERR;
750   }
751 
752   /* Clear FLASH error pending bits */
753   __HAL_FLASH_CLEAR_FLAG(flags);
754 }
755 /**
756   * @}
757   */
758 
759 /**
760   * @}
761   */
762 
763 #endif /* HAL_FLASH_MODULE_ENABLED */
764 
765 /**
766   * @}
767   */
768 
769 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
770