1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2022 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23  @verbatim
24   ==============================================================================
25                         ##### FLASH peripheral features #####
26   ==============================================================================
27 
28   [..] The Flash memory interface manages CPU AHB C-Bus accesses to the Flash memory.
29        It implements the erase and program Flash memory operations and the read
30        and write protection mechanisms.
31 
32   [..] The FLASH main features are:
33       (+) Flash memory read operations
34       (+) Flash memory program/erase operations
35       (+) Read / write protections
36       (+) Option bytes programming
37       (+) TrustZone aware
38       (+) Watermark-based area protection
39       (+) Block-based sector protection
40       (+) Error code correction (ECC)
41 
42 
43                         ##### How to use this driver #####
44  ==============================================================================
45     [..]
46       This driver provides functions and macros to configure and program the FLASH
47       memory of all STM32H5xx devices.
48 
49       (#) FLASH Memory IO Programming functions:
50            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
51                 HAL_FLASH_Lock() functions
52            (++) Flash memory programming by 128 bits (user area, OBKeys) and 16 bits (OTP and Flash high-cycle
53                 data area)
54            (++) There Two modes of programming :
55             (+++) Polling mode using HAL_FLASH_Program() function
56             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
57 
58       (#) Interrupts and flags management functions :
59            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
60            (++) Callback functions are called when the flash operations are finished :
61                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
62                 HAL_FLASH_OperationErrorCallback()
63            (++) Get error flag status by calling HAL_FLASH_GetError()
64 
65       (#) Option bytes management functions :
66            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
67                 HAL_FLASH_OB_Lock() functions
68            (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
69                 In this case, a reset is generated
70     [..]
71       In addition to these functions, this driver includes a set of macros allowing
72       to handle the following operations:
73        (+) Set the latency
74        (+) Enable/Disable the FLASH interrupts
75        (+) Monitor the FLASH flags status
76      [..]
77     (@) The contents of the Flash memory are not guaranteed if a device reset occurs during
78         a Flash memory operation.
79 
80  @endverbatim
81   */
82 
83 /* Includes ------------------------------------------------------------------*/
84 #include "stm32h5xx_hal.h"
85 
86 /** @addtogroup STM32H5xx_HAL_Driver
87   * @{
88   */
89 
90 /** @defgroup FLASH FLASH
91   * @brief FLASH HAL module driver
92   * @{
93   */
94 
95 #ifdef HAL_FLASH_MODULE_ENABLED
96 
97 /* Private typedef -----------------------------------------------------------*/
98 /* Private define ------------------------------------------------------------*/
99 /* Private macro -------------------------------------------------------------*/
100 /* Private variables ---------------------------------------------------------*/
101 /** @defgroup FLASH_Private_Variables FLASH Private Variables
102   * @{
103   */
104 /**
105   * @brief  Variable used for Program/Erase sectors under interruption
106   */
107 FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
108                                .ErrorCode = HAL_FLASH_ERROR_NONE, \
109                                .ProcedureOnGoing = 0U, \
110                                .Address = 0U, \
111                                .Bank = FLASH_BANK_1, \
112                                .Sector = 0U, \
113                                .NbSectorsToErase = 0U
114                               };
115 /**
116   * @}
117   */
118 /* Private function prototypes -----------------------------------------------*/
119 /** @defgroup FLASH_Private_Functions FLASH Private Functions
120   * @{
121   */
122 static void          FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress);
123 #if defined (FLASH_SR_OBKERR)
124 static void          FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress);
125 #endif /* FLASH_SR_OBKERR */
126 static void          FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress);
127 
128 /**
129   * @}
130   */
131 /* Exported functions ---------------------------------------------------------*/
132 
133 /** @defgroup FLASH_Exported_Functions FLASH Exported functions
134   * @{
135   */
136 
137 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
138   *  @brief   Programming operation functions
139   *
140 @verbatim
141  ===============================================================================
142                   ##### Programming operation functions #####
143  ===============================================================================
144     [..]
145     This subsection provides a set of functions allowing to manage the FLASH
146     program operations.
147 
148 @endverbatim
149   * @{
150   */
151 
152 /**
153   * @brief  Program a quad-word at a specified address.
154   * @param  TypeProgram Indicate the way to program at a specified address.
155   *         This parameter can be a value of @ref FLASH_Type_Program
156   * @param  FlashAddress specifies the address to be programmed.
157   *         This parameter shall be aligned to the Flash word (128-bit)
158   * @param  DataAddress specifies the address of data to be programmed
159   *         This parameter shall be 32-bit aligned
160   * @retval HAL_StatusTypeDef HAL Status
161   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)162 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
163 {
164   HAL_StatusTypeDef status;
165   __IO uint32_t *reg_cr;
166 #if defined (FLASH_SR_OBKERR)
167   __IO uint32_t *reg_obkcfgr;
168 #endif /* FLASH_SR_OBKERR */
169 
170   /* Check the parameters */
171   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
172 
173   /* Process Locked */
174   __HAL_LOCK(&pFlash);
175 
176   /* Reset error code */
177   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
178 
179   /* Wait for last operation to be completed */
180   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
181 
182   if (status == HAL_OK)
183   {
184     /* Set current operation type */
185     pFlash.ProcedureOnGoing = TypeProgram;
186 
187     /* Access to SECCR or NSCR depends on operation type */
188 #if defined (FLASH_OPTSR2_TZEN)
189     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
190 #else
191     reg_cr = &(FLASH_NS->NSCR);
192 #endif /* FLASH_OPTSR2_TZEN */
193 
194     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
195     {
196       /* Check the parameters */
197       assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
198 
199       /* Program a quad-word (128-bit) at a specified address */
200       FLASH_Program_QuadWord(FlashAddress, DataAddress);
201     }
202 #if defined (FLASH_SR_OBKERR)
203     else if ((TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK) || (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
204     {
205       /* Check the parameters */
206       assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
207 
208       /* Program a quad-word (128-bit) of OBK at a specified address */
209       FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
210     }
211 #endif /* FLASH_SR_OBKERR */
212 #if defined (FLASH_EDATAR_EDATA_EN)
213     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
214     {
215       /* Check the parameters */
216       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
217 
218       /* Program a Flash high-cycle data half-word at a specified address */
219       FLASH_Program_HalfWord(FlashAddress, DataAddress);
220     }
221 #endif /* FLASH_EDATAR_EDATA_EN */
222     else
223     {
224       /* Check the parameters */
225       assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
226 
227       /* Program an OTP half-word at a specified address */
228       FLASH_Program_HalfWord(FlashAddress, DataAddress);
229     }
230 
231     /* Wait for last operation to be completed */
232     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
233 
234 #if defined (FLASH_SR_OBKERR)
235     /* If the program operation is completed, disable the PG */
236     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OBK | FLASH_OTP | FLASH_OBKCFGR_ALT_SECT)));
237 
238     /* Clear alternate sector bit */
239     if (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)
240     {
241       reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
242       CLEAR_BIT((*reg_obkcfgr), FLASH_OBKCFGR_ALT_SECT);
243     }
244 #else
245     /* If the program operation is completed, disable the PG */
246     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK |  FLASH_OTP)));
247 #endif /* FLASH_SR_OBKERR */
248   }
249   /* Process Unlocked */
250   __HAL_UNLOCK(&pFlash);
251 
252   /* return status */
253   return status;
254 }
255 
256 /**
257   * @brief  Program a quad-word at a specified address with interrupt enabled.
258   * @param  TypeProgram Indicate the way to program at a specified address.
259   *                      This parameter can be a value of @ref FLASH_Type_Program
260   * @param  FlashAddress specifies the address to be programmed.
261   *         This parameter shall be aligned to the Flash word (128-bit)
262   * @param  DataAddress specifies the address of data to be programmed
263   *         This parameter shall be 32-bit aligned
264   * @retval HAL Status
265   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)266 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
267 {
268   HAL_StatusTypeDef status;
269   __IO uint32_t *reg_cr;
270 
271   /* Check the parameters */
272   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
273 
274   /* Process Locked */
275   __HAL_LOCK(&pFlash);
276 
277   /* Reset error code */
278   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
279 
280   /* Wait for last operation to be completed */
281   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
282 
283   if (status != HAL_OK)
284   {
285     /* Process Unlocked */
286     __HAL_UNLOCK(&pFlash);
287   }
288   else
289   {
290     /* Set internal variables used by the IRQ handler */
291     pFlash.ProcedureOnGoing = TypeProgram;
292     pFlash.Address = FlashAddress;
293 
294     /* Access to SECCR or NSCR depends on operation type */
295 #if defined (FLASH_OPTSR2_TZEN)
296     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
297 #else
298     reg_cr = &(FLASH_NS->NSCR);
299 #endif /* FLASH_OPTSR2_TZEN */
300 
301     /* Enable End of Operation and Error interrupts */
302 #if defined (FLASH_SR_OBKERR)
303     (*reg_cr) |= (FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
304                   FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
305                   FLASH_IT_OBKWERR);
306 #else
307     (*reg_cr) |= (FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
308                   FLASH_IT_STRBERR | FLASH_IT_INCERR);
309 #endif /* FLASH_SR_OBKERR */
310 
311     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
312     {
313       /* Check the parameters */
314       assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
315 
316       /* Program a quad-word (128-bit) at a specified address */
317       FLASH_Program_QuadWord(FlashAddress, DataAddress);
318     }
319 #if defined (FLASH_SR_OBKERR)
320     else if (((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \
321              ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
322     {
323       /* Check the parameters */
324       assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
325 
326       /* Program a quad-word (128-bit) of OBK at a specified address */
327       FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
328     }
329 #endif /* FLASH_SR_OBKERR */
330 #if defined (FLASH_EDATAR_EDATA_EN)
331     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
332     {
333       /* Check the parameters */
334       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
335 
336       /* Program a Flash high-cycle data half-word at a specified address */
337       FLASH_Program_HalfWord(FlashAddress, DataAddress);
338     }
339 #endif /* FLASH_EDATAR_EDATA_EN */
340     else
341     {
342       /* Check the parameters */
343       assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
344 
345       /* Program an OTP word at a specified address */
346       FLASH_Program_HalfWord(FlashAddress, DataAddress);
347     }
348   }
349 
350   /* return status */
351   return status;
352 }
353 
354 /**
355   * @brief This function handles FLASH interrupt request.
356   * @retval None
357   */
HAL_FLASH_IRQHandler(void)358 void HAL_FLASH_IRQHandler(void)
359 {
360   uint32_t param = 0U;
361   uint32_t errorflag;
362   __IO uint32_t *reg_cr;
363   __IO uint32_t *reg_ccr;
364   __IO uint32_t *reg_sr;
365 
366   /* Access to CR, CCR and SR registers depends on operation type */
367 #if defined (FLASH_OPTSR2_TZEN)
368   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
369   reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
370   reg_sr  = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
371 #else
372   reg_cr = &(FLASH_NS->NSCR);
373   reg_ccr = &(FLASH_NS->NSCCR);
374   reg_sr = &(FLASH_NS->NSSR);
375 #endif /* FLASH_OPTSR2_TZEN */
376 
377   /* Save Flash errors */
378   errorflag = (*reg_sr) & FLASH_FLAG_SR_ERRORS;
379   /* Add option byte error flag, if any */
380 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
381   errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
382 #endif /* __ARM_FEATURE_CMSE */
383 
384   /* Set parameter of the callback */
385   if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
386   {
387     param = pFlash.Sector;
388   }
389   else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE)
390   {
391     param = pFlash.Bank;
392   }
393   else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
394   {
395     param = pFlash.Address;
396   }
397   else
398   {
399     /* Empty statement (to be compliant MISRA 15.7) */
400   }
401 
402   /* Clear operation bit on the on-going procedure */
403   CLEAR_BIT((*reg_cr), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK)));
404 
405   /* Check FLASH operation error flags */
406   if (errorflag != 0U)
407   {
408     /* Save the error code */
409     pFlash.ErrorCode |= errorflag;
410 
411     /* Clear error programming flags */
412     (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
413 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
414     if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
415     {
416       FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
417     }
418 #endif /* __ARM_FEATURE_CMSE */
419 
420     /* Stop the procedure ongoing */
421     pFlash.ProcedureOnGoing = 0U;
422 
423     /* FLASH error interrupt user callback */
424     HAL_FLASH_OperationErrorCallback(param);
425   }
426 
427   /* Check FLASH End of Operation flag */
428   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
429   {
430     /* Clear FLASH End of Operation pending bit */
431     (*reg_ccr) = FLASH_FLAG_EOP;
432 
433     if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
434     {
435       /* Nb of sector to erased can be decreased */
436       pFlash.NbSectorsToErase--;
437 
438       /* Check if there are still sectors to erase */
439       if (pFlash.NbSectorsToErase != 0U)
440       {
441         /* Increment sector number */
442         pFlash.Sector++;
443         FLASH_Erase_Sector(pFlash.Sector, pFlash.Bank);
444       }
445       else
446       {
447         /* No more sectors to erase */
448         /* Reset sector parameter and stop erase sectors procedure */
449         param = 0xFFFFFFFFU;
450         pFlash.ProcedureOnGoing = 0U;
451       }
452     }
453     else
454     {
455       /* Clear the procedure ongoing */
456       pFlash.ProcedureOnGoing = 0U;
457     }
458 
459     /* FLASH EOP interrupt user callback */
460     HAL_FLASH_EndOfOperationCallback(param);
461   }
462 
463   if (pFlash.ProcedureOnGoing == 0U)
464   {
465     /* Disable Flash Operation and Error source interrupt */
466 #if defined (FLASH_SR_OBKERR)
467     (*reg_cr) &= ~(FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
468                    FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
469                    FLASH_IT_OBKWERR | FLASH_IT_OPTCHANGEERR);
470 #else
471     (*reg_cr) &= ~(FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
472                    FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OPTCHANGEERR);
473 #endif /* FLASH_SR_OBKERR */
474     /* Process Unlocked */
475     __HAL_UNLOCK(&pFlash);
476   }
477 }
478 
479 /**
480   * @brief  FLASH end of operation interrupt callback
481   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
482   *                  Mass Erase: Bank number which has been requested to erase
483   *                  Sectors Erase: Sector which has been erased
484   *                    (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
485   *                  Program: Address which was selected for data program
486   * @retval None
487   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)488 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
489 {
490   /* Prevent unused argument(s) compilation warning */
491   UNUSED(ReturnValue);
492 
493   /* NOTE : This function Should not be modified, when the callback is needed,
494             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
495    */
496 }
497 
498 /**
499   * @brief  FLASH operation error interrupt callback
500   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
501   *                 Mass Erase: Bank number which has been requested to erase
502   *                 Sectors Erase: Sector number which returned an error
503   *                 Program: Address which was selected for data program
504   * @retval None
505   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)506 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
507 {
508   /* Prevent unused argument(s) compilation warning */
509   UNUSED(ReturnValue);
510 
511   /* NOTE : This function Should not be modified, when the callback is needed,
512             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
513    */
514 }
515 
516 /**
517   * @}
518   */
519 
520 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
521   *  @brief    Management functions
522   *
523 @verbatim
524  ===============================================================================
525                       ##### Peripheral Control functions #####
526  ===============================================================================
527     [..]
528     This subsection provides a set of functions allowing to control the FLASH
529     memory operations.
530 
531 @endverbatim
532   * @{
533   */
534 
535 /**
536   * @brief  Unlock the FLASH control registers access
537   * @retval HAL Status
538   */
HAL_FLASH_Unlock(void)539 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
540 {
541   HAL_StatusTypeDef status = HAL_OK;
542 
543   if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
544   {
545     /* Authorize the FLASH Control Register access */
546     WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
547     WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
548 
549     /* Verify Flash CR is unlocked */
550     if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
551     {
552       status = HAL_ERROR;
553     }
554   }
555 
556 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
557   if (status == HAL_OK)
558   {
559     if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
560     {
561       /* Authorize the FLASH Control Register access */
562       WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
563       WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
564 
565       /* verify Flash CR is unlocked */
566       if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
567       {
568         status = HAL_ERROR;
569       }
570     }
571   }
572 #endif /* __ARM_FEATURE_CMSE */
573 
574   return status;
575 }
576 
577 /**
578   * @brief  Locks the FLASH control registers access
579   * @retval HAL Status
580   */
HAL_FLASH_Lock(void)581 HAL_StatusTypeDef HAL_FLASH_Lock(void)
582 {
583   HAL_StatusTypeDef status = HAL_OK;
584 
585   /* Set the LOCK Bit to lock the FLASH Control Register access */
586   SET_BIT(FLASH->NSCR, FLASH_CR_LOCK);
587 
588   /* Verify Flash is locked */
589   if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) == 0U)
590   {
591     status = HAL_ERROR;
592   }
593 
594 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
595   if (status == HAL_OK)
596   {
597     /* Set the LOCK Bit to lock the FLASH Control Register access */
598     SET_BIT(FLASH->SECCR, FLASH_CR_LOCK);
599 
600     /* verify Flash is locked */
601     if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) == 0U)
602     {
603       status = HAL_ERROR;
604     }
605   }
606 #endif /* __ARM_FEATURE_CMSE */
607 
608   return status;
609 }
610 
611 /**
612   * @brief  Unlock the FLASH Option Control Registers access.
613   * @retval HAL Status
614   */
HAL_FLASH_OB_Unlock(void)615 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
616 {
617   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
618   {
619     /* Authorizes the Option Byte registers programming */
620     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
621     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
622 
623     /* Verify that the Option Bytes are unlocked */
624     if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
625     {
626       return HAL_ERROR;
627     }
628   }
629 
630   return HAL_OK;
631 }
632 
633 /**
634   * @brief  Lock the FLASH Option Control Registers access.
635   * @retval HAL Status
636   */
HAL_FLASH_OB_Lock(void)637 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
638 {
639   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
640   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
641 
642   /* Verify that the Option Bytes are locked */
643   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
644   {
645     return HAL_OK;
646   }
647 
648   return HAL_ERROR;
649 }
650 
651 /**
652   * @brief  Launch the option bytes loading.
653   * @retval HAL Status
654   */
HAL_FLASH_OB_Launch(void)655 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
656 {
657   HAL_StatusTypeDef status;
658 
659   /* Set OPTSTRT Bit */
660   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
661 
662   /* Wait for OB change operation to be completed */
663   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
664 
665   return status;
666 }
667 
668 /**
669   * @}
670   */
671 
672 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
673   *  @brief   Peripheral Errors functions
674   *
675 @verbatim
676  ===============================================================================
677                 ##### Peripheral Errors functions #####
678  ===============================================================================
679     [..]
680     This subsection permits to get in run-time Errors of the FLASH peripheral.
681 
682 @endverbatim
683   * @{
684   */
685 
686 /**
687   * @brief  Get the specific FLASH error flag.
688   * @retval HAL_FLASH_ERRORCode The returned value can be:
689   *            @arg HAL_FLASH_ERROR_NONE  : No error set
690   *            @arg HAL_FLASH_ERROR_WRP   : Write Protection Error
691   *            @arg HAL_FLASH_ERROR_PGS   : Program Sequence Error
692   *            @arg HAL_FLASH_ERROR_STRB  : Strobe Error
693   *            @arg HAL_FLASH_ERROR_INC   : Inconsistency Error
694   *            @arg HAL_FLASH_ERROR_OBK   : OBK Error
695   *            @arg HAL_FLASH_ERROR_OBKW  : OBK Write Error
696   *            @arg HAL_FLASH_ERROR_OB_CHANGE : Option Byte Change Error
697   *            @arg HAL_FLASH_ERROR_ECCC  : ECC Single Correction Error
698   *            @arg HAL_FLASH_ERROR_ECCD  : ECC Double Detection Error
699   */
HAL_FLASH_GetError(void)700 uint32_t HAL_FLASH_GetError(void)
701 {
702   return pFlash.ErrorCode;
703 }
704 
705 /**
706   * @}
707   */
708 
709 /**
710   * @}
711   */
712 
713 /* Private functions ---------------------------------------------------------*/
714 
715 /** @addtogroup FLASH_Private_Functions
716   * @{
717   */
718 
719 /**
720   * @brief  Wait for a FLASH operation to complete.
721   * @param  Timeout maximum flash operation timeout
722   * @retval HAL_StatusTypeDef HAL Status
723   */
FLASH_WaitForLastOperation(uint32_t Timeout)724 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
725 {
726   /* Wait for the FLASH operation to complete by polling on BUSY, WBNE and DBNE flags to be reset.
727      Even if the FLASH operation fails, the BUSY, WBNE and DBNE flags will be reset and an error
728      flag will be set */
729 
730   uint32_t errorflag;
731   __IO uint32_t *reg_sr;
732   __IO uint32_t *reg_ccr;
733 
734   uint32_t tickstart = HAL_GetTick();
735 
736   /* Access to SR register depends on operation type */
737 #if defined (FLASH_OPTSR2_TZEN)
738   reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
739 #else
740   reg_sr = &(FLASH_NS->NSSR);
741 #endif /* FLASH_OPTSR2_TZEN */
742 
743   /* Wait on BSY, WBNE and DBNE flags to be reset */
744   while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WBNE | FLASH_FLAG_DBNE)) != 0U)
745   {
746     if (Timeout != HAL_MAX_DELAY)
747     {
748       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
749       {
750         return HAL_TIMEOUT;
751       }
752     }
753   }
754 
755   /* Access to CCR register depends on operation type */
756 #if defined (FLASH_OPTSR2_TZEN)
757   reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
758 #else
759   reg_ccr = &(FLASH_NS->NSCCR);
760 #endif /* FLASH_OPTSR2_TZEN */
761 
762   /* Check FLASH operation error flags */
763   errorflag = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
764   /* Add option byte error flag, if any */
765 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
766   errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
767 #endif /* __ARM_FEATURE_CMSE */
768 
769   /* In case of error reported in Flash SR or OPTSR registers */
770   if (errorflag != 0U)
771   {
772     /*Save the error code*/
773     pFlash.ErrorCode |= errorflag;
774 
775     /* Clear error flags */
776     (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
777 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
778     if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
779     {
780       FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
781     }
782 #endif /* __ARM_FEATURE_CMSE */
783 
784     return HAL_ERROR;
785   }
786 
787   /* Check FLASH End of Operation flag  */
788   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
789   {
790     /* Clear FLASH End of Operation pending bit */
791     (*reg_ccr) = FLASH_FLAG_EOP;
792   }
793 
794   /* If there is no error flag set */
795   return HAL_OK;
796 }
797 
798 /**
799   * @brief  Program a quad-word (128-bit) at a specified address.
800   * @param  FlashAddress specifies the address to be programmed.
801   * @param  DataAddress specifies the address of data to be programmed.
802   * @retval None
803   */
FLASH_Program_QuadWord(uint32_t FlashAddress,uint32_t DataAddress)804 static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress)
805 {
806   uint8_t index = 4;
807   uint32_t *dest_addr = (uint32_t *)FlashAddress;
808   uint32_t *src_addr  = (uint32_t *)DataAddress;
809   uint32_t primask_bit;
810   __IO uint32_t *reg_cr;
811 
812   /* Access to SECCR or NSCR registers depends on operation type */
813 #if defined (FLASH_OPTSR2_TZEN)
814   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
815 #else
816   reg_cr = &(FLASH_NS->NSCR);
817 #endif /* FLASH_OPTSR2_TZEN */
818 
819   /* Set PG bit */
820   SET_BIT((*reg_cr), FLASH_CR_PG);
821 
822   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
823   primask_bit = __get_PRIMASK();
824   __disable_irq();
825 
826   /* Program the quad-word */
827   do
828   {
829     *dest_addr = *src_addr;
830     dest_addr++;
831     src_addr++;
832     index--;
833   } while (index != 0U);
834 
835   /* Exit critical section: restore previous priority mask */
836   __set_PRIMASK(primask_bit);
837 }
838 
839 #if defined (FLASH_SR_OBKERR)
840 /**
841   * @brief  Program a quad-word (128-bit) of OBK at a specified address.
842   * @param  FlashAddress specifies the address to be programmed.
843   * @param  DataAddress specifies the address of data to be programmed.
844   * @retval None
845   */
FLASH_Program_QuadWord_OBK(uint32_t FlashAddress,uint32_t DataAddress)846 static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress)
847 {
848   uint8_t index = 4;
849   uint32_t *dest_addr = (uint32_t *)FlashAddress;
850   uint32_t *src_addr  = (uint32_t *)DataAddress;
851   uint32_t primask_bit;
852   __IO uint32_t *reg_cr;
853   __IO uint32_t *reg_obkcfgr;
854 
855   /* Access to SECCR or NSCR registers depends on operation type */
856   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
857   reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
858 
859   /* Set PG bit */
860   SET_BIT((*reg_cr), FLASH_CR_PG);
861 
862   /* Set ALT_SECT bit */
863   SET_BIT((*reg_obkcfgr), pFlash.ProcedureOnGoing & FLASH_OBKCFGR_ALT_SECT);
864 
865   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
866   primask_bit = __get_PRIMASK();
867   __disable_irq();
868 
869   /* Program the quad-word */
870   do
871   {
872     *dest_addr = *src_addr;
873     dest_addr++;
874     src_addr++;
875     index--;
876   } while (index != 0U);
877 
878   /* Exit critical section: restore previous priority mask */
879   __set_PRIMASK(primask_bit);
880 }
881 #endif /* FLASH_SR_OBKERR */
882 
883 /**
884   * @brief  Program a half-word (16-bit) at a specified address.
885   * @param  FlashAddress specifies the address to be programmed.
886   * @param  DataAddress specifies the address of data to be programmed.
887   * @retval None
888   */
FLASH_Program_HalfWord(uint32_t FlashAddress,uint32_t DataAddress)889 static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress)
890 {
891   __IO uint32_t *reg_cr;
892 
893   /* Access to SECCR or NSCR registers depends on operation type */
894 #if defined (FLASH_OPTSR2_TZEN)
895   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
896 #else
897   reg_cr = &(FLASH_NS->NSCR);
898 #endif /* FLASH_OPTSR2_TZEN */
899 
900   /* Set HalfWord_PG bit */
901   SET_BIT((*reg_cr), FLASH_CR_PG);
902 
903   /* Program a halfword word (16 bits) */
904   *(__IO uint16_t *)FlashAddress = *(__IO uint16_t *)DataAddress;
905 }
906 
907 /**
908   * @}
909   */
910 
911 #endif /* HAL_FLASH_MODULE_ENABLED */
912 
913 /**
914   * @}
915   */
916 
917 /**
918   * @}
919   */
920