1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_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 Errors functions
11   *
12  @verbatim
13   ==============================================================================
14                         ##### FLASH peripheral features #####
15   ==============================================================================
16 
17   [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
18        to the Flash memory. It implements the erase and program Flash memory operations
19        and the read and write protection mechanisms.
20 
21   [..] The Flash memory interface accelerates code execution with a system of instruction
22        prefetch and cache lines.
23 
24   [..] The FLASH main features are:
25       (+) Flash memory read operations
26       (+) Flash memory program/erase operations
27       (+) Read / write protections
28       (+) Option bytes programming
29       (+) Prefetch on I-Code
30       (+) 32 cache lines of 4*64 bits on I-Code
31       (+) 8 cache lines of 4*64 bits on D-Code
32       (+) Error code correction (ECC) : Data in flash are 72-bits word
33           (8 bits added per double word)
34 
35 
36                         ##### How to use this driver #####
37  ==============================================================================
38     [..]
39       This driver provides functions and macros to configure and program the FLASH
40       memory of all STM32L4xx devices.
41 
42       (#) Flash Memory IO Programming functions:
43            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
44                 HAL_FLASH_Lock() functions
45            (++) Program functions: double word and fast program (full row programming)
46            (++) There Two modes of programming :
47             (+++) Polling mode using HAL_FLASH_Program() function
48             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
49 
50       (#) Interrupts and flags management functions :
51            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
52            (++) Callback functions are called when the flash operations are finished :
53                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
54                 HAL_FLASH_OperationErrorCallback()
55            (++) Get error flag status by calling HAL_GetError()
56 
57       (#) Option bytes management functions :
58            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
59                 HAL_FLASH_OB_Lock() functions
60            (++) Launch the reload of the option bytes using HAL_FLASH_Launch() function.
61                 In this case, a reset is generated
62 
63     [..]
64       In addition to these functions, this driver includes a set of macros allowing
65       to handle the following operations:
66        (+) Set the latency
67        (+) Enable/Disable the prefetch buffer
68        (+) Enable/Disable the Instruction cache and the Data cache
69        (+) Reset the Instruction cache and the Data cache
70        (+) Enable/Disable the Flash power-down during low-power run and sleep modes
71        (+) Enable/Disable the Flash interrupts
72        (+) Monitor the Flash flags status
73 
74  @endverbatim
75   ******************************************************************************
76   * @attention
77   *
78   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
79   *
80   * Redistribution and use in source and binary forms, with or without modification,
81   * are permitted provided that the following conditions are met:
82   *   1. Redistributions of source code must retain the above copyright notice,
83   *      this list of conditions and the following disclaimer.
84   *   2. Redistributions in binary form must reproduce the above copyright notice,
85   *      this list of conditions and the following disclaimer in the documentation
86   *      and/or other materials provided with the distribution.
87   *   3. Neither the name of STMicroelectronics nor the names of its contributors
88   *      may be used to endorse or promote products derived from this software
89   *      without specific prior written permission.
90   *
91   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
92   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
95   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
97   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
98   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
99   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
100   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101   *
102   ******************************************************************************
103   */
104 
105 /* Includes ------------------------------------------------------------------*/
106 #include "stm32l4xx_hal.h"
107 
108 /** @addtogroup STM32L4xx_HAL_Driver
109   * @{
110   */
111 
112 /** @defgroup FLASH FLASH
113   * @brief FLASH HAL module driver
114   * @{
115   */
116 
117 #ifdef HAL_FLASH_MODULE_ENABLED
118 
119 /* Private typedef -----------------------------------------------------------*/
120 /* Private defines -----------------------------------------------------------*/
121 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
122 #define FLASH_NB_DOUBLE_WORDS_IN_ROW  64
123 #else
124 #define FLASH_NB_DOUBLE_WORDS_IN_ROW  32
125 #endif
126 /* Private macros ------------------------------------------------------------*/
127 /* Private variables ---------------------------------------------------------*/
128 /** @defgroup FLASH_Private_Variables FLASH Private Variables
129  * @{
130  */
131 /**
132   * @brief  Variable used for Program/Erase sectors under interruption
133   */
134 extern FLASH_ProcessTypeDef pFlash;
135 FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
136                                .ErrorCode = HAL_FLASH_ERROR_NONE, \
137                                .ProcedureOnGoing = FLASH_PROC_NONE, \
138                                .Address = 0U, \
139                                .Bank = FLASH_BANK_1, \
140                                .Page = 0U, \
141                                .NbPagesToErase = 0U, \
142                                .CacheToReactivate = FLASH_CACHE_DISABLED};
143 /**
144   * @}
145   */
146 
147 /* Private function prototypes -----------------------------------------------*/
148 /** @defgroup FLASH_Private_Functions FLASH Private Functions
149  * @{
150  */
151 HAL_StatusTypeDef    FLASH_WaitForLastOperation(uint32_t Timeout);
152 extern void          FLASH_PageErase(uint32_t Page, uint32_t Banks);
153 extern void          FLASH_FlushCaches(void);
154 static void          FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
155 static void          FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress);
156 /**
157   * @}
158   */
159 
160 /* Exported functions --------------------------------------------------------*/
161 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
162   * @{
163   */
164 
165 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
166  *  @brief   Programming operation functions
167  *
168 @verbatim
169  ===============================================================================
170                   ##### Programming operation functions #####
171  ===============================================================================
172     [..]
173     This subsection provides a set of functions allowing to manage the FLASH
174     program operations.
175 
176 @endverbatim
177   * @{
178   */
179 
180 /**
181   * @brief  Program double word or fast program of a row at a specified address.
182   * @param  TypeProgram:  Indicate the way to program at a specified address.
183   *                           This parameter can be a value of @ref FLASH_Type_Program
184   * @param  Address:  specifies the address to be programmed.
185   * @param  Data: specifies the data to be programmed
186   *                This parameter is the data for the double word program and the address where
187   *                are stored the data for the row fast program
188   *
189   * @retval HAL_StatusTypeDef HAL Status
190   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint64_t Data)191 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
192 {
193   HAL_StatusTypeDef status;
194   uint32_t prog_bit = 0;
195 
196   /* Process Locked */
197   __HAL_LOCK(&pFlash);
198 
199   /* Check the parameters */
200   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
201 
202   /* Wait for last operation to be completed */
203   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
204 
205   if(status == HAL_OK)
206   {
207     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
208 
209     /* Deactivate the data cache if they are activated to avoid data misbehavior */
210     if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
211     {
212       /* Disable data cache  */
213       __HAL_FLASH_DATA_CACHE_DISABLE();
214       pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
215     }
216     else
217     {
218       pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
219     }
220 
221     if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
222     {
223       /* Program double-word (64-bit) at a specified address */
224       FLASH_Program_DoubleWord(Address, Data);
225       prog_bit = FLASH_CR_PG;
226     }
227     else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
228     {
229       /* Fast program a 32 row double-word (64-bit) at a specified address */
230       FLASH_Program_Fast(Address, (uint32_t)Data);
231 
232       /* If it is the last row, the bit will be cleared at the end of the operation */
233       if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
234       {
235         prog_bit = FLASH_CR_FSTPG;
236       }
237     }
238     else
239     {
240       /* Nothing to do */
241     }
242 
243     /* Wait for last operation to be completed */
244     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
245 
246     /* If the program operation is completed, disable the PG or FSTPG Bit */
247     if (prog_bit != 0U)
248     {
249       CLEAR_BIT(FLASH->CR, prog_bit);
250     }
251 
252     /* Flush the caches to be sure of the data consistency */
253     FLASH_FlushCaches();
254   }
255 
256   /* Process Unlocked */
257   __HAL_UNLOCK(&pFlash);
258 
259   return status;
260 }
261 
262 /**
263   * @brief  Program double word or fast program of a row at a specified address with interrupt enabled.
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:  specifies the address to be programmed.
267   * @param  Data: specifies the data to be programmed
268   *                This parameter is the data for the double word program and the address where
269   *                are stored the data for the row fast program
270   *
271   * @retval HAL Status
272   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint64_t Data)273 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
274 {
275   HAL_StatusTypeDef status = HAL_OK;
276 
277   /* Check the parameters */
278   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
279 
280   /* Process Locked */
281   __HAL_LOCK(&pFlash);
282 
283   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
284 
285   /* Deactivate the data cache if they are activated to avoid data misbehavior */
286   if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
287   {
288     /* Disable data cache  */
289     __HAL_FLASH_DATA_CACHE_DISABLE();
290     pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
291   }
292   else
293   {
294     pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
295   }
296 
297   /* Set internal variables used by the IRQ handler */
298   if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
299   {
300     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_LAST;
301   }
302   else
303   {
304     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
305   }
306   pFlash.Address = Address;
307 
308   /* Enable End of Operation and Error interrupts */
309   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
310 
311   if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
312   {
313     /* Program double-word (64-bit) at a specified address */
314     FLASH_Program_DoubleWord(Address, Data);
315   }
316   else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
317   {
318     /* Fast program a 32 row double-word (64-bit) at a specified address */
319     FLASH_Program_Fast(Address, (uint32_t)Data);
320   }
321   else
322   {
323     /* Nothing to do */
324   }
325 
326   return status;
327 }
328 
329 /**
330   * @brief Handle FLASH interrupt request.
331   * @retval None
332   */
HAL_FLASH_IRQHandler(void)333 void HAL_FLASH_IRQHandler(void)
334 {
335   uint32_t tmp_page;
336   uint32_t error;
337   FLASH_ProcedureTypeDef procedure;
338 
339   /* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */
340   CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_PER | FLASH_CR_PNB));
341 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
342     defined (STM32L496xx) || defined (STM32L4A6xx) || \
343     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
344   CLEAR_BIT(FLASH->CR, FLASH_CR_MER2);
345 #endif
346 
347   /* Disable the FSTPG Bit only if it is the last row programmed */
348   if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)
349   {
350     CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG);
351   }
352 
353   /* Check FLASH operation error flags */
354   error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
355   error |= (FLASH->ECCR & FLASH_FLAG_ECCC);
356 
357   if (error !=0U)
358   {
359     /*Save the error code*/
360     pFlash.ErrorCode |= error;
361 
362     /* Clear error programming flags */
363     __HAL_FLASH_CLEAR_FLAG(error);
364 
365     /* Flush the caches to be sure of the data consistency */
366     FLASH_FlushCaches() ;
367 
368     /* FLASH error interrupt user callback */
369     procedure = pFlash.ProcedureOnGoing;
370     if(procedure == FLASH_PROC_PAGE_ERASE)
371     {
372        HAL_FLASH_OperationErrorCallback(pFlash.Page);
373     }
374     else if(procedure == FLASH_PROC_MASS_ERASE)
375     {
376         HAL_FLASH_OperationErrorCallback(pFlash.Bank);
377     }
378     else if((procedure == FLASH_PROC_PROGRAM) ||
379             (procedure == FLASH_PROC_PROGRAM_LAST))
380     {
381        HAL_FLASH_OperationErrorCallback(pFlash.Address);
382     }
383     else
384     {
385        HAL_FLASH_OperationErrorCallback(0U);
386     }
387 
388     /*Stop the procedure ongoing*/
389     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
390   }
391 
392   /* Check FLASH End of Operation flag  */
393   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0U)
394   {
395     /* Clear FLASH End of Operation pending bit */
396     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
397 
398     if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE)
399     {
400       /* Nb of pages to erased can be decreased */
401       pFlash.NbPagesToErase--;
402 
403       /* Check if there are still pages to erase*/
404       if(pFlash.NbPagesToErase != 0U)
405       {
406         /* Indicate user which page has been erased*/
407         HAL_FLASH_EndOfOperationCallback(pFlash.Page);
408 
409         /* Increment page number */
410         pFlash.Page++;
411         tmp_page = pFlash.Page;
412         FLASH_PageErase(tmp_page, pFlash.Bank);
413       }
414       else
415       {
416         /* No more pages to Erase */
417         /* Reset Address and stop Erase pages procedure */
418         pFlash.Page = 0xFFFFFFFFU;
419         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
420 
421         /* Flush the caches to be sure of the data consistency */
422         FLASH_FlushCaches() ;
423 
424         /* FLASH EOP interrupt user callback */
425         HAL_FLASH_EndOfOperationCallback(pFlash.Page);
426       }
427     }
428     else
429     {
430       /* Flush the caches to be sure of the data consistency */
431       FLASH_FlushCaches() ;
432 
433       procedure = pFlash.ProcedureOnGoing;
434       if(procedure == FLASH_PROC_MASS_ERASE)
435       {
436         /* MassErase ended. Return the selected bank */
437         /* FLASH EOP interrupt user callback */
438         HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
439       }
440       else if((procedure == FLASH_PROC_PROGRAM) ||
441               (procedure == FLASH_PROC_PROGRAM_LAST))
442       {
443         /* Program ended. Return the selected address */
444         /* FLASH EOP interrupt user callback */
445         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
446       }
447       else
448       {
449         /* Nothing to do */
450       }
451 
452       /*Clear the procedure ongoing*/
453       pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
454     }
455   }
456 
457   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
458   {
459     /* Disable End of Operation and Error interrupts */
460     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
461 
462     /* Process Unlocked */
463     __HAL_UNLOCK(&pFlash);
464   }
465 }
466 
467 /**
468   * @brief  FLASH end of operation interrupt callback.
469   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
470   *                  Mass Erase: Bank number which has been requested to erase
471   *                  Page Erase: Page which has been erased
472   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
473   *                  Program: Address which was selected for data program
474   * @retval None
475   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)476 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
477 {
478   /* Prevent unused argument(s) compilation warning */
479   UNUSED(ReturnValue);
480 
481   /* NOTE : This function should not be modified, when the callback is needed,
482             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
483    */
484 }
485 
486 /**
487   * @brief  FLASH operation error interrupt callback.
488   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
489   *                 Mass Erase: Bank number which has been requested to erase
490   *                 Page Erase: Page number which returned an error
491   *                 Program: Address which was selected for data program
492   * @retval None
493   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)494 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
495 {
496   /* Prevent unused argument(s) compilation warning */
497   UNUSED(ReturnValue);
498 
499   /* NOTE : This function should not be modified, when the callback is needed,
500             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
501    */
502 }
503 
504 /**
505   * @}
506   */
507 
508 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
509  *  @brief   Management functions
510  *
511 @verbatim
512  ===============================================================================
513                       ##### Peripheral Control functions #####
514  ===============================================================================
515     [..]
516     This subsection provides a set of functions allowing to control the FLASH
517     memory operations.
518 
519 @endverbatim
520   * @{
521   */
522 
523 /**
524   * @brief  Unlock the FLASH control register access.
525   * @retval HAL Status
526   */
HAL_FLASH_Unlock(void)527 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
528 {
529   HAL_StatusTypeDef status = HAL_OK;
530 
531   if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
532   {
533     /* Authorize the FLASH Registers access */
534     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
535     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
536 
537     /* Verify Flash is unlocked */
538     if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
539     {
540       status = HAL_ERROR;
541     }
542   }
543 
544   return status;
545 }
546 
547 /**
548   * @brief  Lock the FLASH control register access.
549   * @retval HAL Status
550   */
HAL_FLASH_Lock(void)551 HAL_StatusTypeDef HAL_FLASH_Lock(void)
552 {
553   /* Set the LOCK Bit to lock the FLASH Registers access */
554   SET_BIT(FLASH->CR, FLASH_CR_LOCK);
555 
556   return HAL_OK;
557 }
558 
559 /**
560   * @brief  Unlock the FLASH Option Bytes Registers access.
561   * @retval HAL Status
562   */
HAL_FLASH_OB_Unlock(void)563 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
564 {
565   if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0U)
566   {
567     /* Authorizes the Option Byte register programming */
568     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
569     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
570   }
571   else
572   {
573     return HAL_ERROR;
574   }
575 
576   return HAL_OK;
577 }
578 
579 /**
580   * @brief  Lock the FLASH Option Bytes Registers access.
581   * @retval HAL Status
582   */
HAL_FLASH_OB_Lock(void)583 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
584 {
585   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
586   SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
587 
588   return HAL_OK;
589 }
590 
591 /**
592   * @brief  Launch the option byte loading.
593   * @retval HAL Status
594   */
HAL_FLASH_OB_Launch(void)595 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
596 {
597   /* Set the bit to force the option byte reloading */
598   SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
599 
600   /* Wait for last operation to be completed */
601   return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
602 }
603 
604 /**
605   * @}
606   */
607 
608 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
609  *  @brief   Peripheral Errors functions
610  *
611 @verbatim
612  ===============================================================================
613                 ##### Peripheral Errors functions #####
614  ===============================================================================
615     [..]
616     This subsection permits to get in run-time Errors of the FLASH peripheral.
617 
618 @endverbatim
619   * @{
620   */
621 
622 /**
623   * @brief  Get the specific FLASH error flag.
624   * @retval FLASH_ErrorCode: The returned value can be:
625   *            @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP)
626   *            @arg HAL_FLASH_ERROR_PGS: FLASH Programming Sequence error flag
627   *            @arg HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
628   *            @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag
629   *            @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag
630   *            @arg HAL_FLASH_ERROR_OPERATION: FLASH operation Error flag
631   *            @arg HAL_FLASH_ERROR_NONE: No error set
632   *            @arg HAL_FLASH_ERROR_OP: FLASH Operation error
633   *            @arg HAL_FLASH_ERROR_PROG: FLASH Programming error
634   *            @arg HAL_FLASH_ERROR_WRP: FLASH Write protection error
635   *            @arg HAL_FLASH_ERROR_PGA: FLASH Programming alignment error
636   *            @arg HAL_FLASH_ERROR_SIZ: FLASH Size error
637   *            @arg HAL_FLASH_ERROR_PGS: FLASH Programming sequence error
638   *            @arg HAL_FLASH_ERROR_MIS: FLASH Fast programming data miss error
639   *            @arg HAL_FLASH_ERROR_FAST: FLASH Fast programming error
640   *            @arg HAL_FLASH_ERROR_RD: FLASH PCROP read error
641   *            @arg HAL_FLASH_ERROR_OPTV: FLASH Option validity error
642   *            @arg FLASH_FLAG_PEMPTY : FLASH Boot from not programmed flash (apply only for STM32L43x/STM32L44x devices)
643   *            @arg HAL_FLASH_ERROR_ECCD: FLASH two ECC errors have been detected
644   */
HAL_FLASH_GetError(void)645 uint32_t HAL_FLASH_GetError(void)
646 {
647    return pFlash.ErrorCode;
648 }
649 
650 /**
651   * @}
652   */
653 
654 /**
655   * @}
656   */
657 
658 /* Private functions ---------------------------------------------------------*/
659 
660 /** @addtogroup FLASH_Private_Functions
661   * @{
662   */
663 
664 /**
665   * @brief  Wait for a FLASH operation to complete.
666   * @param  Timeout: maximum flash operation timeout
667   * @retval HAL_StatusTypeDef HAL Status
668   */
FLASH_WaitForLastOperation(uint32_t Timeout)669 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
670 {
671   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
672      Even if the FLASH operation fails, the BUSY flag will be reset and an error
673      flag will be set */
674 
675   uint32_t tickstart = HAL_GetTick();
676   uint32_t error;
677 
678   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
679   {
680     if(Timeout != HAL_MAX_DELAY)
681     {
682       if((HAL_GetTick() - tickstart) >= Timeout)
683       {
684         return HAL_TIMEOUT;
685       }
686     }
687   }
688 
689   error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
690   error |= (FLASH->ECCR & FLASH_FLAG_ECCD);
691 
692   if(error != 0u)
693   {
694     /*Save the error code*/
695     pFlash.ErrorCode |= error;
696 
697     /* Clear error programming flags */
698     __HAL_FLASH_CLEAR_FLAG(error);
699 
700     return HAL_ERROR;
701   }
702 
703   /* Check FLASH End of Operation flag  */
704   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
705   {
706     /* Clear FLASH End of Operation pending bit */
707     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
708   }
709 
710   /* If there is an error flag set */
711   return HAL_OK;
712 }
713 
714 /**
715   * @brief  Program double-word (64-bit) at a specified address.
716   * @param  Address: specifies the address to be programmed.
717   * @param  Data: specifies the data to be programmed.
718   * @retval None
719   */
FLASH_Program_DoubleWord(uint32_t Address,uint64_t Data)720 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
721 {
722   /* Check the parameters */
723   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
724 
725   /* Set PG bit */
726   SET_BIT(FLASH->CR, FLASH_CR_PG);
727 
728   /* Program the double word */
729   *(__IO uint32_t*)Address = (uint32_t)Data;
730   *(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
731 }
732 
733 /**
734   * @brief  Fast program a row double-word (64-bit) at a specified address.
735   * @param  Address: specifies the address to be programmed.
736   * @param  DataAddress: specifies the address where the data are stored.
737   * @retval None
738   */
FLASH_Program_Fast(uint32_t Address,uint32_t DataAddress)739 static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
740 {
741   uint8_t row_index = (2*FLASH_NB_DOUBLE_WORDS_IN_ROW);
742   __IO uint32_t *dest_addr = (__IO uint32_t*)Address;
743   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
744 
745   /* Check the parameters */
746   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
747 
748   /* Set FSTPG bit */
749   SET_BIT(FLASH->CR, FLASH_CR_FSTPG);
750 
751   /* Disable interrupts to avoid any interruption during the loop */
752   __disable_irq();
753 
754   /* Program the double word of the row */
755   do
756   {
757     *dest_addr = *src_addr;
758     dest_addr++;
759     src_addr++;
760     row_index--;
761   } while (row_index != 0U);
762 
763   /* Re-enable the interrupts */
764   __enable_irq();
765 }
766 
767 /**
768   * @}
769   */
770 
771 #endif /* HAL_FLASH_MODULE_ENABLED */
772 
773 /**
774   * @}
775   */
776 
777 /**
778   * @}
779   */
780 
781 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
782