Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c (29013B)
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 */ 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 */ 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 */ 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
