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