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   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
78   * All rights reserved.</center></h2>
79   *
80   * This software component is licensed by ST under BSD 3-Clause license,
81   * the "License"; You may not use this file except in compliance with the
82   * License. You may obtain a copy of the License at:
83   *                       opensource.org/licenses/BSD-3-Clause
84   *
85   ******************************************************************************
86   */
87 
88 /* Includes ------------------------------------------------------------------*/
89 #include "stm32h7xx_hal.h"
90 
91 /** @addtogroup STM32H7xx_HAL_Driver
92   * @{
93   */
94 
95 /** @defgroup FLASH FLASH
96   * @brief FLASH HAL module driver
97   * @{
98   */
99 
100 #ifdef HAL_FLASH_MODULE_ENABLED
101 
102 /* Private typedef -----------------------------------------------------------*/
103 /* Private define ------------------------------------------------------------*/
104 /** @addtogroup FLASH_Private_Constants
105   * @{
106   */
107 #define FLASH_TIMEOUT_VALUE              50000U /* 50 s */
108 /**
109   * @}
110   */
111 /* Private macro -------------------------------------------------------------*/
112 /* Private variables ---------------------------------------------------------*/
113 FLASH_ProcessTypeDef pFlash;
114 /* Private function prototypes -----------------------------------------------*/
115 /* Exported functions ---------------------------------------------------------*/
116 
117 /** @defgroup FLASH_Exported_Functions FLASH Exported functions
118   * @{
119   */
120 
121 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
122  *  @brief   Programming operation functions
123  *
124 @verbatim
125  ===============================================================================
126                   ##### Programming operation functions #####
127  ===============================================================================
128     [..]
129     This subsection provides a set of functions allowing to manage the FLASH
130     program operations.
131 
132 @endverbatim
133   * @{
134   */
135 
136 /**
137   * @brief  Program flash word of 256 bits at a specified address
138   * @param  TypeProgram Indicate the way to program at a specified address.
139   *         This parameter can be a value of @ref FLASH_Type_Program
140   * @param  FlashAddress specifies the address to be programmed.
141   * @param  DataAddress specifies the address of data (256 bits) to be programmed
142   *
143   * @retval HAL_StatusTypeDef HAL Status
144   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)145 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
146 {
147   HAL_StatusTypeDef status;
148   __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
149   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
150   uint32_t bank;
151   uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
152 
153   /* Check the parameters */
154   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
155   assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
156 
157   /* Process Locked */
158   __HAL_LOCK(&pFlash);
159 
160   if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
161   {
162     bank = FLASH_BANK_1;
163   }
164   else
165   {
166     bank = FLASH_BANK_2;
167   }
168 
169   /* Reset error code */
170   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
171 
172   /* Wait for last operation to be completed */
173   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
174 
175   if(status == HAL_OK)
176   {
177     if(bank == FLASH_BANK_1)
178     {
179       /* Set PG bit */
180       SET_BIT(FLASH->CR1, FLASH_CR_PG);
181     }
182     else
183     {
184       /* Set PG bit */
185       SET_BIT(FLASH->CR2, FLASH_CR_PG);
186     }
187 
188     __ISB();
189     __DSB();
190 
191     /* Program the 256 bits flash word */
192     do
193     {
194       *dest_addr = *src_addr;
195       dest_addr++;
196       src_addr++;
197       row_index--;
198     } while (row_index != 0U);
199 
200     __ISB();
201     __DSB();
202 
203     /* Wait for last operation to be completed */
204     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
205 
206     if(bank == FLASH_BANK_1)
207     {
208       /* If the program operation is completed, disable the PG */
209       CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
210     }
211     else
212     {
213       /* If the program operation is completed, disable the PG */
214       CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
215     }
216   }
217 
218   /* Process Unlocked */
219   __HAL_UNLOCK(&pFlash);
220 
221   return status;
222 }
223 
224 /**
225   * @brief  Program flash words of 256 bits at a specified address with interrupt enabled.
226   * @param  TypeProgram Indicate the way to program at a specified address.
227   *                      This parameter can be a value of @ref FLASH_Type_Program
228   * @param  FlashAddress specifies the address to be programmed.
229   * @param  DataAddress specifies the address of data (256 bits) to be programmed
230   *
231   * @retval HAL Status
232   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)233 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
234 {
235   HAL_StatusTypeDef status;
236   __IO uint32_t *dest_addr = (__IO uint32_t*)FlashAddress;
237   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
238   uint32_t bank;
239   uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
240 
241   /* Check the parameters */
242   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
243   assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
244 
245   /* Process Locked */
246   __HAL_LOCK(&pFlash);
247 
248   /* Reset error code */
249   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
250 
251   if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
252   {
253     bank = FLASH_BANK_1;
254   }
255   else
256   {
257     bank = FLASH_BANK_2;
258   }
259 
260   /* Wait for last operation to be completed */
261   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
262 
263   if (status != HAL_OK)
264   {
265     /* Process Unlocked */
266     __HAL_UNLOCK(&pFlash);
267   }
268   else
269   {
270     pFlash.Address = FlashAddress;
271 
272     if(bank == FLASH_BANK_1)
273     {
274       /* Set internal variables used by the IRQ handler */
275       pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
276 
277       /* Set PG bit */
278       SET_BIT(FLASH->CR1, FLASH_CR_PG);
279 
280       /* Enable End of Operation and Error interrupts for Bank 1 */
281       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
282                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
283     }
284     else
285     {
286       /* Set internal variables used by the IRQ handler */
287       pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK2;
288 
289       /* Set PG bit */
290       SET_BIT(FLASH->CR2, FLASH_CR_PG);
291 
292       /* Enable End of Operation and Error interrupts for Bank2 */
293       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
294                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
295     }
296 
297     __ISB();
298     __DSB();
299 
300     /* Program the 256 bits flash word */
301     do
302     {
303       *dest_addr = *src_addr;
304       dest_addr++;
305       src_addr++;
306       row_index--;
307     } while (row_index != 0U);
308 
309     __ISB();
310     __DSB();
311   }
312 
313   return status;
314 }
315 
316 /**
317   * @brief This function handles FLASH interrupt request.
318   * @retval None
319   */
HAL_FLASH_IRQHandler(void)320 void HAL_FLASH_IRQHandler(void)
321 {
322   uint32_t temp;
323   uint32_t errorflag;
324   FLASH_ProcedureTypeDef procedure;
325 
326   /* Check FLASH Bank1 End of Operation flag  */
327   if(__HAL_FLASH_GET_FLAG_BANK1(FLASH_SR_EOP) != RESET)
328   {
329     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK1)
330     {
331       /* Nb of sector to erased can be decreased */
332       pFlash.NbSectorsToErase--;
333 
334       /* Check if there are still sectors to erase */
335       if(pFlash.NbSectorsToErase != 0U)
336       {
337         /* Indicate user which sector has been erased */
338         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
339 
340         /* Clear bank 1 End of Operation pending bit */
341         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
342 
343         /* Increment sector number */
344         pFlash.Sector++;
345         temp = pFlash.Sector;
346         FLASH_Erase_Sector(temp, FLASH_BANK_1, pFlash.VoltageForErase);
347       }
348       else
349       {
350         /* No more sectors to Erase, user callback can be called */
351         /* Reset Sector and stop Erase sectors procedure */
352         pFlash.Sector = 0xFFFFFFFFU;
353         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
354 
355         /* FLASH EOP interrupt user callback */
356         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
357 
358         /* Clear FLASH End of Operation pending bit */
359         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
360       }
361     }
362     else
363     {
364       procedure = pFlash.ProcedureOnGoing;
365 
366       if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
367       {
368         /* MassErase ended. Return the selected bank */
369         /* FLASH EOP interrupt user callback */
370         HAL_FLASH_EndOfOperationCallback(FLASH_BANK_1);
371       }
372       else if(procedure == FLASH_PROC_PROGRAM_BANK1)
373       {
374         /* Program ended. Return the selected address */
375         /* FLASH EOP interrupt user callback */
376         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
377       }
378       else
379       {
380         /* Nothing to do */
381       }
382 
383       if((procedure != FLASH_PROC_SECTERASE_BANK2) && \
384          (procedure != FLASH_PROC_MASSERASE_BANK2) && \
385          (procedure != FLASH_PROC_PROGRAM_BANK2))
386       {
387         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
388         /* Clear FLASH End of Operation pending bit */
389         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
390       }
391     }
392   }
393 
394  /* Check FLASH Bank2 End of Operation flag  */
395   if(__HAL_FLASH_GET_FLAG_BANK2(FLASH_SR_EOP) != RESET)
396   {
397     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK2)
398     {
399       /*Nb of sector to erased can be decreased*/
400       pFlash.NbSectorsToErase--;
401 
402       /* Check if there are still sectors to erase*/
403       if(pFlash.NbSectorsToErase != 0U)
404       {
405         /*Indicate user which sector has been erased*/
406         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
407 
408         /* Clear bank 2 End of Operation pending bit */
409         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
410 
411         /*Increment sector number*/
412         pFlash.Sector++;
413         temp = pFlash.Sector;
414         FLASH_Erase_Sector(temp, FLASH_BANK_2, pFlash.VoltageForErase);
415       }
416       else
417       {
418         /* No more sectors to Erase, user callback can be called */
419         /* Reset Sector and stop Erase sectors procedure */
420         pFlash.Sector = 0xFFFFFFFFU;
421         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
422 
423         /* FLASH EOP interrupt user callback */
424         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
425 
426         /* Clear FLASH End of Operation pending bit */
427         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
428       }
429     }
430     else
431     {
432       procedure = pFlash.ProcedureOnGoing;
433 
434       if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
435       {
436         /*MassErase ended. Return the selected bank*/
437         /* FLASH EOP interrupt user callback */
438         HAL_FLASH_EndOfOperationCallback(FLASH_BANK_2);
439       }
440       else if(procedure == FLASH_PROC_PROGRAM_BANK2)
441       {
442         /* Program ended. Return the selected address */
443         /* FLASH EOP interrupt user callback */
444         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
445       }
446       else
447       {
448         /* Nothing to do */
449       }
450 
451       if((procedure != FLASH_PROC_SECTERASE_BANK1) && \
452          (procedure != FLASH_PROC_MASSERASE_BANK1) && \
453          (procedure != FLASH_PROC_PROGRAM_BANK1))
454       {
455         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
456         /* Clear FLASH End of Operation pending bit */
457         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
458       }
459     }
460   }
461 
462   /* Check FLASH Bank1 operation error flags */
463   errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
464                             FLASH_FLAG_INCERR_BANK1 | FLASH_FLAG_OPERR_BANK1);
465 
466   if(errorflag != 0U)
467   {
468     /* Save the error code */
469     pFlash.ErrorCode |= errorflag;
470 
471     /* Clear error programming flags */
472     __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
473 
474     procedure = pFlash.ProcedureOnGoing;
475 
476     if(procedure == FLASH_PROC_SECTERASE_BANK1)
477     {
478       /* Return the faulty sector */
479       temp = pFlash.Sector;
480       pFlash.Sector = 0xFFFFFFFFU;
481     }
482     else if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
483     {
484       /* Return the faulty bank */
485       temp = FLASH_BANK_1;
486     }
487     else
488     {
489       /* Return the faulty address */
490       temp = pFlash.Address;
491     }
492 
493     /* Stop the procedure ongoing*/
494     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
495 
496     /* FLASH error interrupt user callback */
497     HAL_FLASH_OperationErrorCallback(temp);
498   }
499 
500   /* Check FLASH Bank2 operation error flags */
501   errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
502                              FLASH_FLAG_INCERR_BANK2 | FLASH_FLAG_OPERR_BANK2) & 0x7FFFFFFFU);
503 
504  /* Check FLASH Bank2 operation error flags */
505   if(errorflag != 0U)
506   {
507     /* Save the error code */
508     pFlash.ErrorCode |= (errorflag | 0x80000000U);
509 
510     /* Clear error programming flags */
511     __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
512 
513     procedure = pFlash.ProcedureOnGoing;
514 
515     if(procedure== FLASH_PROC_SECTERASE_BANK2)
516     {
517       /*return the faulty sector*/
518       temp = pFlash.Sector;
519       pFlash.Sector = 0xFFFFFFFFU;
520     }
521     else if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
522     {
523       /*return the faulty bank*/
524       temp = FLASH_BANK_2;
525     }
526     else
527     {
528       /*return the faulty address*/
529       temp = pFlash.Address;
530     }
531 
532     /*Stop the procedure ongoing*/
533     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
534 
535     /* FLASH error interrupt user callback */
536     HAL_FLASH_OperationErrorCallback(temp);
537   }
538 
539   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
540   {
541     /* Disable Bank1 Operation and Error source interrupt */
542     __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1    | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
543                                  FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
544 
545     /* Disable Bank2 Operation and Error source interrupt */
546     __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2    | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
547                                  FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
548 
549     /* Process Unlocked */
550     __HAL_UNLOCK(&pFlash);
551   }
552 }
553 
554 /**
555   * @brief  FLASH end of operation interrupt callback
556   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
557   *                  Mass Erase: Bank number which has been requested to erase
558   *                  Sectors Erase: Sector which has been erased
559   *                    (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
560   *                  Program: Address which was selected for data program
561   * @retval None
562   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)563 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
564 {
565   /* Prevent unused argument(s) compilation warning */
566   UNUSED(ReturnValue);
567 
568   /* NOTE : This function Should not be modified, when the callback is needed,
569             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
570    */
571 }
572 
573 /**
574   * @brief  FLASH operation error interrupt callback
575   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
576   *                 Mass Erase: Bank number which has been requested to erase
577   *                 Sectors Erase: Sector number which returned an error
578   *                 Program: Address which was selected for data program
579   * @retval None
580   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)581 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
582 {
583   /* Prevent unused argument(s) compilation warning */
584   UNUSED(ReturnValue);
585 
586   /* NOTE : This function Should not be modified, when the callback is needed,
587             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
588    */
589 }
590 
591 /**
592   * @}
593   */
594 
595 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
596  *  @brief   Management functions
597  *
598 @verbatim
599  ===============================================================================
600                       ##### Peripheral Control functions #####
601  ===============================================================================
602     [..]
603     This subsection provides a set of functions allowing to control the FLASH
604     memory operations.
605 
606 @endverbatim
607   * @{
608   */
609 
610 /**
611   * @brief  Unlock the FLASH control registers access
612   * @retval HAL Status
613   */
HAL_FLASH_Unlock(void)614 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
615 {
616   if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
617   {
618     /* Authorize the FLASH Bank1 Registers access */
619     WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
620     WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
621 
622     /* Verify Flash Bank1 is unlocked */
623     if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
624     {
625       return HAL_ERROR;
626     }
627   }
628 
629   if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
630   {
631     /* Authorize the FLASH Bank2 Registers access */
632     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
633     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
634 
635     /* Verify Flash Bank2 is unlocked */
636     if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
637     {
638       return HAL_ERROR;
639     }
640   }
641 
642   return HAL_OK;
643 }
644 
645 /**
646   * @brief  Locks the FLASH control registers access
647   * @retval HAL Status
648   */
HAL_FLASH_Lock(void)649 HAL_StatusTypeDef HAL_FLASH_Lock(void)
650 {
651   /* Set the LOCK Bit to lock the FLASH Bank1 Control Register access */
652   SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
653 
654   /* Verify Flash Bank1 is locked */
655   if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) == 0U)
656   {
657     return HAL_ERROR;
658   }
659 
660   /* Set the LOCK Bit to lock the FLASH Bank2 Control Register access */
661   SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
662 
663   /* Verify Flash Bank2 is locked */
664   if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) == 0U)
665   {
666     return HAL_ERROR;
667   }
668 
669   return HAL_OK;
670 }
671 
672 /**
673   * @brief  Unlock the FLASH Option Control Registers access.
674   * @retval HAL Status
675   */
HAL_FLASH_OB_Unlock(void)676 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
677 {
678   if(READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
679   {
680     /* Authorizes the Option Byte registers programming */
681     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
682     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
683 
684     /* Verify that the Option Bytes are unlocked */
685     if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
686     {
687       return HAL_ERROR;
688     }
689   }
690 
691   return HAL_OK;
692 }
693 
694 /**
695   * @brief  Lock the FLASH Option Control Registers access.
696   * @retval HAL Status
697   */
HAL_FLASH_OB_Lock(void)698 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
699 {
700   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
701   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
702 
703   /* Verify that the Option Bytes are locked */
704   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) == 0U)
705   {
706     return HAL_ERROR;
707   }
708 
709   return HAL_OK;
710 }
711 
712 /**
713   * @brief  Launch the option bytes loading.
714   * @retval HAL Status
715   */
HAL_FLASH_OB_Launch(void)716 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
717 {
718   HAL_StatusTypeDef status;
719 
720   /* Wait for CRC computation to be completed */
721   if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
722   {
723     status = HAL_ERROR;
724   }
725   else if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
726   {
727     status = HAL_ERROR;
728   }
729   else
730   {
731     status = HAL_OK;
732   }
733 
734   if (status == HAL_OK)
735   {
736     /* Set OPTSTRT Bit */
737     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
738 
739     /* Wait for OB change operation to be completed */
740     status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
741   }
742 
743   return status;
744 }
745 
746 /**
747   * @}
748   */
749 
750 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
751  *  @brief   Peripheral Errors functions
752  *
753 @verbatim
754  ===============================================================================
755                 ##### Peripheral Errors functions #####
756  ===============================================================================
757     [..]
758     This subsection permits to get in run-time Errors of the FLASH peripheral.
759 
760 @endverbatim
761   * @{
762   */
763 
764 /**
765   * @brief  Get the specific FLASH error flag.
766   * @retval HAL_FLASH_ERRORCode The returned value can be:
767   *            @arg HAL_FLASH_ERROR_NONE       : No error set
768   *
769   *            @arg HAL_FLASH_ERROR_WRP_BANK1  : Write Protection Error on Bank 1
770   *            @arg HAL_FLASH_ERROR_PGS_BANK1  : Program Sequence Error on Bank 1
771   *            @arg HAL_FLASH_ERROR_STRB_BANK1 : Strobe Error on Bank 1
772   *            @arg HAL_FLASH_ERROR_INC_BANK1  : Inconsistency Error on Bank 1
773   *            @arg HAL_FLASH_ERROR_OPE_BANK1  : Operation Error on Bank 1
774   *            @arg HAL_FLASH_ERROR_RDP_BANK1  : Read Protection Error on Bank 1
775   *            @arg HAL_FLASH_ERROR_RDS_BANK1  : Read Secured Error on Bank 1
776   *            @arg HAL_FLASH_ERROR_SNECC_BANK1: ECC Single Correction Error on Bank 1
777   *            @arg HAL_FLASH_ERROR_DBECC_BANK1: ECC Double Detection Error on Bank 1
778   *            @arg HAL_FLASH_ERROR_CRCRD_BANK1: CRC Read Error on Bank 1
779   *
780   *            @arg HAL_FLASH_ERROR_WRP_BANK2  : Write Protection Error on Bank 2
781   *            @arg HAL_FLASH_ERROR_PGS_BANK2  : Program Sequence Error on Bank 2
782   *            @arg HAL_FLASH_ERROR_STRB_BANK2 : Strobe Error on Bank 2
783   *            @arg HAL_FLASH_ERROR_INC_BANK2  : Inconsistency Error on Bank 2
784   *            @arg HAL_FLASH_ERROR_OPE_BANK2  : Operation Error on Bank 2
785   *            @arg HAL_FLASH_ERROR_RDP_BANK2  : Read Protection Error on Bank 2
786   *            @arg HAL_FLASH_ERROR_RDS_BANK2  : Read Secured Error on Bank 2
787   *            @arg HAL_FLASH_ERROR_SNECC_BANK2: SNECC Error on Bank 2
788   *            @arg HAL_FLASH_ERROR_DBECC_BANK2: Double Detection ECC on Bank 2
789   *            @arg HAL_FLASH_ERROR_CRCRD_BANK2: CRC Read Error on Bank 2
790 */
791 
HAL_FLASH_GetError(void)792 uint32_t HAL_FLASH_GetError(void)
793 {
794    return pFlash.ErrorCode;
795 }
796 
797 /**
798   * @}
799   */
800 
801 /**
802   * @}
803   */
804 
805 /* Private functions ---------------------------------------------------------*/
806 
807 /** @addtogroup FLASH_Private_Functions
808   * @{
809   */
810 
811 /**
812   * @brief  Wait for a FLASH operation to complete.
813   * @param  Timeout maximum flash operation timeout
814   * @param  Bank flash FLASH_BANK_1 or FLASH_BANK_2
815   * @retval HAL_StatusTypeDef HAL Status
816   */
FLASH_WaitForLastOperation(uint32_t Timeout,uint32_t Bank)817 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
818 {
819   /* Wait for the FLASH operation to complete by polling on QW flag to be reset.
820      Even if the FLASH operation fails, the QW flag will be reset and an error
821      flag will be set */
822 
823   uint32_t bsyflag, errorflag;
824   uint32_t tickstart = HAL_GetTick();
825 
826   assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
827 
828   /* Select bsyflag depending on Bank */
829   if(Bank == FLASH_BANK_1)
830   {
831     bsyflag = FLASH_FLAG_QW_BANK1;
832   }
833   else
834   {
835     bsyflag = FLASH_FLAG_QW_BANK2;
836   }
837 
838   while(__HAL_FLASH_GET_FLAG(bsyflag))
839   {
840     if(Timeout != HAL_MAX_DELAY)
841     {
842       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
843       {
844         return HAL_TIMEOUT;
845       }
846     }
847   }
848 
849   /* Get Error Flags */
850   if (Bank == FLASH_BANK_1)
851   {
852     errorflag = FLASH->SR1 & FLASH_FLAG_ALL_ERRORS_BANK1;
853   }
854   else
855   {
856     errorflag = (FLASH->SR2 & FLASH_FLAG_ALL_ERRORS_BANK2) | 0x80000000U;
857   }
858 
859   /* In case of error reported in Flash SR1 or SR2 register */
860   if((errorflag & 0x7FFFFFFFU) != 0U)
861   {
862     /*Save the error code*/
863     pFlash.ErrorCode |= errorflag;
864 
865     /* Clear error programming flags */
866     __HAL_FLASH_CLEAR_FLAG(errorflag);
867 
868     return HAL_ERROR;
869   }
870 
871   /* Check FLASH End of Operation flag  */
872   if(Bank == FLASH_BANK_1)
873   {
874     if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
875     {
876       /* Clear FLASH End of Operation pending bit */
877       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
878     }
879   }
880   else
881   {
882     if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
883     {
884       /* Clear FLASH End of Operation pending bit */
885       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
886     }
887   }
888 
889   return HAL_OK;
890 }
891 
892 /**
893   * @brief  Wait for a FLASH Option Bytes change operation to complete.
894   * @param  Timeout maximum flash operation timeout
895   * @retval HAL_StatusTypeDef HAL Status
896   */
FLASH_OB_WaitForLastOperation(uint32_t Timeout)897 HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout)
898 {
899   /* Get timeout */
900   uint32_t tickstart = HAL_GetTick();
901 
902   /* Wait for the FLASH Option Bytes change operation to complete by polling on OPT_BUSY flag to be reset */
903   while(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPT_BUSY) != 0U)
904   {
905     if(Timeout != HAL_MAX_DELAY)
906     {
907       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
908       {
909         return HAL_TIMEOUT;
910       }
911     }
912   }
913 
914   /* Check option byte change error */
915   if(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPTCHANGEERR) != 0U)
916   {
917     /* Save the error code */
918     pFlash.ErrorCode |= HAL_FLASH_ERROR_OB_CHANGE;
919 
920     /* Clear the OB error flag */
921     FLASH->OPTCCR |= FLASH_OPTCCR_CLR_OPTCHANGEERR;
922 
923     return HAL_ERROR;
924   }
925 
926   /* If there is no error flag set */
927   return HAL_OK;
928 }
929 
930 /**
931   * @brief  Wait for a FLASH CRC computation to complete.
932   * @param  Timeout maximum flash operation timeout
933   * @param  Bank flash FLASH_BANK_1 or FLASH_BANK_2
934   * @retval HAL_StatusTypeDef HAL Status
935   */
FLASH_CRC_WaitForLastOperation(uint32_t Timeout,uint32_t Bank)936 HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
937 {
938   uint32_t bsyflag;
939   uint32_t tickstart = HAL_GetTick();
940 
941   assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
942 
943   /* Select bsyflag depending on Bank */
944   if(Bank == FLASH_BANK_1)
945   {
946     bsyflag = FLASH_FLAG_CRC_BUSY_BANK1;
947   }
948   else
949   {
950     bsyflag = FLASH_FLAG_CRC_BUSY_BANK2;
951   }
952 
953   /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
954   while(__HAL_FLASH_GET_FLAG(bsyflag))
955   {
956     if(Timeout != HAL_MAX_DELAY)
957     {
958       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
959       {
960         return HAL_TIMEOUT;
961       }
962     }
963   }
964 
965   /* Check FLASH CRC read error flag  */
966   if(Bank == FLASH_BANK_1)
967   {
968     if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1))
969     {
970       /* Save the error code */
971       pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK1;
972 
973       /* Clear FLASH CRC read error pending bit */
974       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1);
975 
976       return HAL_ERROR;
977     }
978   }
979   else
980   {
981     if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2))
982     {
983       /* Save the error code */
984       pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK2;
985 
986       /* Clear FLASH CRC read error pending bit */
987       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2);
988 
989       return HAL_ERROR;
990     }
991   }
992 
993   /* If there is no error flag set */
994   return HAL_OK;
995 }
996 
997 /**
998   * @}
999   */
1000 
1001 #endif /* HAL_FLASH_MODULE_ENABLED */
1002 
1003 /**
1004   * @}
1005   */
1006 
1007 /**
1008   * @}
1009   */
1010 
1011 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1012