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