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