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) 2023 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 #if defined(FLASH_EDATAR_EDATA_EN)
128 static void          FLASH_Program_Word(uint32_t FlashAddress, uint32_t DataAddress);
129 #endif /* FLASH_EDATAR_EDATA_EN */
130 
131 /**
132   * @}
133   */
134 /* Exported functions ---------------------------------------------------------*/
135 
136 /** @defgroup FLASH_Exported_Functions FLASH Exported functions
137   * @{
138   */
139 
140 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
141   *  @brief   Programming operation functions
142   *
143 @verbatim
144  ===============================================================================
145                   ##### Programming operation functions #####
146  ===============================================================================
147     [..]
148     This subsection provides a set of functions allowing to manage the FLASH
149     program operations.
150 
151 @endverbatim
152   * @{
153   */
154 
155 /**
156   * @brief  Program a quad-word at a specified address.
157   * @param  TypeProgram Indicate the way to program at a specified address.
158   *         This parameter can be a value of @ref FLASH_Type_Program
159   * @param  FlashAddress specifies the address to be programmed.
160   *         This parameter shall be aligned to the Flash word (128-bit)
161   * @param  DataAddress specifies the address of data to be programmed
162   *         This parameter shall be 32-bit aligned
163   * @retval HAL_StatusTypeDef HAL Status
164   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)165 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
166 {
167   HAL_StatusTypeDef status;
168   __IO uint32_t *reg_cr;
169 #if defined (FLASH_SR_OBKERR)
170   __IO uint32_t *reg_obkcfgr;
171 #endif /* FLASH_SR_OBKERR */
172 
173   /* Check the parameters */
174   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
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     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_WORD_EDATA)
222     {
223       /* Check the parameters */
224       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
225 
226       /* Program a Flash high-cycle data half-word at a specified address */
227       FLASH_Program_Word(FlashAddress, DataAddress);
228     }
229 #endif /* FLASH_EDATAR_EDATA_EN */
230     else
231     {
232       /* Check the parameters */
233       assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
234 
235       /* Program an OTP half-word at a specified address */
236       FLASH_Program_HalfWord(FlashAddress, DataAddress);
237     }
238 
239     /* Wait for last operation to be completed */
240     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
241 
242 #if defined (FLASH_SR_OBKERR)
243     /* If the program operation is completed, disable the PG */
244     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OBK | FLASH_OTP | FLASH_OBKCFGR_ALT_SECT)));
245 
246     /* Clear alternate sector bit */
247     if (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)
248     {
249       reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
250       CLEAR_BIT((*reg_obkcfgr), FLASH_OBKCFGR_ALT_SECT);
251     }
252 #else
253     /* If the program operation is completed, disable the PG */
254     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK |  FLASH_OTP)));
255 #endif /* FLASH_SR_OBKERR */
256   }
257   /* return status */
258   return status;
259 }
260 
261 /**
262   * @brief  Program a quad-word at a specified address with interrupt enabled.
263   * @param  TypeProgram Indicate the way to program at a specified address.
264   *                      This parameter can be a value of @ref FLASH_Type_Program
265   * @param  FlashAddress specifies the address to be programmed.
266   *         This parameter shall be aligned to the Flash word (128-bit)
267   * @param  DataAddress specifies the address of data to be programmed
268   *         This parameter shall be 32-bit aligned
269   * @retval HAL Status
270   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t FlashAddress,uint32_t DataAddress)271 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
272 {
273   HAL_StatusTypeDef status;
274   __IO uint32_t *reg_cr;
275 
276   /* Check the parameters */
277   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
278 
279   /* Reset error code */
280   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
281 
282   /* Wait for last operation to be completed */
283   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
284 
285   if (status != HAL_OK)
286   {
287     /* Process Unlocked */
288     __HAL_UNLOCK(&pFlash);
289   }
290   else
291   {
292     /* Set internal variables used by the IRQ handler */
293     pFlash.ProcedureOnGoing = TypeProgram;
294     pFlash.Address = FlashAddress;
295 
296     /* Access to SECCR or NSCR depends on operation type */
297 #if defined (FLASH_OPTSR2_TZEN)
298     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
299 #else
300     reg_cr = &(FLASH_NS->NSCR);
301 #endif /* FLASH_OPTSR2_TZEN */
302 
303     /* Enable End of Operation and Error interrupts */
304 #if defined (FLASH_SR_OBKERR)
305     (*reg_cr) |= (FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
306                   FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
307                   FLASH_IT_OBKWERR);
308 #else
309     (*reg_cr) |= (FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
310                   FLASH_IT_STRBERR | FLASH_IT_INCERR);
311 #endif /* FLASH_SR_OBKERR */
312 
313     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
314     {
315       /* Check the parameters */
316       assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
317 
318       /* Program a quad-word (128-bit) at a specified address */
319       FLASH_Program_QuadWord(FlashAddress, DataAddress);
320     }
321 #if defined (FLASH_SR_OBKERR)
322     else if (((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \
323              ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
324     {
325       /* Check the parameters */
326       assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
327 
328       /* Program a quad-word (128-bit) of OBK at a specified address */
329       FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
330     }
331 #endif /* FLASH_SR_OBKERR */
332 #if defined (FLASH_EDATAR_EDATA_EN)
333     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
334     {
335       /* Check the parameters */
336       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
337 
338       /* Program a Flash high-cycle data half-word at a specified address */
339       FLASH_Program_HalfWord(FlashAddress, DataAddress);
340     }
341      else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_WORD_EDATA)
342     {
343       /* Check the parameters */
344       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
345 
346       /* Program a Flash high-cycle data word at a specified address */
347       FLASH_Program_Word(FlashAddress, DataAddress);
348     }
349 #endif /* FLASH_EDATAR_EDATA_EN */
350     else
351     {
352       /* Check the parameters */
353       assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
354 
355       /* Program an OTP word at a specified address */
356       FLASH_Program_HalfWord(FlashAddress, DataAddress);
357     }
358   }
359 
360   /* return status */
361   return status;
362 }
363 
364 /**
365   * @brief This function handles FLASH interrupt request.
366   * @retval None
367   */
HAL_FLASH_IRQHandler(void)368 void HAL_FLASH_IRQHandler(void)
369 {
370   uint32_t param = 0U;
371   uint32_t errorflag;
372   __IO uint32_t *reg_cr;
373   __IO uint32_t *reg_ccr;
374   const __IO uint32_t *reg_sr;
375   const __IO uint32_t *reg_ecccorr;
376 
377   /* Access to CR, CCR and SR registers depends on operation type */
378 #if defined (FLASH_OPTSR2_TZEN)
379   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
380   reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
381   reg_sr  = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
382 #else
383   reg_cr = &(FLASH_NS->NSCR);
384   reg_ccr = &(FLASH_NS->NSCCR);
385   reg_sr = &(FLASH_NS->NSSR);
386 #endif /* FLASH_OPTSR2_TZEN */
387   reg_ecccorr = &(FLASH->ECCCORR);
388 
389   /* Save Flash errors */
390   errorflag = (*reg_sr) & FLASH_FLAG_SR_ERRORS;
391   /* Add option byte error flag, if any */
392 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
393   errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
394 #endif /* __ARM_FEATURE_CMSE */
395 
396   /* Set parameter of the callback */
397   if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
398   {
399     param = pFlash.Sector;
400   }
401   else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE)
402   {
403     param = pFlash.Bank;
404   }
405   else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
406   {
407     param = pFlash.Address;
408   }
409   else
410   {
411     /* Empty statement (to be compliant MISRA 15.7) */
412   }
413 
414   /* Clear operation bit on the on-going procedure */
415   CLEAR_BIT((*reg_cr), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK)));
416 
417   /* Check FLASH operation error flags */
418   if (errorflag != 0U)
419   {
420     /* Save the error code */
421     pFlash.ErrorCode |= errorflag;
422 
423     /* Clear error programming flags */
424     (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
425 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
426     if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
427     {
428       FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
429     }
430 #endif /* __ARM_FEATURE_CMSE */
431 
432     /* Stop the procedure ongoing */
433     pFlash.ProcedureOnGoing = 0U;
434 
435     /* FLASH error interrupt user callback */
436     HAL_FLASH_OperationErrorCallback(param);
437   }
438 
439   /* Check FLASH End of Operation flag */
440   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
441   {
442     /* Clear FLASH End of Operation pending bit */
443     (*reg_ccr) = FLASH_FLAG_EOP;
444 
445     if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
446     {
447       /* Nb of sector to erased can be decreased */
448       pFlash.NbSectorsToErase--;
449 
450       /* Check if there are still sectors to erase */
451       if (pFlash.NbSectorsToErase != 0U)
452       {
453         /* Increment sector number */
454         pFlash.Sector++;
455         FLASH_Erase_Sector(pFlash.Sector, pFlash.Bank);
456       }
457       else
458       {
459         /* No more sectors to erase */
460         /* Reset sector parameter and stop erase sectors procedure */
461         param = 0xFFFFFFFFU;
462         pFlash.ProcedureOnGoing = 0U;
463       }
464     }
465     else
466     {
467       /* Clear the procedure ongoing */
468       pFlash.ProcedureOnGoing = 0U;
469     }
470 
471     /* FLASH EOP interrupt user callback */
472     HAL_FLASH_EndOfOperationCallback(param);
473   }
474 
475   /* Check FLASH ECC correction flag */
476   if ((*reg_ecccorr & FLASH_ECCR_ECCC) != 0U)
477   {
478     /* Call User callback */
479     HAL_FLASHEx_EccCorrectionCallback();
480 
481     /* Clear ECC correction flag in order to allow new ECC error record */
482     FLASH->ECCCORR |= FLASH_ECCR_ECCC;
483   }
484 
485   if (pFlash.ProcedureOnGoing == 0U)
486   {
487     /* Disable Flash Operation and Error source interrupt */
488 #if defined (FLASH_SR_OBKERR)
489     (*reg_cr) &= ~(FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
490                    FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
491                    FLASH_IT_OBKWERR | FLASH_IT_OPTCHANGEERR);
492 #else
493     (*reg_cr) &= ~(FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
494                    FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OPTCHANGEERR);
495 #endif /* FLASH_SR_OBKERR */
496   }
497 }
498 
499 /**
500   * @brief  FLASH end of operation interrupt callback
501   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
502   *                  Mass Erase: Bank number which has been requested to erase
503   *                  Sectors Erase: Sector which has been erased
504   *                    (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
505   *                  Program: Address which was selected for data program
506   * @retval None
507   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)508 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
509 {
510   /* Prevent unused argument(s) compilation warning */
511   UNUSED(ReturnValue);
512 
513   /* NOTE : This function Should not be modified, when the callback is needed,
514             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
515    */
516 }
517 
518 /**
519   * @brief  FLASH operation error interrupt callback
520   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
521   *                 Mass Erase: Bank number which has been requested to erase
522   *                 Sectors Erase: Sector number which returned an error
523   *                 Program: Address which was selected for data program
524   * @retval None
525   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)526 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
527 {
528   /* Prevent unused argument(s) compilation warning */
529   UNUSED(ReturnValue);
530 
531   /* NOTE : This function Should not be modified, when the callback is needed,
532             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
533    */
534 }
535 
536 /**
537   * @}
538   */
539 
540 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
541   *  @brief    Management functions
542   *
543 @verbatim
544  ===============================================================================
545                       ##### Peripheral Control functions #####
546  ===============================================================================
547     [..]
548     This subsection provides a set of functions allowing to control the FLASH
549     memory operations.
550 
551 @endverbatim
552   * @{
553   */
554 
555 /**
556   * @brief  Unlock the FLASH control registers access
557   * @retval HAL Status
558   */
HAL_FLASH_Unlock(void)559 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
560 {
561   HAL_StatusTypeDef status = HAL_OK;
562 
563   if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
564   {
565     /* Authorize the FLASH Control Register access */
566     WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
567     WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
568 
569     /* Verify Flash CR is unlocked */
570     if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
571     {
572       status = HAL_ERROR;
573     }
574   }
575 
576 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
577   if (status == HAL_OK)
578   {
579     if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
580     {
581       /* Authorize the FLASH Control Register access */
582       WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
583       WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
584 
585       /* verify Flash CR is unlocked */
586       if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
587       {
588         status = HAL_ERROR;
589       }
590     }
591   }
592 #endif /* __ARM_FEATURE_CMSE */
593 
594   return status;
595 }
596 
597 /**
598   * @brief  Locks the FLASH control registers access
599   * @retval HAL Status
600   */
HAL_FLASH_Lock(void)601 HAL_StatusTypeDef HAL_FLASH_Lock(void)
602 {
603   HAL_StatusTypeDef status = HAL_OK;
604 
605   /* Set the LOCK Bit to lock the FLASH Control Register access */
606   SET_BIT(FLASH->NSCR, FLASH_CR_LOCK);
607 
608   /* Verify Flash is locked */
609   if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) == 0U)
610   {
611     status = HAL_ERROR;
612   }
613 
614 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
615   if (status == HAL_OK)
616   {
617     /* Set the LOCK Bit to lock the FLASH Control Register access */
618     SET_BIT(FLASH->SECCR, FLASH_CR_LOCK);
619 
620     /* verify Flash is locked */
621     if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) == 0U)
622     {
623       status = HAL_ERROR;
624     }
625   }
626 #endif /* __ARM_FEATURE_CMSE */
627 
628   return status;
629 }
630 
631 /**
632   * @brief  Unlock the FLASH Option Control Registers access.
633   * @retval HAL Status
634   */
HAL_FLASH_OB_Unlock(void)635 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
636 {
637   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
638   {
639     /* Authorizes the Option Byte registers programming */
640     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
641     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
642 
643     /* Verify that the Option Bytes are unlocked */
644     if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
645     {
646       return HAL_ERROR;
647     }
648   }
649 
650   return HAL_OK;
651 }
652 
653 /**
654   * @brief  Lock the FLASH Option Control Registers access.
655   * @retval HAL Status
656   */
HAL_FLASH_OB_Lock(void)657 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
658 {
659   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
660   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
661 
662   /* Verify that the Option Bytes are locked */
663   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
664   {
665     return HAL_OK;
666   }
667 
668   return HAL_ERROR;
669 }
670 
671 /**
672   * @brief  Launch the option bytes loading.
673   * @retval HAL Status
674   */
HAL_FLASH_OB_Launch(void)675 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
676 {
677   HAL_StatusTypeDef status;
678 
679   /* Set OPTSTRT Bit */
680   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
681 
682   /* Wait for OB change operation to be completed */
683   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
684 
685   return status;
686 }
687 
688 /**
689   * @}
690   */
691 
692 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
693   *  @brief   Peripheral Errors functions
694   *
695 @verbatim
696  ===============================================================================
697                 ##### Peripheral Errors functions #####
698  ===============================================================================
699     [..]
700     This subsection permits to get in run-time Errors of the FLASH peripheral.
701 
702 @endverbatim
703   * @{
704   */
705 
706 /**
707   * @brief  Get the specific FLASH error flag.
708   * @retval HAL_FLASH_ERRORCode The returned value can be:
709   *            @arg HAL_FLASH_ERROR_NONE  : No error set
710   *            @arg HAL_FLASH_ERROR_WRP   : Write Protection Error
711   *            @arg HAL_FLASH_ERROR_PGS   : Program Sequence Error
712   *            @arg HAL_FLASH_ERROR_STRB  : Strobe Error
713   *            @arg HAL_FLASH_ERROR_INC   : Inconsistency Error
714   *            @arg HAL_FLASH_ERROR_OBK   : OBK Error
715   *            @arg HAL_FLASH_ERROR_OBKW  : OBK Write Error
716   *            @arg HAL_FLASH_ERROR_OB_CHANGE : Option Byte Change Error
717   *            @arg HAL_FLASH_ERROR_ECCC  : ECC Single Correction Error
718   *            @arg HAL_FLASH_ERROR_ECCD  : ECC Double Detection Error
719   */
HAL_FLASH_GetError(void)720 uint32_t HAL_FLASH_GetError(void)
721 {
722   return pFlash.ErrorCode;
723 }
724 
725 /**
726   * @}
727   */
728 
729 /**
730   * @}
731   */
732 
733 /* Private functions ---------------------------------------------------------*/
734 
735 /** @addtogroup FLASH_Private_Functions
736   * @{
737   */
738 
739 /**
740   * @brief  Wait for a FLASH operation to complete.
741   * @param  Timeout maximum flash operation timeout
742   * @retval HAL_StatusTypeDef HAL Status
743   */
FLASH_WaitForLastOperation(uint32_t Timeout)744 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
745 {
746   /* Wait for the FLASH operation to complete by polling on BUSY, WBNE and DBNE flags to be reset.
747      Even if the FLASH operation fails, the BUSY, WBNE and DBNE flags will be reset and an error
748      flag will be set */
749 
750   uint32_t errorflag;
751   const __IO uint32_t *reg_sr;
752   __IO uint32_t *reg_ccr;
753 
754   uint32_t tickstart = HAL_GetTick();
755 
756   /* Access to SR register depends on operation type */
757 #if defined (FLASH_OPTSR2_TZEN)
758   reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
759 #else
760   reg_sr = &(FLASH_NS->NSSR);
761 #endif /* FLASH_OPTSR2_TZEN */
762 
763   /* Wait on BSY, WBNE and DBNE flags to be reset */
764   while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WBNE | FLASH_FLAG_DBNE)) != 0U)
765   {
766     if (Timeout != HAL_MAX_DELAY)
767     {
768       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
769       {
770         return HAL_TIMEOUT;
771       }
772     }
773   }
774 
775   /* Access to CCR register depends on operation type */
776 #if defined (FLASH_OPTSR2_TZEN)
777   reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
778 #else
779   reg_ccr = &(FLASH_NS->NSCCR);
780 #endif /* FLASH_OPTSR2_TZEN */
781 
782   /* Check FLASH operation error flags */
783   errorflag = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
784   /* Add option byte error flag, if any */
785 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
786   errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
787 #endif /* __ARM_FEATURE_CMSE */
788 
789   /* In case of error reported in Flash SR or OPTSR registers */
790   if (errorflag != 0U)
791   {
792     /*Save the error code*/
793     pFlash.ErrorCode |= errorflag;
794 
795     /* Clear error flags */
796     (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
797 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
798     if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
799     {
800       FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
801     }
802 #endif /* __ARM_FEATURE_CMSE */
803 
804     return HAL_ERROR;
805   }
806 
807   /* Check FLASH End of Operation flag  */
808   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
809   {
810     /* Clear FLASH End of Operation pending bit */
811     (*reg_ccr) = FLASH_FLAG_EOP;
812   }
813 
814   /* If there is no error flag set */
815   return HAL_OK;
816 }
817 
818 /**
819   * @brief  Program a quad-word (128-bit) at a specified address.
820   * @param  FlashAddress specifies the address to be programmed.
821   * @param  DataAddress specifies the address of data to be programmed.
822   * @retval None
823   */
FLASH_Program_QuadWord(uint32_t FlashAddress,uint32_t DataAddress)824 static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress)
825 {
826   uint8_t index = 4;
827   uint32_t *dest_addr = (uint32_t *)FlashAddress;
828   uint32_t *src_addr  = (uint32_t *)DataAddress;
829   uint32_t primask_bit;
830   __IO uint32_t *reg_cr;
831 
832   /* Access to SECCR or NSCR registers depends on operation type */
833 #if defined (FLASH_OPTSR2_TZEN)
834   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
835 #else
836   reg_cr = &(FLASH_NS->NSCR);
837 #endif /* FLASH_OPTSR2_TZEN */
838 
839   /* Set PG bit */
840   SET_BIT((*reg_cr), FLASH_CR_PG);
841 
842   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
843   primask_bit = __get_PRIMASK();
844   __disable_irq();
845 
846   /* Program the quad-word */
847   do
848   {
849     *dest_addr = *src_addr;
850     dest_addr++;
851     src_addr++;
852     index--;
853   } while (index != 0U);
854 
855   /* Exit critical section: restore previous priority mask */
856   __set_PRIMASK(primask_bit);
857 }
858 
859 #if defined (FLASH_SR_OBKERR)
860 /**
861   * @brief  Program a quad-word (128-bit) of OBK at a specified address.
862   * @param  FlashAddress specifies the address to be programmed.
863   * @param  DataAddress specifies the address of data to be programmed.
864   * @retval None
865   */
FLASH_Program_QuadWord_OBK(uint32_t FlashAddress,uint32_t DataAddress)866 static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress)
867 {
868   uint8_t index = 4;
869   uint32_t *dest_addr = (uint32_t *)FlashAddress;
870   uint32_t *src_addr  = (uint32_t *)DataAddress;
871   uint32_t primask_bit;
872   __IO uint32_t *reg_cr;
873   __IO uint32_t *reg_obkcfgr;
874 
875   /* Access to SECCR or NSCR registers depends on operation type */
876   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
877   reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
878 
879   /* Set PG bit */
880   SET_BIT((*reg_cr), FLASH_CR_PG);
881 
882   /* Set ALT_SECT bit */
883   SET_BIT((*reg_obkcfgr), pFlash.ProcedureOnGoing & FLASH_OBKCFGR_ALT_SECT);
884 
885   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
886   primask_bit = __get_PRIMASK();
887   __disable_irq();
888 
889   /* Program the quad-word */
890   do
891   {
892     *dest_addr = *src_addr;
893     dest_addr++;
894     src_addr++;
895     index--;
896   } while (index != 0U);
897 
898   /* Exit critical section: restore previous priority mask */
899   __set_PRIMASK(primask_bit);
900 }
901 #endif /* FLASH_SR_OBKERR */
902 
903 /**
904   * @brief  Program a half-word (16-bit) at a specified address.
905   * @param  FlashAddress specifies the address to be programmed.
906   * @param  DataAddress specifies the address of data to be programmed.
907   * @retval None
908   */
FLASH_Program_HalfWord(uint32_t FlashAddress,uint32_t DataAddress)909 static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress)
910 {
911   __IO uint32_t *reg_cr;
912 
913   /* Access to SECCR or NSCR registers depends on operation type */
914 #if defined (FLASH_OPTSR2_TZEN)
915   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
916 #else
917   reg_cr = &(FLASH_NS->NSCR);
918 #endif /* FLASH_OPTSR2_TZEN */
919 
920   /* Set HalfWord_PG bit */
921   SET_BIT((*reg_cr), FLASH_CR_PG);
922 
923   /* Program a halfword word (16 bits) */
924   *(__IO uint16_t *)FlashAddress = *(__IO uint16_t *)DataAddress;
925 }
926 
927 #if defined(FLASH_EDATAR_EDATA_EN)
928 /**
929   * @brief  Program a word (32-bit) at a specified address.
930   * @param  FlashAddress specifies the address to be programmed.
931   * @param  DataAddress specifies the address of data to be programmed.
932   * @retval None
933   */
FLASH_Program_Word(uint32_t FlashAddress,uint32_t DataAddress)934 static void FLASH_Program_Word(uint32_t FlashAddress, uint32_t DataAddress)
935 {
936   __IO uint32_t *reg_cr;
937 
938   /* Access to SECCR or NSCR registers depends on operation type */
939 #if defined (FLASH_OPTSR2_TZEN)
940   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
941 #else
942   reg_cr = &(FLASH_NS->NSCR);
943 #endif /* FLASH_OPTSR2_TZEN */
944 
945   /* Set PG bit */
946   SET_BIT((*reg_cr), FLASH_CR_PG);
947 
948     *(__IO uint32_t *)FlashAddress = *(__IO uint32_t *)DataAddress;
949 }
950 #endif /* FLASH_EDATAR_EDATA_EN */
951 
952 /**
953   * @}
954   */
955 
956 #endif /* HAL_FLASH_MODULE_ENABLED */
957 
958 /**
959   * @}
960   */
961 
962 /**
963   * @}
964   */
965