Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32f1xx_hal_flash.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f1xx_hal_flash.c 00004 * @author MCD Application Team 00005 * @version V1.0.4 00006 * @date 29-April-2016 00007 * @brief FLASH HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the internal FLASH memory: 00010 * + Program operations functions 00011 * + Memory Control functions 00012 * + Peripheral State functions 00013 * 00014 @verbatim 00015 ============================================================================== 00016 ##### FLASH peripheral features ##### 00017 ============================================================================== 00018 [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses 00019 to the Flash memory. It implements the erase and program Flash memory operations 00020 and the read and write protection mechanisms. 00021 00022 [..] The Flash memory interface accelerates code execution with a system of instruction 00023 prefetch. 00024 00025 [..] The FLASH main features are: 00026 (+) Flash memory read operations 00027 (+) Flash memory program/erase operations 00028 (+) Read / write protections 00029 (+) Prefetch on I-Code 00030 (+) Option Bytes programming 00031 00032 00033 ##### How to use this driver ##### 00034 ============================================================================== 00035 [..] 00036 This driver provides functions and macros to configure and program the FLASH 00037 memory of all STM32F1xx devices. 00038 00039 (#) FLASH Memory I/O Programming functions: this group includes all needed 00040 functions to erase and program the main memory: 00041 (++) Lock and Unlock the FLASH interface 00042 (++) Erase function: Erase page, erase all pages 00043 (++) Program functions: half word, word and doubleword 00044 00045 (#) FLASH Option Bytes Programming functions: this group includes all needed 00046 functions to manage the Option Bytes: 00047 (++) Lock and Unlock the Option Bytes 00048 (++) Set/Reset the write protection 00049 (++) Set the Read protection Level 00050 (++) Program the user Option Bytes 00051 (++) Launch the Option Bytes loader 00052 (++) Erase Option Bytes 00053 (++) Program the data Option Bytes 00054 (++) Get the Write protection. 00055 (++) Get the user option bytes. 00056 00057 (#) Interrupts and flags management functions : this group 00058 includes all needed functions to: 00059 (++) Handle FLASH interrupts 00060 (++) Wait for last FLASH operation according to its status 00061 (++) Get error flag status 00062 00063 [..] In addition to these function, this driver includes a set of macros allowing 00064 to handle the following operations: 00065 00066 (+) Set/Get the latency 00067 (+) Enable/Disable the prefetch buffer 00068 (+) Enable/Disable the half cycle access 00069 (+) Enable/Disable the FLASH interrupts 00070 (+) Monitor the FLASH flags status 00071 00072 @endverbatim 00073 ****************************************************************************** 00074 * @attention 00075 * 00076 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00077 * 00078 * Redistribution and use in source and binary forms, with or without modification, 00079 * are permitted provided that the following conditions are met: 00080 * 1. Redistributions of source code must retain the above copyright notice, 00081 * this list of conditions and the following disclaimer. 00082 * 2. Redistributions in binary form must reproduce the above copyright notice, 00083 * this list of conditions and the following disclaimer in the documentation 00084 * and/or other materials provided with the distribution. 00085 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00086 * may be used to endorse or promote products derived from this software 00087 * without specific prior written permission. 00088 * 00089 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00090 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00091 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00092 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00093 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00094 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00095 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00096 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00097 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00098 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00099 * 00100 ****************************************************************************** 00101 */ 00102 00103 /* Includes ------------------------------------------------------------------*/ 00104 #include "stm32f1xx_hal.h" 00105 00106 /** @addtogroup STM32F1xx_HAL_Driver 00107 * @{ 00108 */ 00109 00110 #ifdef HAL_FLASH_MODULE_ENABLED 00111 00112 /** @defgroup FLASH FLASH 00113 * @brief FLASH HAL module driver 00114 * @{ 00115 */ 00116 00117 /* Private typedef -----------------------------------------------------------*/ 00118 /* Private define ------------------------------------------------------------*/ 00119 /** @defgroup FLASH_Private_Constants FLASH Private Constants 00120 * @{ 00121 */ 00122 /** 00123 * @} 00124 */ 00125 00126 /* Private macro ---------------------------- ---------------------------------*/ 00127 /** @defgroup FLASH_Private_Macros FLASH Private Macros 00128 * @{ 00129 */ 00130 00131 /** 00132 * @} 00133 */ 00134 00135 /* Private variables ---------------------------------------------------------*/ 00136 /** @defgroup FLASH_Private_Variables FLASH Private Variables 00137 * @{ 00138 */ 00139 /* Variables used for Erase pages under interruption*/ 00140 FLASH_ProcessTypeDef pFlash; 00141 /** 00142 * @} 00143 */ 00144 00145 /* Private function prototypes -----------------------------------------------*/ 00146 /** @defgroup FLASH_Private_Functions FLASH Private Functions 00147 * @{ 00148 */ 00149 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data); 00150 static void FLASH_SetErrorCode(void); 00151 /** 00152 * @} 00153 */ 00154 00155 /* Exported functions ---------------------------------------------------------*/ 00156 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions 00157 * @{ 00158 */ 00159 00160 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions 00161 * @brief Programming operation functions 00162 * 00163 @verbatim 00164 @endverbatim 00165 * @{ 00166 */ 00167 00168 /** 00169 * @brief Program halfword, word or double word at a specified address 00170 * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface 00171 * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface 00172 * 00173 * @note If an erase and a program operations are requested simultaneously, 00174 * the erase operation is performed before the program one. 00175 * 00176 * @note FLASH should be previously erased before new programmation (only exception to this 00177 * is when 0x0000 is programmed) 00178 * 00179 * @param TypeProgram: Indicate the way to program at a specified address. 00180 * This parameter can be a value of @ref FLASH_Type_Program 00181 * @param Address: Specifies the address to be programmed. 00182 * @param Data: Specifies the data to be programmed 00183 * 00184 * @retval HAL_StatusTypeDef HAL Status 00185 */ 00186 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) 00187 { 00188 HAL_StatusTypeDef status = HAL_ERROR; 00189 uint8_t index = 0; 00190 uint8_t nbiterations = 0; 00191 00192 /* Process Locked */ 00193 __HAL_LOCK(&pFlash); 00194 00195 /* Check the parameters */ 00196 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); 00197 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); 00198 00199 #if defined(FLASH_BANK2_END) 00200 if(Address <= FLASH_BANK1_END) 00201 { 00202 #endif /* FLASH_BANK2_END */ 00203 /* Wait for last operation to be completed */ 00204 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00205 #if defined(FLASH_BANK2_END) 00206 } 00207 else 00208 { 00209 /* Wait for last operation to be completed */ 00210 status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); 00211 } 00212 #endif /* FLASH_BANK2_END */ 00213 00214 if(status == HAL_OK) 00215 { 00216 if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) 00217 { 00218 /* Program halfword (16-bit) at a specified address. */ 00219 nbiterations = 1; 00220 } 00221 else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) 00222 { 00223 /* Program word (32-bit = 2*16-bit) at a specified address. */ 00224 nbiterations = 2; 00225 } 00226 else 00227 { 00228 /* Program double word (64-bit = 4*16-bit) at a specified address. */ 00229 nbiterations = 4; 00230 } 00231 00232 for (index = 0; index < nbiterations; index++) 00233 { 00234 FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index))); 00235 00236 #if defined(FLASH_BANK2_END) 00237 if(Address <= FLASH_BANK1_END) 00238 { 00239 #endif /* FLASH_BANK2_END */ 00240 /* Wait for last operation to be completed */ 00241 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00242 00243 /* If the program operation is completed, disable the PG Bit */ 00244 CLEAR_BIT(FLASH->CR, FLASH_CR_PG); 00245 #if defined(FLASH_BANK2_END) 00246 } 00247 else 00248 { 00249 /* Wait for last operation to be completed */ 00250 status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); 00251 00252 /* If the program operation is completed, disable the PG Bit */ 00253 CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG); 00254 } 00255 #endif /* FLASH_BANK2_END */ 00256 /* In case of error, stop programation procedure */ 00257 if (status != HAL_OK) 00258 { 00259 break; 00260 } 00261 } 00262 } 00263 00264 /* Process Unlocked */ 00265 __HAL_UNLOCK(&pFlash); 00266 00267 return status; 00268 } 00269 00270 /** 00271 * @brief Program halfword, word or double word at a specified address with interrupt enabled. 00272 * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface 00273 * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface 00274 * 00275 * @note If an erase and a program operations are requested simultaneously, 00276 * the erase operation is performed before the program one. 00277 * 00278 * @param TypeProgram: Indicate the way to program at a specified address. 00279 * This parameter can be a value of @ref FLASH_Type_Program 00280 * @param Address: Specifies the address to be programmed. 00281 * @param Data: Specifies the data to be programmed 00282 * 00283 * @retval HAL_StatusTypeDef HAL Status 00284 */ 00285 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data) 00286 { 00287 HAL_StatusTypeDef status = HAL_OK; 00288 00289 /* Process Locked */ 00290 __HAL_LOCK(&pFlash); 00291 00292 /* Check the parameters */ 00293 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); 00294 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); 00295 00296 #if defined(FLASH_BANK2_END) 00297 /* If procedure already ongoing, reject the next one */ 00298 if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) 00299 { 00300 return HAL_ERROR; 00301 } 00302 00303 if(Address <= FLASH_BANK1_END) 00304 { 00305 /* Enable End of FLASH Operation and Error source interrupts */ 00306 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1); 00307 00308 }else 00309 { 00310 /* Enable End of FLASH Operation and Error source interrupts */ 00311 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2); 00312 } 00313 #else 00314 /* Enable End of FLASH Operation and Error source interrupts */ 00315 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); 00316 #endif /* FLASH_BANK2_END */ 00317 00318 pFlash.Address = Address; 00319 pFlash.Data = Data; 00320 00321 if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) 00322 { 00323 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD; 00324 /*Program halfword (16-bit) at a specified address.*/ 00325 pFlash.DataRemaining = 1; 00326 } 00327 else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) 00328 { 00329 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD; 00330 /*Program word (32-bit : 2*16-bit) at a specified address.*/ 00331 pFlash.DataRemaining = 2; 00332 } 00333 else 00334 { 00335 pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD; 00336 /*Program double word (64-bit : 4*16-bit) at a specified address.*/ 00337 pFlash.DataRemaining = 4; 00338 } 00339 00340 /*Program halfword (16-bit) at a specified address.*/ 00341 FLASH_Program_HalfWord(Address, (uint16_t)Data); 00342 00343 return status; 00344 } 00345 00346 /** 00347 * @brief This function handles FLASH interrupt request. 00348 * @retval None 00349 */ 00350 void HAL_FLASH_IRQHandler(void) 00351 { 00352 uint32_t addresstmp = 0; 00353 00354 /* Check FLASH operation error flags */ 00355 #if defined(FLASH_BANK2_END) 00356 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \ 00357 (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))) 00358 #else 00359 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) 00360 #endif /* FLASH_BANK2_END */ 00361 { 00362 /*return the faulty address*/ 00363 addresstmp = pFlash.Address; 00364 /* Reset address */ 00365 pFlash.Address = 0xFFFFFFFF; 00366 00367 /*Save the Error code*/ 00368 FLASH_SetErrorCode(); 00369 00370 /* FLASH error interrupt user callback */ 00371 HAL_FLASH_OperationErrorCallback(addresstmp); 00372 00373 /* Stop the procedure ongoing*/ 00374 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00375 } 00376 00377 /* Check FLASH End of Operation flag */ 00378 #if defined(FLASH_BANK2_END) 00379 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1)) 00380 { 00381 /* Clear FLASH End of Operation pending bit */ 00382 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1); 00383 #else 00384 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) 00385 { 00386 /* Clear FLASH End of Operation pending bit */ 00387 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); 00388 #endif /* FLASH_BANK2_END */ 00389 00390 /* Process can continue only if no error detected */ 00391 if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) 00392 { 00393 if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) 00394 { 00395 /* Nb of pages to erased can be decreased */ 00396 pFlash.DataRemaining--; 00397 00398 /* Check if there are still pages to erase*/ 00399 if(pFlash.DataRemaining != 0) 00400 { 00401 addresstmp = pFlash.Address; 00402 /*Indicate user which sector has been erased*/ 00403 HAL_FLASH_EndOfOperationCallback(addresstmp); 00404 00405 /*Increment sector number*/ 00406 addresstmp = pFlash.Address + FLASH_PAGE_SIZE; 00407 pFlash.Address = addresstmp; 00408 00409 /* If the erase operation is completed, disable the PER Bit */ 00410 CLEAR_BIT(FLASH->CR, FLASH_CR_PER); 00411 00412 FLASH_PageErase(addresstmp); 00413 } 00414 else 00415 { 00416 /*No more pages to Erase, user callback can be called.*/ 00417 /*Reset Sector and stop Erase pages procedure*/ 00418 pFlash.Address = addresstmp = 0xFFFFFFFF; 00419 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00420 /* FLASH EOP interrupt user callback */ 00421 HAL_FLASH_EndOfOperationCallback(addresstmp); 00422 } 00423 } 00424 else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) 00425 { 00426 /* Operation is completed, disable the MER Bit */ 00427 CLEAR_BIT(FLASH->CR, FLASH_CR_MER); 00428 00429 #if defined(FLASH_BANK2_END) 00430 /* Stop Mass Erase procedure if no pending mass erase on other bank */ 00431 if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER)) 00432 { 00433 #endif /* FLASH_BANK2_END */ 00434 /* MassErase ended. Return the selected bank*/ 00435 /* FLASH EOP interrupt user callback */ 00436 HAL_FLASH_EndOfOperationCallback(0); 00437 00438 /* Stop Mass Erase procedure*/ 00439 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00440 } 00441 #if defined(FLASH_BANK2_END) 00442 } 00443 #endif /* FLASH_BANK2_END */ 00444 else 00445 { 00446 /* Nb of 16-bit data to program can be decreased */ 00447 pFlash.DataRemaining--; 00448 00449 /* Check if there are still 16-bit data to program */ 00450 if(pFlash.DataRemaining != 0) 00451 { 00452 /* Increment address to 16-bit */ 00453 pFlash.Address += 2; 00454 addresstmp = pFlash.Address; 00455 00456 /* Shift to have next 16-bit data */ 00457 pFlash.Data = (pFlash.Data >> 16); 00458 00459 /* Operation is completed, disable the PG Bit */ 00460 CLEAR_BIT(FLASH->CR, FLASH_CR_PG); 00461 00462 /*Program halfword (16-bit) at a specified address.*/ 00463 FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data); 00464 } 00465 else 00466 { 00467 /*Program ended. Return the selected address*/ 00468 /* FLASH EOP interrupt user callback */ 00469 if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD) 00470 { 00471 HAL_FLASH_EndOfOperationCallback(pFlash.Address); 00472 } 00473 else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD) 00474 { 00475 HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2); 00476 } 00477 else 00478 { 00479 HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6); 00480 } 00481 00482 /* Reset Address and stop Program procedure*/ 00483 pFlash.Address = 0xFFFFFFFF; 00484 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00485 } 00486 } 00487 } 00488 } 00489 00490 #if defined(FLASH_BANK2_END) 00491 /* Check FLASH End of Operation flag */ 00492 if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2)) 00493 { 00494 /* Clear FLASH End of Operation pending bit */ 00495 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2); 00496 00497 /* Process can continue only if no error detected */ 00498 if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) 00499 { 00500 if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) 00501 { 00502 /* Nb of pages to erased can be decreased */ 00503 pFlash.DataRemaining--; 00504 00505 /* Check if there are still pages to erase*/ 00506 if(pFlash.DataRemaining != 0) 00507 { 00508 /* Indicate user which page address has been erased*/ 00509 HAL_FLASH_EndOfOperationCallback(pFlash.Address); 00510 00511 /* Increment page address to next page */ 00512 pFlash.Address += FLASH_PAGE_SIZE; 00513 addresstmp = pFlash.Address; 00514 00515 /* Operation is completed, disable the PER Bit */ 00516 CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER); 00517 00518 FLASH_PageErase(addresstmp); 00519 } 00520 else 00521 { 00522 /*No more pages to Erase*/ 00523 00524 /*Reset Address and stop Erase pages procedure*/ 00525 pFlash.Address = 0xFFFFFFFF; 00526 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00527 00528 /* FLASH EOP interrupt user callback */ 00529 HAL_FLASH_EndOfOperationCallback(pFlash.Address); 00530 } 00531 } 00532 else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) 00533 { 00534 /* Operation is completed, disable the MER Bit */ 00535 CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); 00536 00537 if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER)) 00538 { 00539 /* MassErase ended. Return the selected bank*/ 00540 /* FLASH EOP interrupt user callback */ 00541 HAL_FLASH_EndOfOperationCallback(0); 00542 00543 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00544 } 00545 } 00546 else 00547 { 00548 /* Nb of 16-bit data to program can be decreased */ 00549 pFlash.DataRemaining--; 00550 00551 /* Check if there are still 16-bit data to program */ 00552 if(pFlash.DataRemaining != 0) 00553 { 00554 /* Increment address to 16-bit */ 00555 pFlash.Address += 2; 00556 addresstmp = pFlash.Address; 00557 00558 /* Shift to have next 16-bit data */ 00559 pFlash.Data = (pFlash.Data >> 16); 00560 00561 /* Operation is completed, disable the PG Bit */ 00562 CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG); 00563 00564 /*Program halfword (16-bit) at a specified address.*/ 00565 FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data); 00566 } 00567 else 00568 { 00569 /*Program ended. Return the selected address*/ 00570 /* FLASH EOP interrupt user callback */ 00571 if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD) 00572 { 00573 HAL_FLASH_EndOfOperationCallback(pFlash.Address); 00574 } 00575 else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD) 00576 { 00577 HAL_FLASH_EndOfOperationCallback(pFlash.Address-2); 00578 } 00579 else 00580 { 00581 HAL_FLASH_EndOfOperationCallback(pFlash.Address-6); 00582 } 00583 00584 /* Reset Address and stop Program procedure*/ 00585 pFlash.Address = 0xFFFFFFFF; 00586 pFlash.ProcedureOnGoing = FLASH_PROC_NONE; 00587 } 00588 } 00589 } 00590 } 00591 #endif 00592 00593 if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) 00594 { 00595 #if defined(FLASH_BANK2_END) 00596 /* Operation is completed, disable the PG, PER and MER Bits for both bank */ 00597 CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER)); 00598 CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER)); 00599 00600 /* Disable End of FLASH Operation and Error source interrupts for both banks */ 00601 __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2); 00602 #else 00603 /* Operation is completed, disable the PG, PER and MER Bits */ 00604 CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER)); 00605 00606 /* Disable End of FLASH Operation and Error source interrupts */ 00607 __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); 00608 #endif /* FLASH_BANK2_END */ 00609 00610 /* Process Unlocked */ 00611 __HAL_UNLOCK(&pFlash); 00612 } 00613 } 00614 00615 00616 /** 00617 * @brief FLASH end of operation interrupt callback 00618 * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure 00619 * - Mass Erase: No return value expected 00620 * - Pages Erase: Address of the page which has been erased 00621 * (if 0xFFFFFFFF, it means that all the selected pages have been erased) 00622 * - Program: Address which was selected for data program 00623 * @retval none 00624 */ 00625 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) 00626 { 00627 /* Prevent unused argument(s) compilation warning */ 00628 UNUSED(ReturnValue); 00629 /* NOTE : This function Should not be modified, when the callback is needed, 00630 the HAL_FLASH_EndOfOperationCallback could be implemented in the user file 00631 */ 00632 } 00633 00634 /** 00635 * @brief FLASH operation error interrupt callback 00636 * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure 00637 * - Mass Erase: No return value expected 00638 * - Pages Erase: Address of the page which returned an error 00639 * - Program: Address which was selected for data program 00640 * @retval none 00641 */ 00642 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) 00643 { 00644 /* Prevent unused argument(s) compilation warning */ 00645 UNUSED(ReturnValue); 00646 /* NOTE : This function Should not be modified, when the callback is needed, 00647 the HAL_FLASH_OperationErrorCallback could be implemented in the user file 00648 */ 00649 } 00650 00651 /** 00652 * @} 00653 */ 00654 00655 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions 00656 * @brief management functions 00657 * 00658 @verbatim 00659 =============================================================================== 00660 ##### Peripheral Control functions ##### 00661 =============================================================================== 00662 [..] 00663 This subsection provides a set of functions allowing to control the FLASH 00664 memory operations. 00665 00666 @endverbatim 00667 * @{ 00668 */ 00669 00670 /** 00671 * @brief Unlock the FLASH control register access 00672 * @retval HAL Status 00673 */ 00674 HAL_StatusTypeDef HAL_FLASH_Unlock(void) 00675 { 00676 if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK)) 00677 { 00678 /* Authorize the FLASH Registers access */ 00679 WRITE_REG(FLASH->KEYR, FLASH_KEY1); 00680 WRITE_REG(FLASH->KEYR, FLASH_KEY2); 00681 } 00682 else 00683 { 00684 return HAL_ERROR; 00685 } 00686 00687 #if defined(FLASH_BANK2_END) 00688 if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK)) 00689 { 00690 /* Authorize the FLASH BANK2 Registers access */ 00691 WRITE_REG(FLASH->KEYR2, FLASH_KEY1); 00692 WRITE_REG(FLASH->KEYR2, FLASH_KEY2); 00693 } 00694 else 00695 { 00696 return HAL_ERROR; 00697 } 00698 00699 #endif /* FLASH_BANK2_END */ 00700 return HAL_OK; 00701 } 00702 00703 /** 00704 * @brief Locks the FLASH control register access 00705 * @retval HAL Status 00706 */ 00707 HAL_StatusTypeDef HAL_FLASH_Lock(void) 00708 { 00709 /* Set the LOCK Bit to lock the FLASH Registers access */ 00710 SET_BIT(FLASH->CR, FLASH_CR_LOCK); 00711 00712 #if defined(FLASH_BANK2_END) 00713 /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */ 00714 SET_BIT(FLASH->CR2, FLASH_CR2_LOCK); 00715 #endif /* FLASH_BANK2_END */ 00716 00717 return HAL_OK; 00718 } 00719 00720 00721 /** 00722 * @brief Unlock the FLASH Option Control Registers access. 00723 * @retval HAL Status 00724 */ 00725 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void) 00726 { 00727 if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE)) 00728 { 00729 /* Authorizes the Option Byte register programming */ 00730 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1); 00731 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2); 00732 } 00733 else 00734 { 00735 return HAL_ERROR; 00736 } 00737 00738 return HAL_OK; 00739 } 00740 00741 /** 00742 * @brief Lock the FLASH Option Control Registers access. 00743 * @retval HAL Status 00744 */ 00745 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void) 00746 { 00747 /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */ 00748 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE); 00749 00750 return HAL_OK; 00751 } 00752 00753 /** 00754 * @brief Launch the option byte loading. 00755 * @note This function will reset automatically the MCU. 00756 * @retval HAL_StatusTypeDef HAL Status 00757 */ 00758 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) 00759 { 00760 /* Initiates a system reset request to launch the option byte loading */ 00761 HAL_NVIC_SystemReset(); 00762 00763 return HAL_OK; 00764 } 00765 00766 /** 00767 * @} 00768 */ 00769 00770 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State functions 00771 * @brief Peripheral State functions 00772 * 00773 @verbatim 00774 =============================================================================== 00775 ##### Peripheral State functions ##### 00776 =============================================================================== 00777 [..] 00778 This subsection permit to get in run-time the status of the FLASH peripheral. 00779 00780 @endverbatim 00781 * @{ 00782 */ 00783 00784 /** 00785 * @brief Get the specific FLASH error flag. 00786 * @retval FLASH_ErrorCode: The returned value can be: 00787 * @ref FLASH_Error_Codes 00788 */ 00789 uint32_t HAL_FLASH_GetError(void) 00790 { 00791 return pFlash.ErrorCode; 00792 } 00793 /** 00794 * @} 00795 */ 00796 00797 /** 00798 * @} 00799 */ 00800 00801 /** @addtogroup FLASH_Private_Functions 00802 * @{ 00803 */ 00804 00805 /** 00806 * @brief Program a half-word (16-bit) at a specified address. 00807 * @param Address: specifies the address to be programmed. 00808 * @param Data: specifies the data to be programmed. 00809 * @retval None 00810 */ 00811 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) 00812 { 00813 /* Clean the error context */ 00814 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00815 00816 #if defined(FLASH_BANK2_END) 00817 if(Address <= FLASH_BANK1_END) 00818 { 00819 #endif /* FLASH_BANK2_END */ 00820 /* Proceed to program the new data */ 00821 SET_BIT(FLASH->CR, FLASH_CR_PG); 00822 #if defined(FLASH_BANK2_END) 00823 } 00824 else 00825 { 00826 /* Proceed to program the new data */ 00827 SET_BIT(FLASH->CR2, FLASH_CR2_PG); 00828 } 00829 #endif /* FLASH_BANK2_END */ 00830 00831 /* Write data in the address */ 00832 *(__IO uint16_t*)Address = Data; 00833 } 00834 00835 /** 00836 * @brief Wait for a FLASH operation to complete. 00837 * @param Timeout: maximum flash operation timeout 00838 * @retval HAL_StatusTypeDef HAL Status 00839 */ 00840 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) 00841 { 00842 /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. 00843 Even if the FLASH operation fails, the BUSY flag will be reset and an error 00844 flag will be set */ 00845 00846 uint32_t tickstart = HAL_GetTick(); 00847 00848 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) 00849 { 00850 if (Timeout != HAL_MAX_DELAY) 00851 { 00852 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) 00853 { 00854 return HAL_TIMEOUT; 00855 } 00856 } 00857 } 00858 00859 /* Check FLASH End of Operation flag */ 00860 if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) 00861 { 00862 /* Clear FLASH End of Operation pending bit */ 00863 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); 00864 } 00865 00866 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || 00867 __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || 00868 __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) 00869 { 00870 /*Save the error code*/ 00871 FLASH_SetErrorCode(); 00872 return HAL_ERROR; 00873 } 00874 00875 /* If there is no error flag set */ 00876 return HAL_OK; 00877 } 00878 00879 #if defined(FLASH_BANK2_END) 00880 /** 00881 * @brief Wait for a FLASH BANK2 operation to complete. 00882 * @param Timeout: maximum flash operation timeout 00883 * @retval HAL_StatusTypeDef HAL Status 00884 */ 00885 HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout) 00886 { 00887 /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset. 00888 Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error 00889 flag will be set */ 00890 00891 uint32_t tickstart = HAL_GetTick(); 00892 00893 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2)) 00894 { 00895 if (Timeout != HAL_MAX_DELAY) 00896 { 00897 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) 00898 { 00899 return HAL_TIMEOUT; 00900 } 00901 } 00902 } 00903 00904 /* Check FLASH End of Operation flag */ 00905 if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2)) 00906 { 00907 /* Clear FLASH End of Operation pending bit */ 00908 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2); 00909 } 00910 00911 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)) 00912 { 00913 /*Save the error code*/ 00914 FLASH_SetErrorCode(); 00915 return HAL_ERROR; 00916 } 00917 00918 /* If there is an error flag set */ 00919 return HAL_OK; 00920 00921 } 00922 #endif /* FLASH_BANK2_END */ 00923 00924 /** 00925 * @brief Set the specific FLASH error flag. 00926 * @retval None 00927 */ 00928 static void FLASH_SetErrorCode(void) 00929 { 00930 #if defined(FLASH_BANK2_END) 00931 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2)) 00932 #else 00933 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) 00934 #endif /* FLASH_BANK2_END */ 00935 { 00936 pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; 00937 } 00938 #if defined(FLASH_BANK2_END) 00939 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)) 00940 #else 00941 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) 00942 #endif /* FLASH_BANK2_END */ 00943 { 00944 pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG; 00945 } 00946 00947 if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) 00948 { 00949 pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV; 00950 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); 00951 } 00952 00953 /* Clear FLASH error pending bits */ 00954 #if defined(FLASH_BANK2_END) 00955 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2); 00956 #else 00957 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR); 00958 #endif /* FLASH_BANK2_END */ 00959 } 00960 /** 00961 * @} 00962 */ 00963 00964 /** 00965 * @} 00966 */ 00967 00968 #endif /* HAL_FLASH_MODULE_ENABLED */ 00969 00970 /** 00971 * @} 00972 */ 00973 00974 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 15:37:23 by
