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