1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_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 AXI 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 main features are:
22       (+) Flash memory read operations
23       (+) Flash memory program/erase operations
24       (+) Read / write protections
25       (+) Option bytes programming
26       (+) Error code correction (ECC) : Data in flash are 266-bits word
27           (10 bits added per flash word)
28 
29                         ##### How to use this driver #####
30  ==============================================================================
31     [..]
32       This driver provides functions and macros to configure and program the FLASH
33       memory of all STM32H7xx devices.
34 
35       (#) FLASH Memory IO Programming functions:
36            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
37                 HAL_FLASH_Lock() functions
38            (++) Program functions: 256-bit word only
39            (++) There Two modes of programming :
40             (+++) Polling mode using HAL_FLASH_Program() function
41             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
42 
43       (#) Interrupts and flags management functions :
44            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
45            (++) Callback functions are called when the flash operations are finished :
46                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
47                 HAL_FLASH_OperationErrorCallback()
48            (++) Get error flag status by calling HAL_FLASH_GetError()
49 
50       (#) Option bytes management functions :
51            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
52                 HAL_FLASH_OB_Lock() functions
53            (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
54                 In this case, a reset is generated
55     [..]
56       In addition to these functions, this driver includes a set of macros allowing
57       to handle the following operations:
58        (+) Set the latency
59        (+) Enable/Disable the FLASH interrupts
60        (+) Monitor the FLASH flags status
61      [..]
62     (@) For any Flash memory program operation (erase or program), the CPU clock frequency
63         (HCLK) must be at least 1MHz.
64     (@) The contents of the Flash memory are not guaranteed if a device reset occurs during
65         a Flash memory operation.
66     (@) The application can simultaneously request a read and a write operation through each AXI
67         interface.
68         As the Flash memory is divided into two independent banks, the embedded Flash
69         memory interface can drive different operations at the same time on each bank. For
70         example a read, write or erase operation can be executed on bank 1 while another read,
71         write or erase operation is executed on bank 2.
72 
73  @endverbatim
74   ******************************************************************************
75   * @attention
76   *
77   * Copyright (c) 2017 STMicroelectronics.
78   * All rights reserved.
79   *
80   * This software is licensed under terms that can be found in the LICENSE file in
81   * the root directory of this software component.
82   * If no LICENSE file comes with this software, it is provided AS-IS.
83   ******************************************************************************
84   */
85 
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32h7xx_hal.h"
88 
89 /** @addtogroup STM32H7xx_HAL_Driver
90   * @{
91   */
92 
93 /** @defgroup FLASH FLASH
94   * @brief FLASH HAL module driver
95   * @{
96   */
97 
98 #ifdef HAL_FLASH_MODULE_ENABLED
99 
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
102 /** @addtogroup FLASH_Private_Constants
103   * @{
104   */
105 #define FLASH_TIMEOUT_VALUE              50000U /* 50 s */
106 /**
107   * @}
108   */
109 /* Private macro -------------------------------------------------------------*/
110 /* Private variables ---------------------------------------------------------*/
111 /** @addtogroup FLASH_Private_Variables
112   * @{
113   */
114 FLASH_ProcessTypeDef pFlash;
115 /**
116   * @}
117   */
118 /* Private function prototypes -----------------------------------------------*/
119 /* Exported functions ---------------------------------------------------------*/
120 
121 /** @defgroup FLASH_Exported_Functions FLASH Exported functions
122   * @{
123   */
124 
125 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
126   *  @brief   Programming operation functions
127   *
128 @verbatim
129  ===============================================================================
130                   ##### Programming operation functions #####
131  ===============================================================================
132     [..]
133     This subsection provides a set of functions allowing to manage the FLASH
134     program operations.
135 
136 @endverbatim
137   * @{
138   */
139 
140 /**
141   * @brief  Program a flash word at a specified address
142   * @param  TypeProgram Indicate the way to program at a specified address.
143   *         This parameter can be a value of @ref FLASH_Type_Program
144   * @param  FlashAddress specifies the address to be programmed.
145   *         This parameter shall be aligned to the Flash word:
146   *          - 256 bits for STM32H74x/5X devices (8x 32bits words)
147   *          - 128 bits for STM32H7Ax/BX devices (4x 32bits words)
148   *          - 256 bits for STM32H72x/3X devices (8x 32bits words)
149   * @param  DataAddress specifies the address of data to be programmed.
150   *         This parameter shall be 32-bit aligned
151   *
152   * @retval HAL_StatusTypeDef HAL Status
153   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)154 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
155 {
156   HAL_StatusTypeDef status;
157   __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
158   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
159   uint32_t bank;
160   uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
161 
162   /* Check the parameters */
163   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
164   assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
165 
166   /* Process Locked */
167   __HAL_LOCK(&pFlash);
168 
169 #if defined (FLASH_OPTCR_PG_OTP)
170   if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
171 #else
172   if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
173 #endif /* FLASH_OPTCR_PG_OTP */
174   {
175     bank = FLASH_BANK_1;
176     /* Prevent unused argument(s) compilation warning */
177     UNUSED(TypeProgram);
178   }
179 #if defined (DUAL_BANK)
180   else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
181   {
182     bank = FLASH_BANK_2;
183   }
184 #endif /* DUAL_BANK */
185   else
186   {
187     return HAL_ERROR;
188   }
189 
190   /* Reset error code */
191   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
192 
193   /* Wait for last operation to be completed */
194   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
195 
196   if(status == HAL_OK)
197   {
198 #if defined (DUAL_BANK)
199     if(bank == FLASH_BANK_1)
200     {
201 #if defined (FLASH_OPTCR_PG_OTP)
202       if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
203       {
204         /* Set OTP_PG bit */
205         SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
206       }
207       else
208 #endif /* FLASH_OPTCR_PG_OTP */
209       {
210         /* Set PG bit */
211         SET_BIT(FLASH->CR1, FLASH_CR_PG);
212       }
213     }
214     else
215     {
216       /* Set PG bit */
217       SET_BIT(FLASH->CR2, FLASH_CR_PG);
218     }
219 #else /* Single Bank */
220 #if defined (FLASH_OPTCR_PG_OTP)
221       if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
222       {
223         /* Set OTP_PG bit */
224         SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
225       }
226       else
227 #endif /* FLASH_OPTCR_PG_OTP */
228       {
229         /* Set PG bit */
230         SET_BIT(FLASH->CR1, FLASH_CR_PG);
231       }
232 #endif /* DUAL_BANK */
233 
234     __ISB();
235     __DSB();
236 
237 #if defined (FLASH_OPTCR_PG_OTP)
238     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
239     {
240       /* Program an OTP word (16 bits) */
241       *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
242     }
243     else
244 #endif /* FLASH_OPTCR_PG_OTP */
245     {
246       /* Program the flash word */
247       do
248       {
249         *dest_addr = *src_addr;
250         dest_addr++;
251         src_addr++;
252         row_index--;
253      } while (row_index != 0U);
254     }
255 
256     __ISB();
257     __DSB();
258 
259     /* Wait for last operation to be completed */
260     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
261 
262 #if defined (DUAL_BANK)
263 #if defined (FLASH_OPTCR_PG_OTP)
264     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
265     {
266       /* If the program operation is completed, disable the OTP_PG */
267       CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
268     }
269     else
270 #endif /* FLASH_OPTCR_PG_OTP */
271     {
272       if(bank == FLASH_BANK_1)
273       {
274         /* If the program operation is completed, disable the PG */
275         CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
276       }
277       else
278       {
279         /* If the program operation is completed, disable the PG */
280         CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
281       }
282     }
283 #else /* Single Bank */
284 #if defined (FLASH_OPTCR_PG_OTP)
285     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
286     {
287       /* If the program operation is completed, disable the OTP_PG */
288       CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
289     }
290     else
291 #endif /* FLASH_OPTCR_PG_OTP */
292     {
293       /* If the program operation is completed, disable the PG */
294       CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
295     }
296 #endif /* DUAL_BANK */
297   }
298 
299   /* Process Unlocked */
300   __HAL_UNLOCK(&pFlash);
301 
302   return status;
303 }
304 
305 /**
306   * @brief  Program a flash word at a specified address with interrupt enabled.
307   * @param  TypeProgram Indicate the way to program at a specified address.
308   *                      This parameter can be a value of @ref FLASH_Type_Program
309   * @param  FlashAddress specifies the address to be programmed.
310   *         This parameter shall be aligned to the Flash word:
311   *          - 256 bits for STM32H74x/5X devices (8x 32bits words)
312   *          - 128 bits for STM32H7Ax/BX devices (4x 32bits words)
313   *          - 256 bits for STM32H72x/3X devices (8x 32bits words)
314   * @param  DataAddress specifies the address of data to be programmed.
315   *         This parameter shall be 32-bit aligned
316   *
317   * @retval HAL Status
318   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)319 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
320 {
321   HAL_StatusTypeDef status;
322   __IO uint32_t *dest_addr = (__IO uint32_t*)FlashAddress;
323   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
324   uint32_t bank;
325   uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
326 
327   /* Check the parameters */
328   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
329   assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
330 
331   /* Process Locked */
332   __HAL_LOCK(&pFlash);
333 
334   /* Reset error code */
335   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
336 
337 #if defined (FLASH_OPTCR_PG_OTP)
338   if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
339 #else
340   if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
341 #endif /* FLASH_OPTCR_PG_OTP */
342   {
343     bank = FLASH_BANK_1;
344     /* Prevent unused argument(s) compilation warning */
345     UNUSED(TypeProgram);
346   }
347 #if defined (DUAL_BANK)
348   else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
349   {
350     bank = FLASH_BANK_2;
351   }
352 #endif /* DUAL_BANK */
353   else
354   {
355     return HAL_ERROR;
356   }
357 
358   /* Wait for last operation to be completed */
359   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
360 
361   if (status != HAL_OK)
362   {
363     /* Process Unlocked */
364     __HAL_UNLOCK(&pFlash);
365   }
366   else
367   {
368     pFlash.Address = FlashAddress;
369 
370 #if defined (DUAL_BANK)
371     if(bank == FLASH_BANK_1)
372     {
373       /* Set internal variables used by the IRQ handler */
374       pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
375 
376 #if defined (FLASH_OPTCR_PG_OTP)
377       if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
378       {
379         /* Set OTP_PG bit */
380         SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
381       }
382       else
383 #endif /* FLASH_OPTCR_PG_OTP */
384       {
385         /* Set PG bit */
386         SET_BIT(FLASH->CR1, FLASH_CR_PG);
387       }
388 
389       /* Enable End of Operation and Error interrupts for Bank 1 */
390 #if defined (FLASH_CR_OPERRIE)
391       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
392                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
393 #else
394       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
395                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
396 #endif /* FLASH_CR_OPERRIE */
397     }
398     else
399     {
400       /* Set internal variables used by the IRQ handler */
401       pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK2;
402 
403       /* Set PG bit */
404       SET_BIT(FLASH->CR2, FLASH_CR_PG);
405 
406       /* Enable End of Operation and Error interrupts for Bank2 */
407 #if defined (FLASH_CR_OPERRIE)
408       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
409                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
410 #else
411       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
412                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
413 #endif /* FLASH_CR_OPERRIE */
414     }
415 #else /* Single Bank */
416     /* Set internal variables used by the IRQ handler */
417     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
418 
419 #if defined (FLASH_OPTCR_PG_OTP)
420     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
421     {
422       /* Set OTP_PG bit */
423       SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
424     }
425     else
426 #endif /* FLASH_OPTCR_PG_OTP */
427     {
428       /* Set PG bit */
429       SET_BIT(FLASH->CR1, FLASH_CR_PG);
430     }
431 
432       /* Enable End of Operation and Error interrupts for Bank 1 */
433 #if defined (FLASH_CR_OPERRIE)
434       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
435                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
436 #else
437       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
438                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
439 #endif /* FLASH_CR_OPERRIE */
440 #endif /* DUAL_BANK */
441 
442     __ISB();
443     __DSB();
444 
445 #if defined (FLASH_OPTCR_PG_OTP)
446     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
447     {
448       /* Program an OTP word (16 bits) */
449       *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
450     }
451     else
452 #endif /* FLASH_OPTCR_PG_OTP */
453     {
454       /* Program the flash word */
455       do
456       {
457         *dest_addr = *src_addr;
458         dest_addr++;
459         src_addr++;
460         row_index--;
461       } while (row_index != 0U);
462     }
463 
464     __ISB();
465     __DSB();
466   }
467 
468   return status;
469 }
470 
471 /**
472   * @brief This function handles FLASH interrupt request.
473   * @retval None
474   */
HAL_FLASH_IRQHandler(void)475 void HAL_FLASH_IRQHandler(void)
476 {
477   uint32_t temp;
478   uint32_t errorflag;
479   FLASH_ProcedureTypeDef procedure;
480 
481   /* Check FLASH Bank1 End of Operation flag  */
482   if(__HAL_FLASH_GET_FLAG_BANK1(FLASH_SR_EOP) != RESET)
483   {
484     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK1)
485     {
486       /* Nb of sector to erased can be decreased */
487       pFlash.NbSectorsToErase--;
488 
489       /* Check if there are still sectors to erase */
490       if(pFlash.NbSectorsToErase != 0U)
491       {
492         /* Indicate user which sector has been erased */
493         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
494 
495         /* Clear bank 1 End of Operation pending bit */
496         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
497 
498         /* Increment sector number */
499         pFlash.Sector++;
500         temp = pFlash.Sector;
501         FLASH_Erase_Sector(temp, FLASH_BANK_1, pFlash.VoltageForErase);
502       }
503       else
504       {
505         /* No more sectors to Erase, user callback can be called */
506         /* Reset Sector and stop Erase sectors procedure */
507         pFlash.Sector = 0xFFFFFFFFU;
508         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
509 
510         /* FLASH EOP interrupt user callback */
511         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
512 
513         /* Clear FLASH End of Operation pending bit */
514         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
515       }
516     }
517     else
518     {
519       procedure = pFlash.ProcedureOnGoing;
520 
521       if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
522       {
523         /* MassErase ended. Return the selected bank */
524         /* FLASH EOP interrupt user callback */
525         HAL_FLASH_EndOfOperationCallback(FLASH_BANK_1);
526       }
527       else if(procedure == FLASH_PROC_PROGRAM_BANK1)
528       {
529         /* Program ended. Return the selected address */
530         /* FLASH EOP interrupt user callback */
531         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
532       }
533       else
534       {
535         /* Nothing to do */
536       }
537 
538       if((procedure != FLASH_PROC_SECTERASE_BANK2) && \
539          (procedure != FLASH_PROC_MASSERASE_BANK2) && \
540          (procedure != FLASH_PROC_PROGRAM_BANK2))
541       {
542         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
543         /* Clear FLASH End of Operation pending bit */
544         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
545       }
546     }
547   }
548 
549 #if defined (DUAL_BANK)
550  /* Check FLASH Bank2 End of Operation flag  */
551   if(__HAL_FLASH_GET_FLAG_BANK2(FLASH_SR_EOP) != RESET)
552   {
553     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK2)
554     {
555       /*Nb of sector to erased can be decreased*/
556       pFlash.NbSectorsToErase--;
557 
558       /* Check if there are still sectors to erase*/
559       if(pFlash.NbSectorsToErase != 0U)
560       {
561         /*Indicate user which sector has been erased*/
562         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
563 
564         /* Clear bank 2 End of Operation pending bit */
565         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
566 
567         /*Increment sector number*/
568         pFlash.Sector++;
569         temp = pFlash.Sector;
570         FLASH_Erase_Sector(temp, FLASH_BANK_2, pFlash.VoltageForErase);
571       }
572       else
573       {
574         /* No more sectors to Erase, user callback can be called */
575         /* Reset Sector and stop Erase sectors procedure */
576         pFlash.Sector = 0xFFFFFFFFU;
577         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
578 
579         /* FLASH EOP interrupt user callback */
580         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
581 
582         /* Clear FLASH End of Operation pending bit */
583         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
584       }
585     }
586     else
587     {
588       procedure = pFlash.ProcedureOnGoing;
589 
590       if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
591       {
592         /*MassErase ended. Return the selected bank*/
593         /* FLASH EOP interrupt user callback */
594         HAL_FLASH_EndOfOperationCallback(FLASH_BANK_2);
595       }
596       else if(procedure == FLASH_PROC_PROGRAM_BANK2)
597       {
598         /* Program ended. Return the selected address */
599         /* FLASH EOP interrupt user callback */
600         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
601       }
602       else
603       {
604         /* Nothing to do */
605       }
606 
607       if((procedure != FLASH_PROC_SECTERASE_BANK1) && \
608          (procedure != FLASH_PROC_MASSERASE_BANK1) && \
609          (procedure != FLASH_PROC_PROGRAM_BANK1))
610       {
611         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
612         /* Clear FLASH End of Operation pending bit */
613         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
614       }
615     }
616   }
617 #endif /* DUAL_BANK */
618 
619   /* Check FLASH Bank1 operation error flags */
620 #if defined (FLASH_SR_OPERR)
621   errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
622                             FLASH_FLAG_INCERR_BANK1 | FLASH_FLAG_OPERR_BANK1);
623 #else
624   errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
625                             FLASH_FLAG_INCERR_BANK1);
626 #endif /* FLASH_SR_OPERR */
627 
628   if(errorflag != 0U)
629   {
630     /* Save the error code */
631     pFlash.ErrorCode |= errorflag;
632 
633     /* Clear error programming flags */
634     __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
635 
636     procedure = pFlash.ProcedureOnGoing;
637 
638     if(procedure == FLASH_PROC_SECTERASE_BANK1)
639     {
640       /* Return the faulty sector */
641       temp = pFlash.Sector;
642       pFlash.Sector = 0xFFFFFFFFU;
643     }
644     else if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
645     {
646       /* Return the faulty bank */
647       temp = FLASH_BANK_1;
648     }
649     else
650     {
651       /* Return the faulty address */
652       temp = pFlash.Address;
653     }
654 
655     /* Stop the procedure ongoing*/
656     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
657 
658     /* FLASH error interrupt user callback */
659     HAL_FLASH_OperationErrorCallback(temp);
660   }
661 
662 #if (USE_FLASH_ECC == 1U)
663   /* Check FLASH Bank1 ECC single correction error flag */
664   errorflag = FLASH->SR1 & FLASH_FLAG_SNECCERR_BANK1;
665 
666   if(errorflag != 0U)
667   {
668     /* Save the error code */
669     pFlash.ErrorCode |= errorflag;
670 
671     /* Call User callback */
672     HAL_FLASHEx_EccCorrectionCallback();
673 
674     /* Clear FLASH Bank1 ECC single correction error flag in order to allow new ECC error record */
675     __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
676   }
677 
678   /* Check FLASH Bank1 ECC double detection error flag */
679   errorflag = FLASH->SR1 & FLASH_FLAG_DBECCERR_BANK1;
680 
681   if(errorflag != 0U)
682   {
683     /* Save the error code */
684     pFlash.ErrorCode |= errorflag;
685 
686     /* Call User callback */
687     HAL_FLASHEx_EccDetectionCallback();
688 
689     /* Clear FLASH Bank1 ECC double detection error flag in order to allow new ECC error record */
690     __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
691   }
692 #endif /* USE_FLASH_ECC */
693 
694 #if defined (DUAL_BANK)
695   /* Check FLASH Bank2 operation error flags */
696 #if defined (FLASH_SR_OPERR)
697   errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
698                              FLASH_FLAG_INCERR_BANK2 | FLASH_FLAG_OPERR_BANK2) & 0x7FFFFFFFU);
699 #else
700   errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
701                              FLASH_FLAG_INCERR_BANK2) & 0x7FFFFFFFU);
702 #endif /* FLASH_SR_OPERR */
703 
704   if(errorflag != 0U)
705   {
706     /* Save the error code */
707     pFlash.ErrorCode |= (errorflag | 0x80000000U);
708 
709     /* Clear error programming flags */
710     __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
711 
712     procedure = pFlash.ProcedureOnGoing;
713 
714     if(procedure== FLASH_PROC_SECTERASE_BANK2)
715     {
716       /*return the faulty sector*/
717       temp = pFlash.Sector;
718       pFlash.Sector = 0xFFFFFFFFU;
719     }
720     else if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
721     {
722       /*return the faulty bank*/
723       temp = FLASH_BANK_2;
724     }
725     else
726     {
727       /*return the faulty address*/
728       temp = pFlash.Address;
729     }
730 
731     /*Stop the procedure ongoing*/
732     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
733 
734     /* FLASH error interrupt user callback */
735     HAL_FLASH_OperationErrorCallback(temp);
736   }
737 
738 #if (USE_FLASH_ECC == 1U)
739   /* Check FLASH Bank2 ECC single correction error flag */
740   errorflag = FLASH->SR2 & FLASH_FLAG_SNECCERR_BANK2;
741 
742   if(errorflag != 0U)
743   {
744     /* Save the error code */
745     pFlash.ErrorCode |= (errorflag | 0x80000000U);
746 
747     /* Call User callback */
748     HAL_FLASHEx_EccCorrectionCallback();
749 
750     /* Clear FLASH Bank2 ECC single correction error flag in order to allow new ECC error record */
751     __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
752   }
753 
754   /* Check FLASH Bank2 ECC double detection error flag */
755   errorflag = FLASH->SR2 & FLASH_FLAG_DBECCERR_BANK2;
756 
757   if(errorflag != 0U)
758   {
759     /* Save the error code */
760     pFlash.ErrorCode |= (errorflag | 0x80000000U);
761 
762     /* Call User callback */
763     HAL_FLASHEx_EccDetectionCallback();
764 
765     /* Clear FLASH Bank2 ECC double detection error flag in order to allow new ECC error record */
766     __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
767   }
768 
769 #endif /* USE_FLASH_ECC */
770 #endif /* DUAL_BANK */
771 
772   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
773   {
774 #if defined (FLASH_CR_OPERRIE)
775     /* Disable Bank1 Operation and Error source interrupt */
776     __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1    | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
777                                  FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
778 
779 #if defined (DUAL_BANK)
780     /* Disable Bank2 Operation and Error source interrupt */
781     __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2    | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
782                                  FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
783 #endif /* DUAL_BANK */
784 #else
785     /* Disable Bank1 Operation and Error source interrupt */
786     __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1    | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
787                                  FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
788 
789 #if defined (DUAL_BANK)
790     /* Disable Bank2 Operation and Error source interrupt */
791     __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2    | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
792                                  FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
793 #endif /* DUAL_BANK */
794 #endif /* FLASH_CR_OPERRIE */
795 
796     /* Process Unlocked */
797     __HAL_UNLOCK(&pFlash);
798   }
799 }
800 
801 /**
802   * @brief  FLASH end of operation interrupt callback
803   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
804   *                  Mass Erase: Bank number which has been requested to erase
805   *                  Sectors Erase: Sector which has been erased
806   *                    (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
807   *                  Program: Address which was selected for data program
808   * @retval None
809   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)810 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
811 {
812   /* Prevent unused argument(s) compilation warning */
813   UNUSED(ReturnValue);
814 
815   /* NOTE : This function Should not be modified, when the callback is needed,
816             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
817    */
818 }
819 
820 /**
821   * @brief  FLASH operation error interrupt callback
822   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
823   *                 Mass Erase: Bank number which has been requested to erase
824   *                 Sectors Erase: Sector number which returned an error
825   *                 Program: Address which was selected for data program
826   * @retval None
827   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)828 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
829 {
830   /* Prevent unused argument(s) compilation warning */
831   UNUSED(ReturnValue);
832 
833   /* NOTE : This function Should not be modified, when the callback is needed,
834             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
835    */
836 }
837 
838 /**
839   * @}
840   */
841 
842 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
843   *  @brief   Management functions
844   *
845 @verbatim
846  ===============================================================================
847                       ##### Peripheral Control functions #####
848  ===============================================================================
849     [..]
850     This subsection provides a set of functions allowing to control the FLASH
851     memory operations.
852 
853 @endverbatim
854   * @{
855   */
856 
857 /**
858   * @brief  Unlock the FLASH control registers access
859   * @retval HAL Status
860   */
HAL_FLASH_Unlock(void)861 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
862 {
863   if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
864   {
865     /* Authorize the FLASH Bank1 Registers access */
866     WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
867     WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
868 
869     /* Verify Flash Bank1 is unlocked */
870     if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
871     {
872       return HAL_ERROR;
873     }
874   }
875 
876 #if defined (DUAL_BANK)
877   if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
878   {
879     /* Authorize the FLASH Bank2 Registers access */
880     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
881     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
882 
883     /* Verify Flash Bank2 is unlocked */
884     if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
885     {
886       return HAL_ERROR;
887     }
888   }
889 #endif /* DUAL_BANK */
890 
891   return HAL_OK;
892 }
893 
894 /**
895   * @brief  Locks the FLASH control registers access
896   * @retval HAL Status
897   */
HAL_FLASH_Lock(void)898 HAL_StatusTypeDef HAL_FLASH_Lock(void)
899 {
900   /* Set the LOCK Bit to lock the FLASH Bank1 Control Register access */
901   SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
902 
903   /* Verify Flash Bank1 is locked */
904   if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) == 0U)
905   {
906     return HAL_ERROR;
907   }
908 
909 #if defined (DUAL_BANK)
910   /* Set the LOCK Bit to lock the FLASH Bank2 Control Register access */
911   SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
912 
913   /* Verify Flash Bank2 is locked */
914   if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) == 0U)
915   {
916     return HAL_ERROR;
917   }
918 #endif /* DUAL_BANK */
919 
920   return HAL_OK;
921 }
922 
923 /**
924   * @brief  Unlock the FLASH Option Control Registers access.
925   * @retval HAL Status
926   */
HAL_FLASH_OB_Unlock(void)927 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
928 {
929   if(READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
930   {
931     /* Authorizes the Option Byte registers programming */
932     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
933     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
934 
935     /* Verify that the Option Bytes are unlocked */
936     if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
937     {
938       return HAL_ERROR;
939     }
940   }
941 
942   return HAL_OK;
943 }
944 
945 /**
946   * @brief  Lock the FLASH Option Control Registers access.
947   * @retval HAL Status
948   */
HAL_FLASH_OB_Lock(void)949 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
950 {
951   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
952   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
953 
954   /* Verify that the Option Bytes are locked */
955   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) == 0U)
956   {
957     return HAL_ERROR;
958   }
959 
960   return HAL_OK;
961 }
962 
963 /**
964   * @brief  Launch the option bytes loading.
965   * @retval HAL Status
966   */
HAL_FLASH_OB_Launch(void)967 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
968 {
969   HAL_StatusTypeDef status;
970 
971   /* Wait for CRC computation to be completed */
972   if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
973   {
974     status = HAL_ERROR;
975   }
976 #if defined (DUAL_BANK)
977   else if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
978   {
979     status = HAL_ERROR;
980   }
981 #endif /* DUAL_BANK */
982   else
983   {
984     status = HAL_OK;
985   }
986 
987   if (status == HAL_OK)
988   {
989     /* Set OPTSTRT Bit */
990     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
991 
992     /* Wait for OB change operation to be completed */
993     status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
994   }
995 
996   return status;
997 }
998 
999 /**
1000   * @}
1001   */
1002 
1003 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
1004   *  @brief   Peripheral Errors functions
1005   *
1006 @verbatim
1007  ===============================================================================
1008                 ##### Peripheral Errors functions #####
1009  ===============================================================================
1010     [..]
1011     This subsection permits to get in run-time Errors of the FLASH peripheral.
1012 
1013 @endverbatim
1014   * @{
1015   */
1016 
1017 /**
1018   * @brief  Get the specific FLASH error flag.
1019   * @retval HAL_FLASH_ERRORCode The returned value can be:
1020   *            @arg HAL_FLASH_ERROR_NONE       : No error set
1021   *
1022   *            @arg HAL_FLASH_ERROR_WRP_BANK1  : Write Protection Error on Bank 1
1023   *            @arg HAL_FLASH_ERROR_PGS_BANK1  : Program Sequence Error on Bank 1
1024   *            @arg HAL_FLASH_ERROR_STRB_BANK1 : Strobe Error on Bank 1
1025   *            @arg HAL_FLASH_ERROR_INC_BANK1  : Inconsistency Error on Bank 1
1026   *            @arg HAL_FLASH_ERROR_OPE_BANK1  : Operation Error on Bank 1
1027   *            @arg HAL_FLASH_ERROR_RDP_BANK1  : Read Protection Error on Bank 1
1028   *            @arg HAL_FLASH_ERROR_RDS_BANK1  : Read Secured Error on Bank 1
1029   *            @arg HAL_FLASH_ERROR_SNECC_BANK1: ECC Single Correction Error on Bank 1
1030   *            @arg HAL_FLASH_ERROR_DBECC_BANK1: ECC Double Detection Error on Bank 1
1031   *            @arg HAL_FLASH_ERROR_CRCRD_BANK1: CRC Read Error on Bank 1
1032   *
1033   *            @arg HAL_FLASH_ERROR_WRP_BANK2  : Write Protection Error on Bank 2
1034   *            @arg HAL_FLASH_ERROR_PGS_BANK2  : Program Sequence Error on Bank 2
1035   *            @arg HAL_FLASH_ERROR_STRB_BANK2 : Strobe Error on Bank 2
1036   *            @arg HAL_FLASH_ERROR_INC_BANK2  : Inconsistency Error on Bank 2
1037   *            @arg HAL_FLASH_ERROR_OPE_BANK2  : Operation Error on Bank 2
1038   *            @arg HAL_FLASH_ERROR_RDP_BANK2  : Read Protection Error on Bank 2
1039   *            @arg HAL_FLASH_ERROR_RDS_BANK2  : Read Secured Error on Bank 2
1040   *            @arg HAL_FLASH_ERROR_SNECC_BANK2: SNECC Error on Bank 2
1041   *            @arg HAL_FLASH_ERROR_DBECC_BANK2: Double Detection ECC on Bank 2
1042   *            @arg HAL_FLASH_ERROR_CRCRD_BANK2: CRC Read Error on Bank 2
1043   */
1044 
HAL_FLASH_GetError(void)1045 uint32_t HAL_FLASH_GetError(void)
1046 {
1047    return pFlash.ErrorCode;
1048 }
1049 
1050 /**
1051   * @}
1052   */
1053 
1054 /**
1055   * @}
1056   */
1057 
1058 /* Private functions ---------------------------------------------------------*/
1059 
1060 /** @addtogroup FLASH_Private_Functions
1061   * @{
1062   */
1063 
1064 /**
1065   * @brief  Wait for a FLASH operation to complete.
1066   * @param  Timeout maximum flash operation timeout
1067   * @param  Bank flash FLASH_BANK_1 or FLASH_BANK_2
1068   * @retval HAL_StatusTypeDef HAL Status
1069   */
FLASH_WaitForLastOperation(uint32_t Timeout,uint32_t Bank)1070 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
1071 {
1072   /* Wait for the FLASH operation to complete by polling on QW flag to be reset.
1073      Even if the FLASH operation fails, the QW flag will be reset and an error
1074      flag will be set */
1075 
1076   uint32_t bsyflag = FLASH_FLAG_QW_BANK1;
1077   uint32_t errorflag = 0;
1078   uint32_t tickstart = HAL_GetTick();
1079 
1080   assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
1081 
1082 #if defined (DUAL_BANK)
1083 
1084   if (Bank == FLASH_BANK_2)
1085   {
1086     /* Select bsyflag depending on Bank */
1087     bsyflag = FLASH_FLAG_QW_BANK2;
1088   }
1089 #endif /* DUAL_BANK */
1090 
1091   while(__HAL_FLASH_GET_FLAG(bsyflag))
1092   {
1093     if(Timeout != HAL_MAX_DELAY)
1094     {
1095       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1096       {
1097         return HAL_TIMEOUT;
1098       }
1099     }
1100   }
1101 
1102   /* Get Error Flags */
1103   if (Bank == FLASH_BANK_1)
1104   {
1105     errorflag = FLASH->SR1 & FLASH_FLAG_ALL_ERRORS_BANK1;
1106   }
1107 #if defined (DUAL_BANK)
1108   else
1109   {
1110     errorflag = (FLASH->SR2 & FLASH_FLAG_ALL_ERRORS_BANK2) | 0x80000000U;
1111   }
1112 #endif /* DUAL_BANK */
1113 
1114   /* In case of error reported in Flash SR1 or SR2 register */
1115   if((errorflag & 0x7FFFFFFFU) != 0U)
1116   {
1117     /*Save the error code*/
1118     pFlash.ErrorCode |= errorflag;
1119 
1120     /* Clear error programming flags */
1121     __HAL_FLASH_CLEAR_FLAG(errorflag);
1122 
1123     return HAL_ERROR;
1124   }
1125 
1126   /* Check FLASH End of Operation flag  */
1127   if(Bank == FLASH_BANK_1)
1128   {
1129     if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
1130     {
1131       /* Clear FLASH End of Operation pending bit */
1132       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
1133     }
1134   }
1135 #if defined (DUAL_BANK)
1136   else
1137   {
1138     if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
1139     {
1140       /* Clear FLASH End of Operation pending bit */
1141       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
1142     }
1143   }
1144 #endif /* DUAL_BANK */
1145 
1146   return HAL_OK;
1147 }
1148 
1149 /**
1150   * @brief  Wait for a FLASH Option Bytes change operation to complete.
1151   * @param  Timeout maximum flash operation timeout
1152   * @retval HAL_StatusTypeDef HAL Status
1153   */
FLASH_OB_WaitForLastOperation(uint32_t Timeout)1154 HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout)
1155 {
1156   /* Get timeout */
1157   uint32_t tickstart = HAL_GetTick();
1158 
1159   /* Wait for the FLASH Option Bytes change operation to complete by polling on OPT_BUSY flag to be reset */
1160   while(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPT_BUSY) != 0U)
1161   {
1162     if(Timeout != HAL_MAX_DELAY)
1163     {
1164       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1165       {
1166         return HAL_TIMEOUT;
1167       }
1168     }
1169   }
1170 
1171   /* Check option byte change error */
1172   if(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPTCHANGEERR) != 0U)
1173   {
1174     /* Save the error code */
1175     pFlash.ErrorCode |= HAL_FLASH_ERROR_OB_CHANGE;
1176 
1177     /* Clear the OB error flag */
1178     FLASH->OPTCCR |= FLASH_OPTCCR_CLR_OPTCHANGEERR;
1179 
1180     return HAL_ERROR;
1181   }
1182 
1183   /* If there is no error flag set */
1184   return HAL_OK;
1185 }
1186 
1187 /**
1188   * @brief  Wait for a FLASH CRC computation to complete.
1189   * @param  Timeout maximum flash operation timeout
1190   * @param  Bank flash FLASH_BANK_1 or FLASH_BANK_2
1191   * @retval HAL_StatusTypeDef HAL Status
1192   */
FLASH_CRC_WaitForLastOperation(uint32_t Timeout,uint32_t Bank)1193 HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
1194 {
1195   uint32_t bsyflag;
1196   uint32_t tickstart = HAL_GetTick();
1197 
1198   assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
1199 
1200   /* Select bsyflag depending on Bank */
1201   if(Bank == FLASH_BANK_1)
1202   {
1203     bsyflag = FLASH_FLAG_CRC_BUSY_BANK1;
1204   }
1205   else
1206   {
1207     bsyflag = FLASH_FLAG_CRC_BUSY_BANK2;
1208   }
1209 
1210   /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
1211   while(__HAL_FLASH_GET_FLAG(bsyflag))
1212   {
1213     if(Timeout != HAL_MAX_DELAY)
1214     {
1215       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1216       {
1217         return HAL_TIMEOUT;
1218       }
1219     }
1220   }
1221 
1222   /* Check FLASH CRC read error flag  */
1223   if(Bank == FLASH_BANK_1)
1224   {
1225     if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1))
1226     {
1227       /* Save the error code */
1228       pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK1;
1229 
1230       /* Clear FLASH CRC read error pending bit */
1231       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1);
1232 
1233       return HAL_ERROR;
1234     }
1235   }
1236 #if defined (DUAL_BANK)
1237   else
1238   {
1239     if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2))
1240     {
1241       /* Save the error code */
1242       pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK2;
1243 
1244       /* Clear FLASH CRC read error pending bit */
1245       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2);
1246 
1247       return HAL_ERROR;
1248     }
1249   }
1250 #endif /* DUAL_BANK */
1251 
1252   /* If there is no error flag set */
1253   return HAL_OK;
1254 }
1255 
1256 /**
1257   * @}
1258   */
1259 
1260 #endif /* HAL_FLASH_MODULE_ENABLED */
1261 
1262 /**
1263   * @}
1264   */
1265 
1266 /**
1267   * @}
1268   */
1269 
1270