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