1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_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 STM32F1xx 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, erase all pages
41         (++) Program functions: half word, word and doubleword
42       (#) FLASH Option Bytes Programming functions: this group includes all needed
43           functions to manage the Option Bytes:
44         (++) Lock and Unlock the Option Bytes
45         (++) Set/Reset the write protection
46         (++) Set the Read protection Level
47         (++) Program the user Option Bytes
48         (++) Launch the Option Bytes loader
49         (++) Erase Option Bytes
50         (++) Program the data Option Bytes
51         (++) Get the Write protection.
52         (++) Get the user option bytes.
53 
54       (#) Interrupts and flags management functions : this group
55           includes all needed functions to:
56         (++) Handle FLASH interrupts
57         (++) Wait for last FLASH operation according to its status
58         (++) Get error flag status
59 
60   [..] In addition to these function, this driver includes a set of macros allowing
61        to handle the following operations:
62 
63       (+) Set/Get the latency
64       (+) Enable/Disable the prefetch buffer
65       (+) Enable/Disable the half cycle access
66       (+) Enable/Disable the FLASH interrupts
67       (+) Monitor the FLASH flags status
68 
69   @endverbatim
70   ******************************************************************************
71   * @attention
72   *
73   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
74   * All rights reserved.</center></h2>
75   *
76   * This software component is licensed by ST under BSD 3-Clause license,
77   * the "License"; You may not use this file except in compliance with the
78   * License. You may obtain a copy of the License at:
79   *                        opensource.org/licenses/BSD-3-Clause
80   *
81   ******************************************************************************
82   */
83 
84 /* Includes ------------------------------------------------------------------*/
85 #include "stm32f1xx_hal.h"
86 
87 /** @addtogroup STM32F1xx_HAL_Driver
88   * @{
89   */
90 
91 #ifdef HAL_FLASH_MODULE_ENABLED
92 
93 /** @defgroup FLASH FLASH
94   * @brief FLASH HAL module driver
95   * @{
96   */
97 
98 /* Private typedef -----------------------------------------------------------*/
99 /* Private define ------------------------------------------------------------*/
100 /** @defgroup FLASH_Private_Constants FLASH Private Constants
101   * @{
102   */
103 /**
104   * @}
105   */
106 
107 /* Private macro ---------------------------- ---------------------------------*/
108 /** @defgroup FLASH_Private_Macros FLASH Private Macros
109   * @{
110   */
111 
112 /**
113   * @}
114   */
115 
116 /* Private variables ---------------------------------------------------------*/
117 /** @defgroup FLASH_Private_Variables FLASH Private Variables
118   * @{
119   */
120 /* Variables used for Erase pages under interruption*/
121 FLASH_ProcessTypeDef pFlash;
122 /**
123   * @}
124   */
125 
126 /* Private function prototypes -----------------------------------------------*/
127 /** @defgroup FLASH_Private_Functions FLASH Private Functions
128   * @{
129   */
130 static  void   FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
131 static  void   FLASH_SetErrorCode(void);
132 extern void    FLASH_PageErase(uint32_t PageAddress);
133 /**
134   * @}
135   */
136 
137 /* Exported functions ---------------------------------------------------------*/
138 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
139   * @{
140   */
141 
142 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
143   *  @brief   Programming operation functions
144   *
145 @verbatim
146 @endverbatim
147   * @{
148   */
149 
150 /**
151   * @brief  Program halfword, word or double word at a specified address
152   * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
153   *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
154   *
155   * @note   If an erase and a program operations are requested simultaneously,
156   *         the erase operation is performed before the program one.
157   *
158   * @note   FLASH should be previously erased before new programmation (only exception to this
159   *         is when 0x0000 is programmed)
160   *
161   * @param  TypeProgram:  Indicate the way to program at a specified address.
162   *                       This parameter can be a value of @ref FLASH_Type_Program
163   * @param  Address:      Specifies the address to be programmed.
164   * @param  Data:         Specifies the data to be programmed
165   *
166   * @retval HAL_StatusTypeDef HAL Status
167   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint64_t Data)168 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
169 {
170   HAL_StatusTypeDef status = HAL_ERROR;
171   uint8_t index = 0;
172   uint8_t nbiterations = 0;
173 
174   /* Process Locked */
175   __HAL_LOCK(&pFlash);
176 
177   /* Check the parameters */
178   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
179   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
180 
181 #if defined(FLASH_BANK2_END)
182   if(Address <= FLASH_BANK1_END)
183   {
184 #endif /* FLASH_BANK2_END */
185     /* Wait for last operation to be completed */
186     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
187 #if defined(FLASH_BANK2_END)
188   }
189   else
190   {
191     /* Wait for last operation to be completed */
192     status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
193   }
194 #endif /* FLASH_BANK2_END */
195 
196   if(status == HAL_OK)
197   {
198     if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
199     {
200       /* Program halfword (16-bit) at a specified address. */
201       nbiterations = 1U;
202     }
203     else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
204     {
205       /* Program word (32-bit = 2*16-bit) at a specified address. */
206       nbiterations = 2U;
207     }
208     else
209     {
210       /* Program double word (64-bit = 4*16-bit) at a specified address. */
211       nbiterations = 4U;
212     }
213 
214     for (index = 0U; index < nbiterations; index++)
215     {
216       FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*index)));
217 
218 #if defined(FLASH_BANK2_END)
219       if(Address <= FLASH_BANK1_END)
220       {
221 #endif /* FLASH_BANK2_END */
222         /* Wait for last operation to be completed */
223         status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
224 
225         /* If the program operation is completed, disable the PG Bit */
226         CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
227 #if defined(FLASH_BANK2_END)
228       }
229       else
230       {
231         /* Wait for last operation to be completed */
232         status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
233 
234         /* If the program operation is completed, disable the PG Bit */
235         CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
236       }
237 #endif /* FLASH_BANK2_END */
238       /* In case of error, stop programation procedure */
239       if (status != HAL_OK)
240       {
241         break;
242       }
243     }
244   }
245 
246   /* Process Unlocked */
247   __HAL_UNLOCK(&pFlash);
248 
249   return status;
250 }
251 
252 /**
253   * @brief  Program halfword, word or double word at a specified address  with interrupt enabled.
254   * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
255   *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
256   *
257   * @note   If an erase and a program operations are requested simultaneously,
258   *         the erase operation is performed before the program one.
259   *
260   * @param  TypeProgram: Indicate the way to program at a specified address.
261   *                      This parameter can be a value of @ref FLASH_Type_Program
262   * @param  Address:     Specifies the address to be programmed.
263   * @param  Data:        Specifies the data to be programmed
264   *
265   * @retval HAL_StatusTypeDef HAL Status
266   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint64_t Data)267 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
268 {
269   HAL_StatusTypeDef status = HAL_OK;
270 
271   /* Process Locked */
272   __HAL_LOCK(&pFlash);
273 
274   /* Check the parameters */
275   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
276   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
277 
278 #if defined(FLASH_BANK2_END)
279   /* If procedure already ongoing, reject the next one */
280   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
281   {
282     return HAL_ERROR;
283   }
284 
285   if(Address <= FLASH_BANK1_END)
286   {
287     /* Enable End of FLASH Operation and Error source interrupts */
288     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
289 
290   }else
291   {
292     /* Enable End of FLASH Operation and Error source interrupts */
293     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
294   }
295 #else
296   /* Enable End of FLASH Operation and Error source interrupts */
297   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
298 #endif /* FLASH_BANK2_END */
299 
300   pFlash.Address = Address;
301   pFlash.Data = Data;
302 
303   if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
304   {
305     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
306     /* Program halfword (16-bit) at a specified address. */
307     pFlash.DataRemaining = 1U;
308   }
309   else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
310   {
311     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
312     /* Program word (32-bit : 2*16-bit) at a specified address. */
313     pFlash.DataRemaining = 2U;
314   }
315   else
316   {
317     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
318     /* Program double word (64-bit : 4*16-bit) at a specified address. */
319     pFlash.DataRemaining = 4U;
320   }
321 
322   /* Program halfword (16-bit) at a specified address. */
323   FLASH_Program_HalfWord(Address, (uint16_t)Data);
324 
325   return status;
326 }
327 
328 /**
329   * @brief This function handles FLASH interrupt request.
330   * @retval None
331   */
HAL_FLASH_IRQHandler(void)332 void HAL_FLASH_IRQHandler(void)
333 {
334   uint32_t addresstmp = 0U;
335 
336   /* Check FLASH operation error flags */
337 #if defined(FLASH_BANK2_END)
338   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
339     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
340 #else
341   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
342 #endif /* FLASH_BANK2_END */
343   {
344     /* Return the faulty address */
345     addresstmp = pFlash.Address;
346     /* Reset address */
347     pFlash.Address = 0xFFFFFFFFU;
348 
349     /* Save the Error code */
350     FLASH_SetErrorCode();
351 
352     /* FLASH error interrupt user callback */
353     HAL_FLASH_OperationErrorCallback(addresstmp);
354 
355     /* Stop the procedure ongoing */
356     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
357   }
358 
359   /* Check FLASH End of Operation flag  */
360 #if defined(FLASH_BANK2_END)
361   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
362   {
363     /* Clear FLASH End of Operation pending bit */
364     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
365 #else
366   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
367   {
368     /* Clear FLASH End of Operation pending bit */
369     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
370 #endif /* FLASH_BANK2_END */
371 
372     /* Process can continue only if no error detected */
373     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
374     {
375       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
376       {
377         /* Nb of pages to erased can be decreased */
378         pFlash.DataRemaining--;
379 
380         /* Check if there are still pages to erase */
381         if(pFlash.DataRemaining != 0U)
382         {
383           addresstmp = pFlash.Address;
384           /*Indicate user which sector has been erased */
385           HAL_FLASH_EndOfOperationCallback(addresstmp);
386 
387           /*Increment sector number*/
388           addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
389           pFlash.Address = addresstmp;
390 
391           /* If the erase operation is completed, disable the PER Bit */
392           CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
393 
394           FLASH_PageErase(addresstmp);
395         }
396         else
397         {
398           /* No more pages to Erase, user callback can be called. */
399           /* Reset Sector and stop Erase pages procedure */
400           pFlash.Address = addresstmp = 0xFFFFFFFFU;
401           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
402           /* FLASH EOP interrupt user callback */
403           HAL_FLASH_EndOfOperationCallback(addresstmp);
404         }
405       }
406       else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
407       {
408         /* Operation is completed, disable the MER Bit */
409         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
410 
411 #if defined(FLASH_BANK2_END)
412         /* Stop Mass Erase procedure if no pending mass erase on other bank */
413         if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
414         {
415 #endif /* FLASH_BANK2_END */
416           /* MassErase ended. Return the selected bank */
417           /* FLASH EOP interrupt user callback */
418           HAL_FLASH_EndOfOperationCallback(0U);
419 
420           /* Stop Mass Erase procedure*/
421           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
422         }
423 #if defined(FLASH_BANK2_END)
424       }
425 #endif /* FLASH_BANK2_END */
426       else
427       {
428         /* Nb of 16-bit data to program can be decreased */
429         pFlash.DataRemaining--;
430 
431         /* Check if there are still 16-bit data to program */
432         if(pFlash.DataRemaining != 0U)
433         {
434           /* Increment address to 16-bit */
435           pFlash.Address += 2U;
436           addresstmp = pFlash.Address;
437 
438           /* Shift to have next 16-bit data */
439           pFlash.Data = (pFlash.Data >> 16U);
440 
441           /* Operation is completed, disable the PG Bit */
442           CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
443 
444           /*Program halfword (16-bit) at a specified address.*/
445           FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
446         }
447         else
448         {
449           /* Program ended. Return the selected address */
450           /* FLASH EOP interrupt user callback */
451           if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
452           {
453             HAL_FLASH_EndOfOperationCallback(pFlash.Address);
454           }
455           else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
456           {
457             HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2U);
458           }
459           else
460           {
461             HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6U);
462           }
463 
464           /* Reset Address and stop Program procedure */
465           pFlash.Address = 0xFFFFFFFFU;
466           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
467         }
468       }
469     }
470   }
471 
472 #if defined(FLASH_BANK2_END)
473   /* Check FLASH End of Operation flag  */
474   if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
475   {
476     /* Clear FLASH End of Operation pending bit */
477     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
478 
479     /* Process can continue only if no error detected */
480     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
481     {
482       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
483       {
484         /* Nb of pages to erased can be decreased */
485         pFlash.DataRemaining--;
486 
487         /* Check if there are still pages to erase*/
488         if(pFlash.DataRemaining != 0U)
489         {
490           /* Indicate user which page address has been erased*/
491           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
492 
493           /* Increment page address to next page */
494           pFlash.Address += FLASH_PAGE_SIZE;
495           addresstmp = pFlash.Address;
496 
497           /* Operation is completed, disable the PER Bit */
498           CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
499 
500           FLASH_PageErase(addresstmp);
501         }
502         else
503         {
504           /*No more pages to Erase*/
505 
506           /*Reset Address and stop Erase pages procedure*/
507           pFlash.Address = 0xFFFFFFFFU;
508           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
509 
510           /* FLASH EOP interrupt user callback */
511           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
512         }
513       }
514       else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
515       {
516         /* Operation is completed, disable the MER Bit */
517         CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
518 
519         if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
520         {
521           /* MassErase ended. Return the selected bank*/
522           /* FLASH EOP interrupt user callback */
523           HAL_FLASH_EndOfOperationCallback(0U);
524 
525           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
526         }
527       }
528       else
529       {
530         /* Nb of 16-bit data to program can be decreased */
531         pFlash.DataRemaining--;
532 
533         /* Check if there are still 16-bit data to program */
534         if(pFlash.DataRemaining != 0U)
535         {
536           /* Increment address to 16-bit */
537           pFlash.Address += 2U;
538           addresstmp = pFlash.Address;
539 
540           /* Shift to have next 16-bit data */
541           pFlash.Data = (pFlash.Data >> 16U);
542 
543           /* Operation is completed, disable the PG Bit */
544           CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
545 
546           /*Program halfword (16-bit) at a specified address.*/
547           FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
548         }
549         else
550         {
551           /*Program ended. Return the selected address*/
552           /* FLASH EOP interrupt user callback */
553           if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
554           {
555             HAL_FLASH_EndOfOperationCallback(pFlash.Address);
556           }
557           else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
558           {
559             HAL_FLASH_EndOfOperationCallback(pFlash.Address-2U);
560           }
561           else
562           {
563             HAL_FLASH_EndOfOperationCallback(pFlash.Address-6U);
564           }
565 
566           /* Reset Address and stop Program procedure*/
567           pFlash.Address = 0xFFFFFFFFU;
568           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
569         }
570       }
571     }
572   }
573 #endif
574 
575   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
576   {
577 #if defined(FLASH_BANK2_END)
578     /* Operation is completed, disable the PG, PER and MER Bits for both bank */
579     CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
580     CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));
581 
582     /* Disable End of FLASH Operation and Error source interrupts for both banks */
583     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
584 #else
585     /* Operation is completed, disable the PG, PER and MER Bits */
586     CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
587 
588     /* Disable End of FLASH Operation and Error source interrupts */
589     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
590 #endif /* FLASH_BANK2_END */
591 
592     /* Process Unlocked */
593     __HAL_UNLOCK(&pFlash);
594   }
595 }
596 
597 /**
598   * @brief  FLASH end of operation interrupt callback
599   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
600   *                 - Mass Erase: No return value expected
601   *                 - Pages Erase: Address of the page which has been erased
602   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
603   *                 - Program: Address which was selected for data program
604   * @retval none
605   */
606 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
607 {
608   /* Prevent unused argument(s) compilation warning */
609   UNUSED(ReturnValue);
610 
611   /* NOTE : This function Should not be modified, when the callback is needed,
612             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
613    */
614 }
615 
616 /**
617   * @brief  FLASH operation error interrupt callback
618   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
619   *                 - Mass Erase: No return value expected
620   *                 - Pages Erase: Address of the page which returned an error
621   *                 - Program: Address which was selected for data program
622   * @retval none
623   */
624 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
625 {
626   /* Prevent unused argument(s) compilation warning */
627   UNUSED(ReturnValue);
628 
629   /* NOTE : This function Should not be modified, when the callback is needed,
630             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
631    */
632 }
633 
634 /**
635   * @}
636   */
637 
638 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
639  *  @brief   management functions
640  *
641 @verbatim
642  ===============================================================================
643                       ##### Peripheral Control functions #####
644  ===============================================================================
645     [..]
646     This subsection provides a set of functions allowing to control the FLASH
647     memory operations.
648 
649 @endverbatim
650   * @{
651   */
652 
653 /**
654   * @brief  Unlock the FLASH control register access
655   * @retval HAL Status
656   */
657 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
658 {
659   HAL_StatusTypeDef status = HAL_OK;
660 
661   if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
662   {
663     /* Authorize the FLASH Registers access */
664     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
665     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
666 
667     /* Verify Flash is unlocked */
668     if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
669     {
670       status = HAL_ERROR;
671     }
672   }
673 #if defined(FLASH_BANK2_END)
674   if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
675   {
676     /* Authorize the FLASH BANK2 Registers access */
677     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
678     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
679 
680     /* Verify Flash BANK2 is unlocked */
681     if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
682     {
683       status = HAL_ERROR;
684     }
685   }
686 #endif /* FLASH_BANK2_END */
687 
688   return status;
689 }
690 
691 /**
692   * @brief  Locks the FLASH control register access
693   * @retval HAL Status
694   */
695 HAL_StatusTypeDef HAL_FLASH_Lock(void)
696 {
697   /* Set the LOCK Bit to lock the FLASH Registers access */
698   SET_BIT(FLASH->CR, FLASH_CR_LOCK);
699 
700 #if defined(FLASH_BANK2_END)
701   /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
702   SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
703 
704 #endif /* FLASH_BANK2_END */
705   return HAL_OK;
706 }
707 
708 /**
709   * @brief  Unlock the FLASH Option Control Registers access.
710   * @retval HAL Status
711   */
712 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
713 {
714   if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
715   {
716     /* Authorizes the Option Byte register programming */
717     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
718     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
719   }
720   else
721   {
722     return HAL_ERROR;
723   }
724 
725   return HAL_OK;
726 }
727 
728 /**
729   * @brief  Lock the FLASH Option Control Registers access.
730   * @retval HAL Status
731   */
732 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
733 {
734   /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
735   CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
736 
737   return HAL_OK;
738 }
739 
740 /**
741   * @brief  Launch the option byte loading.
742   * @note   This function will reset automatically the MCU.
743   * @retval None
744   */
745 void HAL_FLASH_OB_Launch(void)
746 {
747   /* Initiates a system reset request to launch the option byte loading */
748   HAL_NVIC_SystemReset();
749 }
750 
751 /**
752   * @}
753   */
754 
755 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
756  *  @brief    Peripheral errors functions
757  *
758 @verbatim
759  ===============================================================================
760                       ##### Peripheral Errors functions #####
761  ===============================================================================
762     [..]
763     This subsection permit to get in run-time errors of  the FLASH peripheral.
764 
765 @endverbatim
766   * @{
767   */
768 
769 /**
770   * @brief  Get the specific FLASH error flag.
771   * @retval FLASH_ErrorCode The returned value can be:
772   *            @ref FLASH_Error_Codes
773   */
774 uint32_t HAL_FLASH_GetError(void)
775 {
776    return pFlash.ErrorCode;
777 }
778 
779 /**
780   * @}
781   */
782 
783 /**
784   * @}
785   */
786 
787 /** @addtogroup FLASH_Private_Functions
788  * @{
789  */
790 
791 /**
792   * @brief  Program a half-word (16-bit) at a specified address.
793   * @param  Address specify the address to be programmed.
794   * @param  Data    specify the data to be programmed.
795   * @retval None
796   */
797 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
798 {
799   /* Clean the error context */
800   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
801 
802 #if defined(FLASH_BANK2_END)
803   if(Address <= FLASH_BANK1_END)
804   {
805 #endif /* FLASH_BANK2_END */
806     /* Proceed to program the new data */
807     SET_BIT(FLASH->CR, FLASH_CR_PG);
808 #if defined(FLASH_BANK2_END)
809   }
810   else
811   {
812     /* Proceed to program the new data */
813     SET_BIT(FLASH->CR2, FLASH_CR2_PG);
814   }
815 #endif /* FLASH_BANK2_END */
816 
817   /* Write data in the address */
818   *(__IO uint16_t*)Address = Data;
819 }
820 
821 /**
822   * @brief  Wait for a FLASH operation to complete.
823   * @param  Timeout  maximum flash operation timeout
824   * @retval HAL Status
825   */
826 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
827 {
828   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
829      Even if the FLASH operation fails, the BUSY flag will be reset and an error
830      flag will be set */
831 
832   uint32_t tickstart = HAL_GetTick();
833 
834   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
835   {
836     if (Timeout != HAL_MAX_DELAY)
837     {
838       if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
839       {
840         return HAL_TIMEOUT;
841       }
842     }
843   }
844 
845   /* Check FLASH End of Operation flag  */
846   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
847   {
848     /* Clear FLASH End of Operation pending bit */
849     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
850   }
851 
852   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)  ||
853      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
854      __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
855   {
856     /*Save the error code*/
857     FLASH_SetErrorCode();
858     return HAL_ERROR;
859   }
860 
861   /* There is no error flag set */
862   return HAL_OK;
863 }
864 
865 #if defined(FLASH_BANK2_END)
866 /**
867   * @brief  Wait for a FLASH BANK2 operation to complete.
868   * @param  Timeout maximum flash operation timeout
869   * @retval HAL_StatusTypeDef HAL Status
870   */
871 HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
872 {
873   /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
874      Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
875      flag will be set */
876 
877   uint32_t tickstart = HAL_GetTick();
878 
879   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2))
880   {
881     if (Timeout != HAL_MAX_DELAY)
882     {
883       if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
884       {
885         return HAL_TIMEOUT;
886       }
887     }
888   }
889 
890   /* Check FLASH End of Operation flag  */
891   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
892   {
893     /* Clear FLASH End of Operation pending bit */
894     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
895   }
896 
897   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
898   {
899     /*Save the error code*/
900     FLASH_SetErrorCode();
901     return HAL_ERROR;
902   }
903 
904   /* If there is an error flag set */
905   return HAL_OK;
906 
907 }
908 #endif /* FLASH_BANK2_END */
909 
910 /**
911   * @brief  Set the specific FLASH error flag.
912   * @retval None
913   */
914 static void FLASH_SetErrorCode(void)
915 {
916   uint32_t flags = 0U;
917 
918 #if defined(FLASH_BANK2_END)
919   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
920 #else
921   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
922 #endif /* FLASH_BANK2_END */
923   {
924     pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
925 #if defined(FLASH_BANK2_END)
926     flags |= FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2;
927 #else
928     flags |= FLASH_FLAG_WRPERR;
929 #endif /* FLASH_BANK2_END */
930   }
931 #if defined(FLASH_BANK2_END)
932   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
933 #else
934   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
935 #endif /* FLASH_BANK2_END */
936   {
937     pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
938 #if defined(FLASH_BANK2_END)
939     flags |= FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2;
940 #else
941     flags |= FLASH_FLAG_PGERR;
942 #endif /* FLASH_BANK2_END */
943   }
944   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
945   {
946     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
947   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
948   }
949 
950   /* Clear FLASH error pending bits */
951   __HAL_FLASH_CLEAR_FLAG(flags);
952 }
953 /**
954   * @}
955   */
956 
957 /**
958   * @}
959   */
960 
961 #endif /* HAL_FLASH_MODULE_ENABLED */
962 
963 /**
964   * @}
965   */
966 
967 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
968