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