STM32F103xB HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f1xx_hal_flash_ex.c 00004 * @author MCD Application Team 00005 * @brief Extended FLASH HAL module driver. 00006 * 00007 * This file provides firmware functions to manage the following 00008 * functionalities of the FLASH peripheral: 00009 * + Extended Initialization/de-initialization functions 00010 * + Extended I/O operation functions 00011 * + Extended Peripheral Control functions 00012 * 00013 @verbatim 00014 ============================================================================== 00015 ##### Flash peripheral extended features ##### 00016 ============================================================================== 00017 00018 ##### How to use this driver ##### 00019 ============================================================================== 00020 [..] This driver provides functions to configure and program the FLASH memory 00021 of all STM32F1xxx devices. It includes 00022 00023 (++) Set/Reset the write protection 00024 (++) Program the user Option Bytes 00025 (++) Get the Read protection Level 00026 00027 @endverbatim 00028 ****************************************************************************** 00029 * @attention 00030 * 00031 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00032 * All rights reserved.</center></h2> 00033 * 00034 * This software component is licensed by ST under BSD 3-Clause license, 00035 * the "License"; You may not use this file except in compliance with the 00036 * License. You may obtain a copy of the License at: 00037 * opensource.org/licenses/BSD-3-Clause 00038 * 00039 ****************************************************************************** 00040 */ 00041 00042 /* Includes ------------------------------------------------------------------*/ 00043 #include "stm32f1xx_hal.h" 00044 00045 /** @addtogroup STM32F1xx_HAL_Driver 00046 * @{ 00047 */ 00048 #ifdef HAL_FLASH_MODULE_ENABLED 00049 00050 /** @addtogroup FLASH 00051 * @{ 00052 */ 00053 /** @addtogroup FLASH_Private_Variables 00054 * @{ 00055 */ 00056 /* Variables used for Erase pages under interruption*/ 00057 extern FLASH_ProcessTypeDef pFlash; 00058 /** 00059 * @} 00060 */ 00061 00062 /** 00063 * @} 00064 */ 00065 00066 /** @defgroup FLASHEx FLASHEx 00067 * @brief FLASH HAL Extension module driver 00068 * @{ 00069 */ 00070 00071 /* Private typedef -----------------------------------------------------------*/ 00072 /* Private define ------------------------------------------------------------*/ 00073 /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants 00074 * @{ 00075 */ 00076 #define FLASH_POSITION_IWDGSW_BIT FLASH_OBR_IWDG_SW_Pos 00077 #define FLASH_POSITION_OB_USERDATA0_BIT FLASH_OBR_DATA0_Pos 00078 #define FLASH_POSITION_OB_USERDATA1_BIT FLASH_OBR_DATA1_Pos 00079 /** 00080 * @} 00081 */ 00082 00083 /* Private macro -------------------------------------------------------------*/ 00084 /** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros 00085 * @{ 00086 */ 00087 /** 00088 * @} 00089 */ 00090 00091 /* Private variables ---------------------------------------------------------*/ 00092 /* Private function prototypes -----------------------------------------------*/ 00093 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions 00094 * @{ 00095 */ 00096 /* Erase operations */ 00097 static void FLASH_MassErase(uint32_t Banks); 00098 void FLASH_PageErase(uint32_t PageAddress); 00099 00100 /* Option bytes control */ 00101 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage); 00102 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage); 00103 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel); 00104 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig); 00105 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data); 00106 static uint32_t FLASH_OB_GetWRP(void); 00107 static uint32_t FLASH_OB_GetRDP(void); 00108 static uint8_t FLASH_OB_GetUser(void); 00109 00110 /** 00111 * @} 00112 */ 00113 00114 /* Exported functions ---------------------------------------------------------*/ 00115 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions 00116 * @{ 00117 */ 00118 00119 /** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions 00120 * @brief FLASH Memory Erasing functions 00121 * 00122 @verbatim 00123 ============================================================================== 00124 ##### FLASH Erasing Programming functions ##### 00125 ============================================================================== 00126 00127 [..] The FLASH Memory Erasing functions, includes the following functions: 00128 (+) @ref HAL_FLASHEx_Erase: return only when erase has been done 00129 (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback 00130 is called with parameter 0xFFFFFFFF 00131 00132 [..] Any operation of erase should follow these steps: 00133 (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and 00134 program memory access. 00135 (#) Call the desired function to erase page. 00136 (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access 00137 (recommended to protect the FLASH memory against possible unwanted operation). 00138 00139 @endverbatim 00140 * @{ 00141 */ 00142 00143 00144 /** 00145 * @brief Perform a mass erase or erase the specified FLASH memory pages 00146 * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function 00147 * must be called before. 00148 * Call the @ref HAL_FLASH_Lock() to disable the flash memory access 00149 * (recommended to protect the FLASH memory against possible unwanted operation) 00150 * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that 00151 * contains the configuration information for the erasing. 00152 * 00153 * @param[out] PageError pointer to variable that 00154 * contains the configuration information on faulty page in case of error 00155 * (0xFFFFFFFF means that all the pages have been correctly erased) 00156 * 00157 * @retval HAL_StatusTypeDef HAL Status 00158 */ 00159 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError) 00160 { 00161 HAL_StatusTypeDef status = HAL_ERROR; 00162 uint32_t address = 0U; 00163 00164 /* Process Locked */ 00165 __HAL_LOCK(&pFlash); 00166 00167 /* Check the parameters */ 00168 assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); 00169 00170 if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) 00171 { 00172 #if defined(FLASH_BANK2_END) 00173 if (pEraseInit->Banks == FLASH_BANK_BOTH) 00174 { 00175 /* Mass Erase requested for Bank1 and Bank2 */ 00176 /* Wait for last operation to be completed */ 00177 if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \ 00178 (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)) 00179 { 00180 /*Mass erase to be done*/ 00181 FLASH_MassErase(FLASH_BANK_BOTH); 00182 00183 /* Wait for last operation to be completed */ 00184 if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \ 00185 (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)) 00186 { 00187 status = HAL_OK; 00188 } 00189 00190 /* If the erase operation is completed, disable the MER Bit */ 00191 CLEAR_BIT(FLASH->CR, FLASH_CR_MER); 00192 CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); 00193 } 00194 } 00195 else if (pEraseInit->Banks == FLASH_BANK_2) 00196 { 00197 /* Mass Erase requested for Bank2 */ 00198 /* Wait for last operation to be completed */ 00199 if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) 00200 { 00201 /*Mass erase to be done*/ 00202 FLASH_MassErase(FLASH_BANK_2); 00203 00204 /* Wait for last operation to be completed */ 00205 status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); 00206 00207 /* If the erase operation is completed, disable the MER Bit */ 00208 CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); 00209 } 00210 } 00211 else 00212 #endif /* FLASH_BANK2_END */ 00213 { 00214 /* Mass Erase requested for Bank1 */ 00215 /* Wait for last operation to be completed */ 00216 if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) 00217 { 00218 /*Mass erase to be done*/ 00219 FLASH_MassErase(FLASH_BANK_1); 00220 00221 /* Wait for last operation to be completed */ 00222 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00223 00224 /* If the erase operation is completed, disable the MER Bit */ 00225 CLEAR_BIT(FLASH->CR, FLASH_CR_MER); 00226 } 00227 } 00228 } 00229 else 00230 { 00231 /* Page Erase is requested */ 00232 /* Check the parameters */ 00233 assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); 00234 assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); 00235 00236 #if defined(FLASH_BANK2_END) 00237 /* Page Erase requested on address located on bank2 */ 00238 if(pEraseInit->PageAddress > FLASH_BANK1_END) 00239 { 00240 /* Wait for last operation to be completed */ 00241 if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) 00242 { 00243 /*Initialization of PageError variable*/ 00244 *PageError = 0xFFFFFFFFU; 00245 00246 /* Erase by page by page to be done*/ 00247 for(address = pEraseInit->PageAddress; 00248 address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE); 00249 address += FLASH_PAGE_SIZE) 00250 { 00251 FLASH_PageErase(address); 00252 00253 /* Wait for last operation to be completed */ 00254 status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); 00255 00256 /* If the erase operation is completed, disable the PER Bit */ 00257 CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER); 00258 00259 if (status != HAL_OK) 00260 { 00261 /* In case of error, stop erase procedure and return the faulty address */ 00262 *PageError = address; 00263 break; 00264 } 00265 } 00266 } 00267 } 00268 else 00269 #endif /* FLASH_BANK2_END */ 00270 { 00271 /* Page Erase requested on address located on bank1 */ 00272 /* Wait for last operation to be completed */ 00273 if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) 00274 { 00275 /*Initialization of PageError variable*/ 00276 *PageError = 0xFFFFFFFFU; 00277 00278 /* Erase page by page to be done*/ 00279 for(address = pEraseInit->PageAddress; 00280 address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress); 00281 address += FLASH_PAGE_SIZE) 00282 { 00283 FLASH_PageErase(address); 00284 00285 /* Wait for last operation to be completed */ 00286 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00287 00288 /* If the erase operation is completed, disable the PER Bit */ 00289 CLEAR_BIT(FLASH->CR, FLASH_CR_PER); 00290 00291 if (status != HAL_OK) 00292 { 00293 /* In case of error, stop erase procedure and return the faulty address */ 00294 *PageError = address; 00295 break; 00296 } 00297 } 00298 } 00299 } 00300 } 00301 00302 /* Process Unlocked */ 00303 __HAL_UNLOCK(&pFlash); 00304 00305 return status; 00306 } 00307 00308 /** 00309 * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled 00310 * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function 00311 * must be called before. 00312 * Call the @ref HAL_FLASH_Lock() to disable the flash memory access 00313 * (recommended to protect the FLASH memory against possible unwanted operation) 00314 * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that 00315 * contains the configuration information for the erasing. 00316 * 00317 * @retval HAL_StatusTypeDef HAL Status 00318 */ 00319 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) 00320 { 00321 HAL_StatusTypeDef status = HAL_OK; 00322 00323 /* Process Locked */ 00324 __HAL_LOCK(&pFlash); 00325 00326 /* If procedure already ongoing, reject the next one */ 00327 if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) 00328 { 00329 return HAL_ERROR; 00330 } 00331 00332 /* Check the parameters */ 00333 assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); 00334 00335 /* Enable End of FLASH Operation and Error source interrupts */ 00336 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); 00337 00338 #if defined(FLASH_BANK2_END) 00339 /* Enable End of FLASH Operation and Error source interrupts */ 00340 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2); 00341 00342 #endif 00343 if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) 00344 { 00345 /*Mass erase to be done*/ 00346 pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; 00347 FLASH_MassErase(pEraseInit->Banks); 00348 } 00349 else 00350 { 00351 /* Erase by page to be done*/ 00352 00353 /* Check the parameters */ 00354 assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); 00355 assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); 00356 00357 pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE; 00358 pFlash.DataRemaining = pEraseInit->NbPages; 00359 pFlash.Address = pEraseInit->PageAddress; 00360 00361 /*Erase 1st page and wait for IT*/ 00362 FLASH_PageErase(pEraseInit->PageAddress); 00363 } 00364 00365 return status; 00366 } 00367 00368 /** 00369 * @} 00370 */ 00371 00372 /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions 00373 * @brief Option Bytes Programming functions 00374 * 00375 @verbatim 00376 ============================================================================== 00377 ##### Option Bytes Programming functions ##### 00378 ============================================================================== 00379 [..] 00380 This subsection provides a set of functions allowing to control the FLASH 00381 option bytes operations. 00382 00383 @endverbatim 00384 * @{ 00385 */ 00386 00387 /** 00388 * @brief Erases the FLASH option bytes. 00389 * @note This functions erases all option bytes except the Read protection (RDP). 00390 * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface 00391 * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes 00392 * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes 00393 * (system reset will occur) 00394 * @retval HAL status 00395 */ 00396 00397 HAL_StatusTypeDef HAL_FLASHEx_OBErase(void) 00398 { 00399 uint8_t rdptmp = OB_RDP_LEVEL_0; 00400 HAL_StatusTypeDef status = HAL_ERROR; 00401 00402 /* Get the actual read protection Option Byte value */ 00403 rdptmp = FLASH_OB_GetRDP(); 00404 00405 /* Wait for last operation to be completed */ 00406 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00407 00408 if(status == HAL_OK) 00409 { 00410 /* Clean the error context */ 00411 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00412 00413 /* If the previous operation is completed, proceed to erase the option bytes */ 00414 SET_BIT(FLASH->CR, FLASH_CR_OPTER); 00415 SET_BIT(FLASH->CR, FLASH_CR_STRT); 00416 00417 /* Wait for last operation to be completed */ 00418 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00419 00420 /* If the erase operation is completed, disable the OPTER Bit */ 00421 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER); 00422 00423 if(status == HAL_OK) 00424 { 00425 /* Restore the last read protection Option Byte value */ 00426 status = FLASH_OB_RDP_LevelConfig(rdptmp); 00427 } 00428 } 00429 00430 /* Return the erase status */ 00431 return status; 00432 } 00433 00434 /** 00435 * @brief Program option bytes 00436 * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface 00437 * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes 00438 * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes 00439 * (system reset will occur) 00440 * 00441 * @param pOBInit pointer to an FLASH_OBInitStruct structure that 00442 * contains the configuration information for the programming. 00443 * 00444 * @retval HAL_StatusTypeDef HAL Status 00445 */ 00446 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) 00447 { 00448 HAL_StatusTypeDef status = HAL_ERROR; 00449 00450 /* Process Locked */ 00451 __HAL_LOCK(&pFlash); 00452 00453 /* Check the parameters */ 00454 assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); 00455 00456 /* Write protection configuration */ 00457 if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) 00458 { 00459 assert_param(IS_WRPSTATE(pOBInit->WRPState)); 00460 if (pOBInit->WRPState == OB_WRPSTATE_ENABLE) 00461 { 00462 /* Enable of Write protection on the selected page */ 00463 status = FLASH_OB_EnableWRP(pOBInit->WRPPage); 00464 } 00465 else 00466 { 00467 /* Disable of Write protection on the selected page */ 00468 status = FLASH_OB_DisableWRP(pOBInit->WRPPage); 00469 } 00470 if (status != HAL_OK) 00471 { 00472 /* Process Unlocked */ 00473 __HAL_UNLOCK(&pFlash); 00474 return status; 00475 } 00476 } 00477 00478 /* Read protection configuration */ 00479 if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP) 00480 { 00481 status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel); 00482 if (status != HAL_OK) 00483 { 00484 /* Process Unlocked */ 00485 __HAL_UNLOCK(&pFlash); 00486 return status; 00487 } 00488 } 00489 00490 /* USER configuration */ 00491 if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER) 00492 { 00493 status = FLASH_OB_UserConfig(pOBInit->USERConfig); 00494 if (status != HAL_OK) 00495 { 00496 /* Process Unlocked */ 00497 __HAL_UNLOCK(&pFlash); 00498 return status; 00499 } 00500 } 00501 00502 /* DATA configuration*/ 00503 if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA) 00504 { 00505 status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData); 00506 if (status != HAL_OK) 00507 { 00508 /* Process Unlocked */ 00509 __HAL_UNLOCK(&pFlash); 00510 return status; 00511 } 00512 } 00513 00514 /* Process Unlocked */ 00515 __HAL_UNLOCK(&pFlash); 00516 00517 return status; 00518 } 00519 00520 /** 00521 * @brief Get the Option byte configuration 00522 * @param pOBInit pointer to an FLASH_OBInitStruct structure that 00523 * contains the configuration information for the programming. 00524 * 00525 * @retval None 00526 */ 00527 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) 00528 { 00529 pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER; 00530 00531 /*Get WRP*/ 00532 pOBInit->WRPPage = FLASH_OB_GetWRP(); 00533 00534 /*Get RDP Level*/ 00535 pOBInit->RDPLevel = FLASH_OB_GetRDP(); 00536 00537 /*Get USER*/ 00538 pOBInit->USERConfig = FLASH_OB_GetUser(); 00539 } 00540 00541 /** 00542 * @brief Get the Option byte user data 00543 * @param DATAAdress Address of the option byte DATA 00544 * This parameter can be one of the following values: 00545 * @arg @ref OB_DATA_ADDRESS_DATA0 00546 * @arg @ref OB_DATA_ADDRESS_DATA1 00547 * @retval Value programmed in USER data 00548 */ 00549 uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress) 00550 { 00551 uint32_t value = 0; 00552 00553 if (DATAAdress == OB_DATA_ADDRESS_DATA0) 00554 { 00555 /* Get value programmed in OB USER Data0 */ 00556 value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT; 00557 } 00558 else 00559 { 00560 /* Get value programmed in OB USER Data1 */ 00561 value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT; 00562 } 00563 00564 return value; 00565 } 00566 00567 /** 00568 * @} 00569 */ 00570 00571 /** 00572 * @} 00573 */ 00574 00575 /** @addtogroup FLASHEx_Private_Functions 00576 * @{ 00577 */ 00578 00579 /** 00580 * @brief Full erase of FLASH memory Bank 00581 * @param Banks Banks to be erased 00582 * This parameter can be one of the following values: 00583 * @arg @ref FLASH_BANK_1 Bank1 to be erased 00584 @if STM32F101xG 00585 * @arg @ref FLASH_BANK_2 Bank2 to be erased 00586 * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased 00587 @endif 00588 @if STM32F103xG 00589 * @arg @ref FLASH_BANK_2 Bank2 to be erased 00590 * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased 00591 @endif 00592 * 00593 * @retval None 00594 */ 00595 static void FLASH_MassErase(uint32_t Banks) 00596 { 00597 /* Check the parameters */ 00598 assert_param(IS_FLASH_BANK(Banks)); 00599 00600 /* Clean the error context */ 00601 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00602 00603 #if defined(FLASH_BANK2_END) 00604 if(Banks == FLASH_BANK_BOTH) 00605 { 00606 /* bank1 & bank2 will be erased*/ 00607 SET_BIT(FLASH->CR, FLASH_CR_MER); 00608 SET_BIT(FLASH->CR2, FLASH_CR2_MER); 00609 SET_BIT(FLASH->CR, FLASH_CR_STRT); 00610 SET_BIT(FLASH->CR2, FLASH_CR2_STRT); 00611 } 00612 else if(Banks == FLASH_BANK_2) 00613 { 00614 /*Only bank2 will be erased*/ 00615 SET_BIT(FLASH->CR2, FLASH_CR2_MER); 00616 SET_BIT(FLASH->CR2, FLASH_CR2_STRT); 00617 } 00618 else 00619 { 00620 #endif /* FLASH_BANK2_END */ 00621 #if !defined(FLASH_BANK2_END) 00622 /* Prevent unused argument(s) compilation warning */ 00623 UNUSED(Banks); 00624 #endif /* FLASH_BANK2_END */ 00625 /* Only bank1 will be erased*/ 00626 SET_BIT(FLASH->CR, FLASH_CR_MER); 00627 SET_BIT(FLASH->CR, FLASH_CR_STRT); 00628 #if defined(FLASH_BANK2_END) 00629 } 00630 #endif /* FLASH_BANK2_END */ 00631 } 00632 00633 /** 00634 * @brief Enable the write protection of the desired pages 00635 * @note An option byte erase is done automatically in this function. 00636 * @note When the memory read protection level is selected (RDP level = 1), 00637 * it is not possible to program or erase the flash page i if 00638 * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 00639 * 00640 * @param WriteProtectPage specifies the page(s) to be write protected. 00641 * The value of this parameter depend on device used within the same series 00642 * @retval HAL status 00643 */ 00644 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage) 00645 { 00646 HAL_StatusTypeDef status = HAL_OK; 00647 uint16_t WRP0_Data = 0xFFFF; 00648 #if defined(FLASH_WRP1_WRP1) 00649 uint16_t WRP1_Data = 0xFFFF; 00650 #endif /* FLASH_WRP1_WRP1 */ 00651 #if defined(FLASH_WRP2_WRP2) 00652 uint16_t WRP2_Data = 0xFFFF; 00653 #endif /* FLASH_WRP2_WRP2 */ 00654 #if defined(FLASH_WRP3_WRP3) 00655 uint16_t WRP3_Data = 0xFFFF; 00656 #endif /* FLASH_WRP3_WRP3 */ 00657 00658 /* Check the parameters */ 00659 assert_param(IS_OB_WRP(WriteProtectPage)); 00660 00661 /* Get current write protected pages and the new pages to be protected ******/ 00662 WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage)); 00663 00664 #if defined(OB_WRP_PAGES0TO15MASK) 00665 WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); 00666 #elif defined(OB_WRP_PAGES0TO31MASK) 00667 WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); 00668 #endif /* OB_WRP_PAGES0TO31MASK */ 00669 00670 #if defined(OB_WRP_PAGES16TO31MASK) 00671 WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U); 00672 #elif defined(OB_WRP_PAGES32TO63MASK) 00673 WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U); 00674 #endif /* OB_WRP_PAGES32TO63MASK */ 00675 00676 #if defined(OB_WRP_PAGES64TO95MASK) 00677 WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U); 00678 #endif /* OB_WRP_PAGES64TO95MASK */ 00679 #if defined(OB_WRP_PAGES32TO47MASK) 00680 WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U); 00681 #endif /* OB_WRP_PAGES32TO47MASK */ 00682 00683 #if defined(OB_WRP_PAGES96TO127MASK) 00684 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U); 00685 #elif defined(OB_WRP_PAGES48TO255MASK) 00686 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U); 00687 #elif defined(OB_WRP_PAGES48TO511MASK) 00688 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U); 00689 #elif defined(OB_WRP_PAGES48TO127MASK) 00690 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U); 00691 #endif /* OB_WRP_PAGES96TO127MASK */ 00692 00693 /* Wait for last operation to be completed */ 00694 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00695 00696 if(status == HAL_OK) 00697 { 00698 /* Clean the error context */ 00699 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00700 00701 /* To be able to write again option byte, need to perform a option byte erase */ 00702 status = HAL_FLASHEx_OBErase(); 00703 if (status == HAL_OK) 00704 { 00705 /* Enable write protection */ 00706 SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 00707 00708 #if defined(FLASH_WRP0_WRP0) 00709 if(WRP0_Data != 0xFFU) 00710 { 00711 OB->WRP0 &= WRP0_Data; 00712 00713 /* Wait for last operation to be completed */ 00714 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00715 } 00716 #endif /* FLASH_WRP0_WRP0 */ 00717 00718 #if defined(FLASH_WRP1_WRP1) 00719 if((status == HAL_OK) && (WRP1_Data != 0xFFU)) 00720 { 00721 OB->WRP1 &= WRP1_Data; 00722 00723 /* Wait for last operation to be completed */ 00724 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00725 } 00726 #endif /* FLASH_WRP1_WRP1 */ 00727 00728 #if defined(FLASH_WRP2_WRP2) 00729 if((status == HAL_OK) && (WRP2_Data != 0xFFU)) 00730 { 00731 OB->WRP2 &= WRP2_Data; 00732 00733 /* Wait for last operation to be completed */ 00734 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00735 } 00736 #endif /* FLASH_WRP2_WRP2 */ 00737 00738 #if defined(FLASH_WRP3_WRP3) 00739 if((status == HAL_OK) && (WRP3_Data != 0xFFU)) 00740 { 00741 OB->WRP3 &= WRP3_Data; 00742 00743 /* Wait for last operation to be completed */ 00744 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00745 } 00746 #endif /* FLASH_WRP3_WRP3 */ 00747 00748 /* if the program operation is completed, disable the OPTPG Bit */ 00749 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); 00750 } 00751 } 00752 00753 return status; 00754 } 00755 00756 /** 00757 * @brief Disable the write protection of the desired pages 00758 * @note An option byte erase is done automatically in this function. 00759 * @note When the memory read protection level is selected (RDP level = 1), 00760 * it is not possible to program or erase the flash page i if 00761 * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 00762 * 00763 * @param WriteProtectPage specifies the page(s) to be write unprotected. 00764 * The value of this parameter depend on device used within the same series 00765 * @retval HAL status 00766 */ 00767 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage) 00768 { 00769 HAL_StatusTypeDef status = HAL_OK; 00770 uint16_t WRP0_Data = 0xFFFF; 00771 #if defined(FLASH_WRP1_WRP1) 00772 uint16_t WRP1_Data = 0xFFFF; 00773 #endif /* FLASH_WRP1_WRP1 */ 00774 #if defined(FLASH_WRP2_WRP2) 00775 uint16_t WRP2_Data = 0xFFFF; 00776 #endif /* FLASH_WRP2_WRP2 */ 00777 #if defined(FLASH_WRP3_WRP3) 00778 uint16_t WRP3_Data = 0xFFFF; 00779 #endif /* FLASH_WRP3_WRP3 */ 00780 00781 /* Check the parameters */ 00782 assert_param(IS_OB_WRP(WriteProtectPage)); 00783 00784 /* Get current write protected pages and the new pages to be unprotected ******/ 00785 WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage); 00786 00787 #if defined(OB_WRP_PAGES0TO15MASK) 00788 WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); 00789 #elif defined(OB_WRP_PAGES0TO31MASK) 00790 WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); 00791 #endif /* OB_WRP_PAGES0TO31MASK */ 00792 00793 #if defined(OB_WRP_PAGES16TO31MASK) 00794 WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U); 00795 #elif defined(OB_WRP_PAGES32TO63MASK) 00796 WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U); 00797 #endif /* OB_WRP_PAGES32TO63MASK */ 00798 00799 #if defined(OB_WRP_PAGES64TO95MASK) 00800 WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U); 00801 #endif /* OB_WRP_PAGES64TO95MASK */ 00802 #if defined(OB_WRP_PAGES32TO47MASK) 00803 WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U); 00804 #endif /* OB_WRP_PAGES32TO47MASK */ 00805 00806 #if defined(OB_WRP_PAGES96TO127MASK) 00807 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U); 00808 #elif defined(OB_WRP_PAGES48TO255MASK) 00809 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U); 00810 #elif defined(OB_WRP_PAGES48TO511MASK) 00811 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U); 00812 #elif defined(OB_WRP_PAGES48TO127MASK) 00813 WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U); 00814 #endif /* OB_WRP_PAGES96TO127MASK */ 00815 00816 00817 /* Wait for last operation to be completed */ 00818 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00819 00820 if(status == HAL_OK) 00821 { 00822 /* Clean the error context */ 00823 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00824 00825 /* To be able to write again option byte, need to perform a option byte erase */ 00826 status = HAL_FLASHEx_OBErase(); 00827 if (status == HAL_OK) 00828 { 00829 SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 00830 00831 #if defined(FLASH_WRP0_WRP0) 00832 if(WRP0_Data != 0xFFU) 00833 { 00834 OB->WRP0 |= WRP0_Data; 00835 00836 /* Wait for last operation to be completed */ 00837 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00838 } 00839 #endif /* FLASH_WRP0_WRP0 */ 00840 00841 #if defined(FLASH_WRP1_WRP1) 00842 if((status == HAL_OK) && (WRP1_Data != 0xFFU)) 00843 { 00844 OB->WRP1 |= WRP1_Data; 00845 00846 /* Wait for last operation to be completed */ 00847 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00848 } 00849 #endif /* FLASH_WRP1_WRP1 */ 00850 00851 #if defined(FLASH_WRP2_WRP2) 00852 if((status == HAL_OK) && (WRP2_Data != 0xFFU)) 00853 { 00854 OB->WRP2 |= WRP2_Data; 00855 00856 /* Wait for last operation to be completed */ 00857 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00858 } 00859 #endif /* FLASH_WRP2_WRP2 */ 00860 00861 #if defined(FLASH_WRP3_WRP3) 00862 if((status == HAL_OK) && (WRP3_Data != 0xFFU)) 00863 { 00864 OB->WRP3 |= WRP3_Data; 00865 00866 /* Wait for last operation to be completed */ 00867 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00868 } 00869 #endif /* FLASH_WRP3_WRP3 */ 00870 00871 /* if the program operation is completed, disable the OPTPG Bit */ 00872 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); 00873 } 00874 } 00875 return status; 00876 } 00877 00878 /** 00879 * @brief Set the read protection level. 00880 * @param ReadProtectLevel specifies the read protection level. 00881 * This parameter can be one of the following values: 00882 * @arg @ref OB_RDP_LEVEL_0 No protection 00883 * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory 00884 * @retval HAL status 00885 */ 00886 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel) 00887 { 00888 HAL_StatusTypeDef status = HAL_OK; 00889 00890 /* Check the parameters */ 00891 assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel)); 00892 00893 /* Wait for last operation to be completed */ 00894 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00895 00896 if(status == HAL_OK) 00897 { 00898 /* Clean the error context */ 00899 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00900 00901 /* If the previous operation is completed, proceed to erase the option bytes */ 00902 SET_BIT(FLASH->CR, FLASH_CR_OPTER); 00903 SET_BIT(FLASH->CR, FLASH_CR_STRT); 00904 00905 /* Wait for last operation to be completed */ 00906 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00907 00908 /* If the erase operation is completed, disable the OPTER Bit */ 00909 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER); 00910 00911 if(status == HAL_OK) 00912 { 00913 /* Enable the Option Bytes Programming operation */ 00914 SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 00915 00916 WRITE_REG(OB->RDP, ReadProtectLevel); 00917 00918 /* Wait for last operation to be completed */ 00919 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00920 00921 /* if the program operation is completed, disable the OPTPG Bit */ 00922 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); 00923 } 00924 } 00925 00926 return status; 00927 } 00928 00929 /** 00930 * @brief Program the FLASH User Option Byte. 00931 * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs) 00932 * @param UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2), 00933 * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4). 00934 * And BFBF2(Bit5) for STM32F101xG and STM32F103xG . 00935 * @retval HAL status 00936 */ 00937 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig) 00938 { 00939 HAL_StatusTypeDef status = HAL_OK; 00940 00941 /* Check the parameters */ 00942 assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW))); 00943 assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST))); 00944 assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST))); 00945 #if defined(FLASH_BANK2_END) 00946 assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET))); 00947 #endif /* FLASH_BANK2_END */ 00948 00949 /* Wait for last operation to be completed */ 00950 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00951 00952 if(status == HAL_OK) 00953 { 00954 /* Clean the error context */ 00955 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 00956 00957 /* Enable the Option Bytes Programming operation */ 00958 SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 00959 00960 #if defined(FLASH_BANK2_END) 00961 OB->USER = (UserConfig | 0xF0U); 00962 #else 00963 OB->USER = (UserConfig | 0x88U); 00964 #endif /* FLASH_BANK2_END */ 00965 00966 /* Wait for last operation to be completed */ 00967 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00968 00969 /* if the program operation is completed, disable the OPTPG Bit */ 00970 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); 00971 } 00972 00973 return status; 00974 } 00975 00976 /** 00977 * @brief Programs a half word at a specified Option Byte Data address. 00978 * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface 00979 * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes 00980 * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes 00981 * (system reset will occur) 00982 * Programming of the OB should be performed only after an erase (otherwise PGERR occurs) 00983 * @param Address specifies the address to be programmed. 00984 * This parameter can be 0x1FFFF804 or 0x1FFFF806. 00985 * @param Data specifies the data to be programmed. 00986 * @retval HAL status 00987 */ 00988 static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data) 00989 { 00990 HAL_StatusTypeDef status = HAL_ERROR; 00991 00992 /* Check the parameters */ 00993 assert_param(IS_OB_DATA_ADDRESS(Address)); 00994 00995 /* Wait for last operation to be completed */ 00996 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 00997 00998 if(status == HAL_OK) 00999 { 01000 /* Clean the error context */ 01001 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 01002 01003 /* Enables the Option Bytes Programming operation */ 01004 SET_BIT(FLASH->CR, FLASH_CR_OPTPG); 01005 *(__IO uint16_t*)Address = Data; 01006 01007 /* Wait for last operation to be completed */ 01008 status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); 01009 01010 /* If the program operation is completed, disable the OPTPG Bit */ 01011 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); 01012 } 01013 /* Return the Option Byte Data Program Status */ 01014 return status; 01015 } 01016 01017 /** 01018 * @brief Return the FLASH Write Protection Option Bytes value. 01019 * @retval The FLASH Write Protection Option Bytes value 01020 */ 01021 static uint32_t FLASH_OB_GetWRP(void) 01022 { 01023 /* Return the FLASH write protection Register value */ 01024 return (uint32_t)(READ_REG(FLASH->WRPR)); 01025 } 01026 01027 /** 01028 * @brief Returns the FLASH Read Protection level. 01029 * @retval FLASH RDP level 01030 * This parameter can be one of the following values: 01031 * @arg @ref OB_RDP_LEVEL_0 No protection 01032 * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory 01033 */ 01034 static uint32_t FLASH_OB_GetRDP(void) 01035 { 01036 uint32_t readstatus = OB_RDP_LEVEL_0; 01037 uint32_t tmp_reg = 0U; 01038 01039 /* Read RDP level bits */ 01040 tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT); 01041 01042 if (tmp_reg == FLASH_OBR_RDPRT) 01043 { 01044 readstatus = OB_RDP_LEVEL_1; 01045 } 01046 else 01047 { 01048 readstatus = OB_RDP_LEVEL_0; 01049 } 01050 01051 return readstatus; 01052 } 01053 01054 /** 01055 * @brief Return the FLASH User Option Byte value. 01056 * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2), 01057 * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4). 01058 * And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG . 01059 */ 01060 static uint8_t FLASH_OB_GetUser(void) 01061 { 01062 /* Return the User Option Byte */ 01063 return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT); 01064 } 01065 01066 /** 01067 * @} 01068 */ 01069 01070 /** 01071 * @} 01072 */ 01073 01074 /** @addtogroup FLASH 01075 * @{ 01076 */ 01077 01078 /** @addtogroup FLASH_Private_Functions 01079 * @{ 01080 */ 01081 01082 /** 01083 * @brief Erase the specified FLASH memory page 01084 * @param PageAddress FLASH page to erase 01085 * The value of this parameter depend on device used within the same series 01086 * 01087 * @retval None 01088 */ 01089 void FLASH_PageErase(uint32_t PageAddress) 01090 { 01091 /* Clean the error context */ 01092 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; 01093 01094 #if defined(FLASH_BANK2_END) 01095 if(PageAddress > FLASH_BANK1_END) 01096 { 01097 /* Proceed to erase the page */ 01098 SET_BIT(FLASH->CR2, FLASH_CR2_PER); 01099 WRITE_REG(FLASH->AR2, PageAddress); 01100 SET_BIT(FLASH->CR2, FLASH_CR2_STRT); 01101 } 01102 else 01103 { 01104 #endif /* FLASH_BANK2_END */ 01105 /* Proceed to erase the page */ 01106 SET_BIT(FLASH->CR, FLASH_CR_PER); 01107 WRITE_REG(FLASH->AR, PageAddress); 01108 SET_BIT(FLASH->CR, FLASH_CR_STRT); 01109 #if defined(FLASH_BANK2_END) 01110 } 01111 #endif /* FLASH_BANK2_END */ 01112 } 01113 01114 /** 01115 * @} 01116 */ 01117 01118 /** 01119 * @} 01120 */ 01121 01122 #endif /* HAL_FLASH_MODULE_ENABLED */ 01123 /** 01124 * @} 01125 */ 01126 01127 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/