fix LPC812 PWM
Fork of mbed-dev by
Diff: targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash_ex.c
- Revision:
- 124:6a4a5b7d7324
- Parent:
- 0:9b334a45a8ff
diff -r 5dbefb20d136 -r 6a4a5b7d7324 targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash_ex.c --- a/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash_ex.c Thu May 05 21:00:11 2016 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_flash_ex.c Mon May 09 18:30:12 2016 +0100 @@ -2,8 +2,8 @@ ****************************************************************************** * @file stm32f1xx_hal_flash_ex.c * @author MCD Application Team - * @version V1.0.0 - * @date 15-December-2014 + * @version V1.0.4 + * @date 29-April-2016 * @brief Extended FLASH HAL module driver. * * This file provides firmware functions to manage the following @@ -30,7 +30,7 @@ ****************************************************************************** * @attention * - * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -82,7 +82,7 @@ */ /** @defgroup FLASHEx FLASHEx - * @brief FLASH Extended HAL module driver + * @brief FLASH HAL Extension module driver * @{ */ @@ -91,6 +91,9 @@ /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants * @{ */ +#define FLASH_POSITION_IWDGSW_BIT (uint32_t)POSITION_VAL(FLASH_OBR_IWDG_SW) +#define FLASH_POSITION_OB_USERDATA0_BIT (uint32_t)POSITION_VAL(FLASH_OBR_DATA0) +#define FLASH_POSITION_OB_USERDATA1_BIT (uint32_t)POSITION_VAL(FLASH_OBR_DATA1) /** * @} */ @@ -118,13 +121,9 @@ static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig); static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data); static uint32_t FLASH_OB_GetWRP(void); -static FlagStatus FLASH_OB_GetRDP(void); +static uint32_t FLASH_OB_GetRDP(void); static uint8_t FLASH_OB_GetUser(void); -#if defined(STM32F101xG) || defined(STM32F103xG) -/* State operations */ -static HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout); -#endif /** * @} */ @@ -134,13 +133,25 @@ * @{ */ -/** @defgroup FLASHEx_Exported_Functions_Group1 Extended Input and Output operation functions - * @brief I/O operation functions +/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions + * @brief FLASH Memory Erasing functions * @verbatim - =============================================================================== - ##### IO operation functions ##### - =============================================================================== + ============================================================================== + ##### FLASH Erasing Programming functions ##### + ============================================================================== + + [..] The FLASH Memory Erasing functions, includes the following functions: + (+) @ref HAL_FLASHEx_Erase: return only when erase has been done + (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback + is called with parameter 0xFFFFFFFF + + [..] Any operation of erase should follow these steps: + (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and + program memory access. + (#) Call the desired function to erase page. + (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access + (recommended to protect the FLASH memory against possible unwanted operation). @endverbatim * @{ @@ -149,12 +160,14 @@ /** * @brief Perform a mass erase or erase the specified FLASH memory pages - * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface - * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function + * must be called before. + * Call the @ref HAL_FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * - * @param[out] PageError: pointer to variable that + * @param[out] PageError pointer to variable that * contains the configuration information on faulty page in case of error * (0xFFFFFFFF means that all the pages have been correctly erased) * @@ -173,7 +186,7 @@ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) if (pEraseInit->Banks == FLASH_BANK_BOTH) { /* Mass Erase requested for Bank1 and Bank2 */ @@ -213,7 +226,7 @@ } } else -#endif /* STM32F101xG || STM32F103xG */ +#endif /* FLASH_BANK2_END */ { /* Mass Erase requested for Bank1 */ /* Wait for last operation to be completed */ @@ -237,7 +250,7 @@ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) /* Page Erase requested on address located on bank2 */ if(pEraseInit->PageAddress > FLASH_BANK1_END) { @@ -270,47 +283,33 @@ } } else -#endif /* STM32F101xG || STM32F103xG */ - { +#endif /* FLASH_BANK2_END */ + { /* Page Erase requested on address located on bank1 */ /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { - if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + /*Initialization of PageError variable*/ + *PageError = 0xFFFFFFFF; + + /* Erase page by page to be done*/ + for(address = pEraseInit->PageAddress; + address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress); + address += FLASH_PAGE_SIZE) { - /*Mass erase to be done*/ - FLASH_MassErase(pEraseInit->Banks); + FLASH_PageErase(address); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - /* If the erase operation is completed, disable the MER Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_MER); - } - else - { - /*Initialization of PageError variable*/ - *PageError = 0xFFFFFFFF; + /* If the erase operation is completed, disable the PER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PER); - /* Erase by page by page to be done*/ - for(address = pEraseInit->PageAddress; - address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE); - address += FLASH_PAGE_SIZE) + if (status != HAL_OK) { - FLASH_PageErase(address); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - - /* If the erase operation is completed, disable the PER Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_PER); - - if (status != HAL_OK) - { - /* In case of error, stop erase procedure and return the faulty address */ - *PageError = address; - break; - } + /* In case of error, stop erase procedure and return the faulty address */ + *PageError = address; + break; } } } @@ -324,10 +323,12 @@ } /** - * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled - * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface - * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that + * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function + * must be called before. + * Call the @ref HAL_FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @retval HAL_StatusTypeDef HAL Status @@ -349,18 +350,18 @@ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); /* Enable End of FLASH Operation and Error source interrupts */ - __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR)); + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) /* Enable End of FLASH Operation and Error source interrupts */ - __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2)); + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2); + #endif - if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; - FLASH_MassErase(pEraseInit->Banks); + FLASH_MassErase(pEraseInit->Banks); } else { @@ -384,17 +385,17 @@ /** * @} */ - -/** @defgroup FLASHEx_Exported_Functions_Group2 Extended Peripheral Control functions - * @brief Peripheral Control functions + +/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions + * @brief Option Bytes Programming functions * @verbatim - =============================================================================== - ##### Peripheral Control functions ##### - =============================================================================== + ============================================================================== + ##### Option Bytes Programming functions ##### + ============================================================================== [..] This subsection provides a set of functions allowing to control the FLASH - memory operations. + option bytes operations. @endverbatim * @{ @@ -403,9 +404,9 @@ /** * @brief Erases the FLASH option bytes. * @note This functions erases all option bytes except the Read protection (RDP). - * The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes - * The function HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes + * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes + * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes * (system reset will occur) * @retval HAL status */ @@ -416,10 +417,7 @@ HAL_StatusTypeDef status = HAL_ERROR; /* Get the actual read protection Option Byte value */ - if(FLASH_OB_GetRDP() != RESET) - { - rdptmp = OB_RDP_LEVEL_1; - } + rdptmp = FLASH_OB_GetRDP(); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); @@ -452,12 +450,12 @@ /** * @brief Program option bytes - * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes - * The function HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes + * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes + * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes * (system reset will occur) * - * @param pOBInit: pointer to an FLASH_OBInitStruct structure that + * @param pOBInit pointer to an FLASH_OBInitStruct structure that * contains the configuration information for the programming. * * @retval HAL_StatusTypeDef HAL Status @@ -466,6 +464,9 @@ { HAL_StatusTypeDef status = HAL_ERROR; + /* Process Locked */ + __HAL_LOCK(&pFlash); + /* Check the parameters */ assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); @@ -483,32 +484,59 @@ /* Disable of Write protection on the selected page */ status = FLASH_OB_DisableWRP(pOBInit->WRPPage); } + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } } /* Read protection configuration */ if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP) { status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel); + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } } /* USER configuration */ if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER) { status = FLASH_OB_UserConfig(pOBInit->USERConfig); + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } } /* DATA configuration*/ if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA) { status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData); + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } } + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; } /** * @brief Get the Option byte configuration - * @param pOBInit: pointer to an FLASH_OBInitStruct structure that + * @param pOBInit pointer to an FLASH_OBInitStruct structure that * contains the configuration information for the programming. * * @retval None @@ -528,6 +556,32 @@ } /** + * @brief Get the Option byte user data + * @param DATAAdress Address of the option byte DATA + * This parameter can be one of the following values: + * @arg @ref OB_DATA_ADDRESS_DATA0 + * @arg @ref OB_DATA_ADDRESS_DATA1 + * @retval Value programmed in USER data + */ +uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress) +{ + uint32_t value = 0; + + if (DATAAdress == OB_DATA_ADDRESS_DATA0) + { + /* Get value programmed in OB USER Data0 */ + value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT; + } + else + { + /* Get value programmed in OB USER Data1 */ + value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT; + } + + return value; +} + +/** * @} */ @@ -541,13 +595,19 @@ /** * @brief Full erase of FLASH memory Bank - * @param Banks: Banks to be erased + * @param Banks Banks to be erased * This parameter can be one of the following values: - * @arg FLASH_BANK_1: Bank1 to be erased - * @arg FLASH_BANK_2: Bank2 to be erased - * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased + * @arg @ref FLASH_BANK_1 Bank1 to be erased + @if STM32F101xG + * @arg @ref FLASH_BANK_2 Bank2 to be erased + * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased + @endif + @if STM32F103xG + * @arg @ref FLASH_BANK_2 Bank2 to be erased + * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased + @endif * - * @retval HAL Status + * @retval None */ static void FLASH_MassErase(uint32_t Banks) { @@ -557,7 +617,7 @@ /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) if(Banks == FLASH_BANK_BOTH) { /* bank1 & bank2 will be erased*/ @@ -574,22 +634,23 @@ } else { -#endif /* STM32F101xG || STM32F103xG */ - /*Only bank1 will be erased*/ +#endif /* FLASH_BANK2_END */ + /* Only bank1 will be erased*/ SET_BIT(FLASH->CR, FLASH_CR_MER); SET_BIT(FLASH->CR, FLASH_CR_STRT); -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) } -#endif /* STM32F101xG || STM32F103xG */ +#endif /* FLASH_BANK2_END */ } /** * @brief Enable the write protection of the desired pages + * @note An option byte erase is done automatically in this function. * @note When the memory read protection level is selected (RDP level = 1), - * it is not possible to program or erase the flash page i if CortexM4 + * it is not possible to program or erase the flash page i if * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 * - * @param WriteProtectPage: specifies the page(s) to be write protected. + * @param WriteProtectPage specifies the page(s) to be write protected. * The value of this parameter depend on device used within the same series * @retval HAL status */ @@ -597,61 +658,51 @@ { HAL_StatusTypeDef status = HAL_OK; uint16_t WRP0_Data = 0xFFFF; -#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \ - defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \ - defined(STM32F101xG) || defined(STM32F103xG) || \ - defined(STM32F105xC) || defined(STM32F107xC) - uint16_t WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF; -#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB || */ - /* STM32F100xE || STM32F101xE || STM32F103xE || */ - /* STM32F101xG || STM32F103xG || */ - /* STM32F105xC || STM32F107xC */ +#if defined(FLASH_WRP1_WRP1) + uint16_t WRP1_Data = 0xFFFF; +#endif /* FLASH_WRP1_WRP1 */ +#if defined(FLASH_WRP2_WRP2) + uint16_t WRP2_Data = 0xFFFF; +#endif /* FLASH_WRP2_WRP2 */ +#if defined(FLASH_WRP3_WRP3) + uint16_t WRP3_Data = 0xFFFF; +#endif /* FLASH_WRP3_WRP3 */ /* Check the parameters */ assert_param(IS_OB_WRP(WriteProtectPage)); - WriteProtectPage = (uint32_t)(~WriteProtectPage); - - /* Low Density and Medium Density */ -#if defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || \ - defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) - WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); -#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 || */ - /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */ + /* Get current write protected pages and the new pages to be protected ******/ + WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage)); -/* Medium Density */ -#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) - WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8); - WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16); - WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); -#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */ - -/* High Density, XL Density and Connectivity line devices*/ -#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \ - defined(STM32F101xG) || defined(STM32F103xG) || \ - defined(STM32F105xC) || defined(STM32F107xC) +#if defined(OB_WRP_PAGES0TO15MASK) WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); +#elif defined(OB_WRP_PAGES0TO31MASK) + WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); +#endif /* OB_WRP_PAGES0TO31MASK */ + +#if defined(OB_WRP_PAGES16TO31MASK) WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8); +#elif defined(OB_WRP_PAGES32TO63MASK) + WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8); +#endif /* OB_WRP_PAGES32TO63MASK */ + +#if defined(OB_WRP_PAGES64TO95MASK) + WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16); +#endif /* OB_WRP_PAGES64TO95MASK */ +#if defined(OB_WRP_PAGES32TO47MASK) WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16); -#endif /* STM32F100xE || STM32F101xE || STM32F103xE */ - /* STM32F101xG || STM32F103xG */ - /* STM32F105xC || STM32F107xC */ - -/* High Density */ -#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) - WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); -#endif /* STM32F100xE || STM32F101xE || STM32F103xE */ +#endif /* OB_WRP_PAGES32TO47MASK */ -/* XL Density */ -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(OB_WRP_PAGES96TO127MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); +#elif defined(OB_WRP_PAGES48TO255MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); +#elif defined(OB_WRP_PAGES48TO511MASK) WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24); -#endif /* STM32F101xG || STM32F103xG */ - -/* Connectivity line devices */ -#if defined(STM32F105xC) || defined(STM32F107xC) +#elif defined(OB_WRP_PAGES48TO127MASK) WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24); -#endif /* STM32F105xC || STM32F107xC */ - +#endif /* OB_WRP_PAGES96TO127MASK */ + /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); @@ -660,51 +711,56 @@ /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - SET_BIT(FLASH->CR, FLASH_CR_OPTPG); - - if(WRP0_Data != 0xFF) + /* To be able to write again option byte, need to perform a option byte erase */ + status = HAL_FLASHEx_OBErase(); + if (status == HAL_OK) { - OB->WRP0 &= WRP0_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } + /* Enable write protection */ + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); -#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \ - defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \ - defined(STM32F101xG) || defined(STM32F103xG) || \ - defined(STM32F105xC) || defined(STM32F107xC) - - if((status == HAL_OK) && (WRP1_Data != 0xFF)) - { - OB->WRP1 &= WRP1_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } +#if defined(FLASH_WRP0_WRP0) + if(WRP0_Data != 0xFF) + { + OB->WRP0 &= WRP0_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP0_WRP0 */ - if((status == HAL_OK) && (WRP2_Data != 0xFF)) - { - OB->WRP2 &= WRP2_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } +#if defined(FLASH_WRP1_WRP1) + if((status == HAL_OK) && (WRP1_Data != 0xFF)) + { + OB->WRP1 &= WRP1_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP1_WRP1 */ - if((status == HAL_OK) && (WRP3_Data != 0xFF)) - { - OB->WRP3 &= WRP3_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); +#if defined(FLASH_WRP2_WRP2) + if((status == HAL_OK) && (WRP2_Data != 0xFF)) + { + OB->WRP2 &= WRP2_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP2_WRP2 */ + +#if defined(FLASH_WRP3_WRP3) + if((status == HAL_OK) && (WRP3_Data != 0xFF)) + { + OB->WRP3 &= WRP3_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP3_WRP3 */ + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); } -#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB || */ - /* STM32F100xE || STM32F101xE || STM32F103xE || */ - /* STM32F101xG || STM32F103xG || */ - /* STM32F105xC || STM32F107xC */ - - /* if the program operation is completed, disable the OPTPG Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); } return status; @@ -712,11 +768,12 @@ /** * @brief Disable the write protection of the desired pages + * @note An option byte erase is done automatically in this function. * @note When the memory read protection level is selected (RDP level = 1), - * it is not possible to program or erase the flash page i if CortexM4 + * it is not possible to program or erase the flash page i if * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 * - * @param WriteProtectPage: specifies the page(s) to be write unprotected. + * @param WriteProtectPage specifies the page(s) to be write unprotected. * The value of this parameter depend on device used within the same series * @retval HAL status */ @@ -724,58 +781,51 @@ { HAL_StatusTypeDef status = HAL_OK; uint16_t WRP0_Data = 0xFFFF; -#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \ - defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \ - defined(STM32F101xG) || defined(STM32F103xG) || \ - defined(STM32F105xC) || defined(STM32F107xC) - uint16_t WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF; -#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB || */ - /* STM32F100xE || STM32F101xE || STM32F103xE || */ - /* STM32F101xG || STM32F103xG || */ - /* STM32F105xC || STM32F107xC */ +#if defined(FLASH_WRP1_WRP1) + uint16_t WRP1_Data = 0xFFFF; +#endif /* FLASH_WRP1_WRP1 */ +#if defined(FLASH_WRP2_WRP2) + uint16_t WRP2_Data = 0xFFFF; +#endif /* FLASH_WRP2_WRP2 */ +#if defined(FLASH_WRP3_WRP3) + uint16_t WRP3_Data = 0xFFFF; +#endif /* FLASH_WRP3_WRP3 */ /* Check the parameters */ assert_param(IS_OB_WRP(WriteProtectPage)); - /* Low Density and Medium Density */ -#if defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || \ - defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) + /* Get current write protected pages and the new pages to be unprotected ******/ + WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage); + +#if defined(OB_WRP_PAGES0TO15MASK) + WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); +#elif defined(OB_WRP_PAGES0TO31MASK) WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); -#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 || */ - /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */ +#endif /* OB_WRP_PAGES0TO31MASK */ -/* Medium Density */ -#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) - WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8); - WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16); - WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); -#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */ - -/* High Density, XL Density and Connectivity line devices*/ -#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \ - defined(STM32F101xG) || defined(STM32F103xG) || \ - defined(STM32F105xC) || defined(STM32F107xC) - WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); +#if defined(OB_WRP_PAGES16TO31MASK) WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8); +#elif defined(OB_WRP_PAGES32TO63MASK) + WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8); +#endif /* OB_WRP_PAGES32TO63MASK */ + +#if defined(OB_WRP_PAGES64TO95MASK) + WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16); +#endif /* OB_WRP_PAGES64TO95MASK */ +#if defined(OB_WRP_PAGES32TO47MASK) WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16); -#endif /* STM32F100xE || STM32F101xE || STM32F103xE */ - /* STM32F101xG || STM32F103xG */ - /* STM32F105xC || STM32F107xC */ - -/* High Density */ -#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) - WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); -#endif /* STM32F100xE || STM32F101xE || STM32F103xE */ +#endif /* OB_WRP_PAGES32TO47MASK */ -/* XL Density */ -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(OB_WRP_PAGES96TO127MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24); +#elif defined(OB_WRP_PAGES48TO255MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24); +#elif defined(OB_WRP_PAGES48TO511MASK) WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24); -#endif /* STM32F101xG || STM32F103xG */ - -/* Connectivity line devices */ -#if defined(STM32F105xC) || defined(STM32F107xC) +#elif defined(OB_WRP_PAGES48TO127MASK) WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24); -#endif /* STM32F105xC || STM32F107xC */ +#endif /* OB_WRP_PAGES96TO127MASK */ + /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); @@ -785,61 +835,65 @@ /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - SET_BIT(FLASH->CR, FLASH_CR_OPTPG); - - if(WRP0_Data != 0xFF) + /* To be able to write again option byte, need to perform a option byte erase */ + status = HAL_FLASHEx_OBErase(); + if (status == HAL_OK) { - OB->WRP0 |= WRP0_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } -#if defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB) || \ - defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || \ - defined(STM32F101xG) || defined(STM32F103xG) || \ - defined(STM32F105xC) || defined(STM32F107xC) - - if((status == HAL_OK) && (WRP1_Data != 0xFF)) - { - OB->WRP1 |= WRP1_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + +#if defined(FLASH_WRP0_WRP0) + if(WRP0_Data != 0xFF) + { + OB->WRP0 |= WRP0_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP0_WRP0 */ - if((status == HAL_OK) && (WRP2_Data != 0xFF)) - { - OB->WRP2 |= WRP2_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } +#if defined(FLASH_WRP1_WRP1) + if((status == HAL_OK) && (WRP1_Data != 0xFF)) + { + OB->WRP1 |= WRP1_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP1_WRP1 */ - if((status == HAL_OK) && (WRP3_Data != 0xFF)) - { - OB->WRP3 |= WRP3_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); +#if defined(FLASH_WRP2_WRP2) + if((status == HAL_OK) && (WRP2_Data != 0xFF)) + { + OB->WRP2 |= WRP2_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP2_WRP2 */ + +#if defined(FLASH_WRP3_WRP3) + if((status == HAL_OK) && (WRP3_Data != 0xFF)) + { + OB->WRP3 |= WRP3_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_WRP3_WRP3 */ + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); } -#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB ||*/ - /* STM32F100xE || STM32F101xE || STM32F103xE ||*/ - /* STM32F101xG || STM32F103xG ||*/ - /* STM32F105xC || STM32F107xC */ - - /* if the program operation is completed, disable the OPTPG Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); } return status; } /** * @brief Set the read protection level. - * @param ReadProtectLevel: specifies the read protection level. + * @param ReadProtectLevel specifies the read protection level. * This parameter can be one of the following values: - * @arg OB_RDP_LEVEL_0: No protection - * @arg OB_RDP_LEVEL_1: Read protection of the memory - * + * @arg @ref OB_RDP_LEVEL_0 No protection + * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory * @retval HAL status */ static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel) @@ -857,16 +911,29 @@ /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - /* Enable the Option Bytes Programming operation */ - SET_BIT(FLASH->CR, FLASH_CR_OPTPG); - - WRITE_REG(OB->RDP, ReadProtectLevel); - + /* If the previous operation is completed, proceed to erase the option bytes */ + SET_BIT(FLASH->CR, FLASH_CR_OPTER); + SET_BIT(FLASH->CR, FLASH_CR_STRT); + /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - - /* if the program operation is completed, disable the OPTPG Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the erase operation is completed, disable the OPTER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER); + + if(status == HAL_OK) + { + /* Enable the Option Bytes Programming operation */ + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + + WRITE_REG(OB->RDP, ReadProtectLevel); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + } } return status; @@ -875,7 +942,7 @@ /** * @brief Program the FLASH User Option Byte. * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs) - * @param UserConfig: The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2), + * @param UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2), * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4). * And BFBF2(Bit5) for STM32F101xG and STM32F103xG . * @retval HAL status @@ -888,9 +955,9 @@ assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW))); assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST))); assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST))); -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET))); -#endif /* STM32F101xG || STM32F103xG */ +#endif /* FLASH_BANK2_END */ /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); @@ -903,11 +970,11 @@ /* Enable the Option Bytes Programming operation */ SET_BIT(FLASH->CR, FLASH_CR_OPTPG); -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) OB->USER = (UserConfig | 0xF0); #else - OB->USER = (UserConfig | 0xF8); -#endif /* STM32F101xG || STM32F103xG */ + OB->USER = (UserConfig | 0x88); +#endif /* FLASH_BANK2_END */ /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); @@ -921,14 +988,14 @@ /** * @brief Programs a half word at a specified Option Byte Data address. - * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes - * The function HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes + * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes + * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes * (system reset will occur) * Programming of the OB should be performed only after an erase (otherwise PGERR occurs) - * @param Address: specifies the address to be programmed. + * @param Address specifies the address to be programmed. * This parameter can be 0x1FFFF804 or 0x1FFFF806. - * @param Data: specifies the data to be programmed. + * @param Data specifies the data to be programmed. * @retval HAL status */ static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data) @@ -973,21 +1040,27 @@ /** * @brief Returns the FLASH Read Protection level. * @retval FLASH ReadOut Protection Status: - * - SET, when OB_RDP_LEVEL_1 is set - * - RESET, when OB_RDP_LEVEL_0 is set + * This parameter can be one of the following values: + * @arg @ref OB_RDP_LEVEL_0 No protection + * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory */ -static FlagStatus FLASH_OB_GetRDP(void) +static uint32_t FLASH_OB_GetRDP(void) { - FlagStatus readstatus = RESET; + uint32_t readstatus = OB_RDP_LEVEL_0; + uint32_t tmp_reg = 0; + + /* Read RDP level bits */ + tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT); - if (HAL_IS_BIT_SET(FLASH->OBR, FLASH_OBR_RDPRT)) + if (tmp_reg == FLASH_OBR_RDPRT) { - readstatus = SET; + readstatus = OB_RDP_LEVEL_1; } - else + else { - readstatus = RESET; + readstatus = OB_RDP_LEVEL_0; } + return readstatus; } @@ -1000,54 +1073,9 @@ static uint8_t FLASH_OB_GetUser(void) { /* Return the User Option Byte */ - return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> 2); + return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT); } -#if defined(STM32F101xG) || defined(STM32F103xG) -/** - * @brief Wait for a FLASH BANK2 operation to complete. - * @param Timeout: maximum flash operationtimeout - * @retval HAL_StatusTypeDef HAL Status - */ -static HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout) -{ - /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset. - Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error - flag will be set */ - - uint32_t tickstart = HAL_GetTick(); - - while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2)) - { - if (Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) - { - return HAL_TIMEOUT; - } - } - } - - /* Check FLASH End of Operation flag */ - if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2)) - { - /* Clear FLASH End of Operation pending bit */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2); - } - - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)) - { - /*Save the error code*/ - FLASH_SetErrorCode(); - return HAL_ERROR; - } - - /* If there is an error flag set */ - return HAL_OK; - -} -#endif /* STM32F101xG || STM32F103xG */ - /** * @} */ @@ -1060,549 +1088,13 @@ * @{ */ -#if defined(STM32F101xG) || defined(STM32F103xG) -/** @addtogroup FLASH_Exported_Functions - * @{ - */ - -/** @addtogroup FLASH_Exported_Functions_Group2 - * @{ - */ - -/** - * @brief Unlock the FLASH control register access - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASH_Unlock(void) -{ - if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK)) - { - /* Authorize the FLASH BANK1 Registers access */ - WRITE_REG(FLASH->KEYR, FLASH_KEY1); - WRITE_REG(FLASH->KEYR, FLASH_KEY2); - } - else - { - return HAL_ERROR; - } - - - if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK)) - { - /* Authorize the FLASH BANK2 Registers access */ - WRITE_REG(FLASH->KEYR2, FLASH_KEY1); - WRITE_REG(FLASH->KEYR2, FLASH_KEY2); - } - else - { - return HAL_ERROR; - } - - return HAL_OK; -} - -/** - * @brief Locks the FLASH control register access - * @retval HAL Status - */ -HAL_StatusTypeDef HAL_FLASH_Lock(void) -{ - /* Set the LOCK Bit to lock the FLASH BANK1 Registers access */ - SET_BIT(FLASH->CR, FLASH_CR_LOCK); - - /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */ - SET_BIT(FLASH->CR2, FLASH_CR2_LOCK); - - return HAL_OK; -} -/** - * @} - */ - -/** @addtogroup FLASH_Exported_Functions_Group1 - * @{ - */ - -/** - * @brief Program halfword, word or double word at a specified address - * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface - * - * @note If an erase and a program operations are requested simultaneously, - * the erase operation is performed before the program one. - * - * @note FLASH should be previously erased before new programmation (only exception to this - * is when 0x0000 is programmed) - * - * @param TypeProgram: Indicate the way to program at a specified address. - * This parameter can be a value of @ref FLASH_Type_Program - * @param Address: Specifies the address to be programmed. - * @param Data: Specifies the data to be programmed - * - * @retval HAL_StatusTypeDef HAL Status - */ -HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) -{ - HAL_StatusTypeDef status = HAL_ERROR; - uint8_t index = 0; - uint8_t nbiterations = 0; - - /* Process Locked */ - __HAL_LOCK(&pFlash); - - /* Check the parameters */ - assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); - assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); - - if(Address <= FLASH_BANK1_END) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - } - else - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); - } - - if(status == HAL_OK) - { - if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) - { - /* Program halfword (16-bit) at a specified address. */ - nbiterations = 1; - } - else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) - { - /* Program word (32-bit = 2*16-bit) at a specified address. */ - nbiterations = 2; - } - else - { - /* Program double word (64-bit = 4*16-bit) at a specified address. */ - nbiterations = 4; - } - - for (index = 0; index < nbiterations; index++) - { - FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index))); - - if(Address <= FLASH_BANK1_END) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); - - /* If the program operation is completed, disable the PG Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_PG); - } - else - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); - - /* If the program operation is completed, disable the PG Bit */ - CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG); - } - /* In case of error, stop programation procedure */ - if (status != HAL_OK) - { - break; - } - } - } - - /* Process Unlocked */ - __HAL_UNLOCK(&pFlash); - - return status; -} - -/** - * @brief Program halfword, word or double word at a specified address with interrupt enabled. - * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface - * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface - * - * @note If an erase and a program operations are requested simultaneously, - * the erase operation is performed before the program one. - * - * @param TypeProgram: Indicate the way to program at a specified address. - * This parameter can be a value of @ref FLASH_Type_Program - * @param Address: Specifies the address to be programmed. - * @param Data: Specifies the data to be programmed - * - * @retval HAL_StatusTypeDef HAL Status - */ -HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data) -{ - HAL_StatusTypeDef status = HAL_OK; - - /* Process Locked */ - __HAL_LOCK(&pFlash); - - /* If procedure already ongoing, reject the next one */ - if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); - assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); - - if(Address <= FLASH_BANK1_END) - { - /* Enable End of FLASH Operation and Error source interrupts */ - __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1)); - }else - { - /* Enable End of FLASH Operation and Error source interrupts */ - __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2)); - } - - pFlash.Address = Address; - pFlash.Data = Data; - - if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) - { - pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD; - /*Program halfword (16-bit) at a specified address.*/ - pFlash.DataRemaining = 1; - } - else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) - { - pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD; - /*Program word (32-bit : 2*16-bit) at a specified address.*/ - pFlash.DataRemaining = 2; - } - else - { - pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD; - /*Program double word (64-bit : 4*16-bit) at a specified address.*/ - pFlash.DataRemaining = 4; - } - - /*Program halfword (16-bit) at a specified address.*/ - FLASH_Program_HalfWord(Address, (uint16_t)Data); - - return status; -} - -/** - * @brief This function handles FLASH interrupt request. - * @retval None - */ -void HAL_FLASH_IRQHandler(void) -{ - uint32_t addresstmp = 0; - - /* Check FLASH operation error flags */ - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \ - (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))) - { - /*Save the Error code*/ - FLASH_SetErrorCode(); - - /* FLASH error interrupt user callback */ - HAL_FLASH_OperationErrorCallback(pFlash.Address); - - /* Reset address and stop the procedure ongoing*/ - pFlash.Address = 0xFFFFFFFF; - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - - /* Check FLASH End of Operation flag */ - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1)) - { - /* Clear FLASH End of Operation pending bit */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1); - - /* Process can continue only if no error detected */ - if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) - { - if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) - { - /* Nb of pages to erased can be decreased */ - pFlash.DataRemaining--; - - /* Indicate user which page address has been erased*/ - HAL_FLASH_EndOfOperationCallback(pFlash.Address); - - /* Check if there are still pages to erase*/ - if(pFlash.DataRemaining != 0) - { - /* Increment page address to next page */ - pFlash.Address += FLASH_PAGE_SIZE; - addresstmp = pFlash.Address; - - /* Operation is completed, disable the PER Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_PER); - - FLASH_PageErase(addresstmp); - } - else - { - /*No more pages to Erase*/ - - /*Reset Address and stop Erase pages procedure*/ - pFlash.Address = 0xFFFFFFFF; - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - } - else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) - { - /* Operation is completed, disable the MER Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_MER); - - /* Stop Mass Erase procedure if no pending mass erase on other bank */ - if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER)) - { - /* MassErase ended. Return the selected bank*/ - /* FLASH EOP interrupt user callback */ - HAL_FLASH_EndOfOperationCallback(0); - - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - } - else - { - /* Nb of 16-bit data to program can be decreased */ - pFlash.DataRemaining--; - - /* Check if there are still 16-bit data to program */ - if(pFlash.DataRemaining != 0) - { - /* Increment address to 16-bit */ - pFlash.Address += 2; - addresstmp = pFlash.Address; - - /* Shift to have next 16-bit data */ - pFlash.Data = (pFlash.Data >> 16); - - /* Operation is completed, disable the PG Bit */ - CLEAR_BIT(FLASH->CR, FLASH_CR_PG); - - /*Program halfword (16-bit) at a specified address.*/ - FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data); - } - else - { - /*Program ended. Return the selected address*/ - /* FLASH EOP interrupt user callback */ - if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD) - { - HAL_FLASH_EndOfOperationCallback(pFlash.Address); - } - else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD) - { - HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2); - } - else - { - HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6); - } - - /* Reset Address and stop Program procedure*/ - pFlash.Address = 0xFFFFFFFF; - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - } - } - } - - /* Check FLASH End of Operation flag */ - if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2)) - { - /* Clear FLASH End of Operation pending bit */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2); - - /* Process can continue only if no error detected */ - if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) - { - if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) - { - /* Nb of pages to erased can be decreased */ - pFlash.DataRemaining--; - - /* Indicate user which page address has been erased*/ - HAL_FLASH_EndOfOperationCallback(pFlash.Address); - - /* Check if there are still pages to erase*/ - if(pFlash.DataRemaining != 0) - { - /* Increment page address to next page */ - pFlash.Address += FLASH_PAGE_SIZE; - addresstmp = pFlash.Address; - - /* Operation is completed, disable the PER Bit */ - CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER); - - FLASH_PageErase(addresstmp); - } - else - { - /*No more pages to Erase*/ - - /*Reset Address and stop Erase pages procedure*/ - pFlash.Address = 0xFFFFFFFF; - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - } - else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) - { - /* Operation is completed, disable the MER Bit */ - CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); - - if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER)) - { - /* MassErase ended. Return the selected bank*/ - /* FLASH EOP interrupt user callback */ - HAL_FLASH_EndOfOperationCallback(0); - - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - } - else - { - /* Nb of 16-bit data to program can be decreased */ - pFlash.DataRemaining--; - - /* Check if there are still 16-bit data to program */ - if(pFlash.DataRemaining != 0) - { - /* Increment address to 16-bit */ - pFlash.Address += 2; - addresstmp = pFlash.Address; - - /* Shift to have next 16-bit data */ - pFlash.Data = (pFlash.Data >> 16); - - /* Operation is completed, disable the PG Bit */ - CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG); - - /*Program halfword (16-bit) at a specified address.*/ - FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data); - } - else - { - /*Program ended. Return the selected address*/ - /* FLASH EOP interrupt user callback */ - if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD) - { - HAL_FLASH_EndOfOperationCallback(pFlash.Address); - } - else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD) - { - HAL_FLASH_EndOfOperationCallback(pFlash.Address-2); - } - else - { - HAL_FLASH_EndOfOperationCallback(pFlash.Address-6); - } - - /* Reset Address and stop Program procedure*/ - pFlash.Address = 0xFFFFFFFF; - pFlash.ProcedureOnGoing = FLASH_PROC_NONE; - } - } - } - } - - if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) - { - /* Operation is completed, disable the PG, PER and MER Bits for both bank */ - CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER)); - CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER)); - - /* Disable End of FLASH Operation and Error source interrupts for both banks */ - __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2); - - /* Process Unlocked */ - __HAL_UNLOCK(&pFlash); - } -} -/** - * @} - */ - -/** - * @} - */ -#endif /* STM32F101xG || STM32F103xG */ - /** @addtogroup FLASH_Private_Functions * @{ */ /** - * @brief Program a half-word (16-bit) at a specified address. - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed. - * @retval None - */ -void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) -{ - /* Clean the error context */ - pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; - -#if defined(STM32F101xG) || defined(STM32F103xG) - if(Address <= FLASH_BANK1_END) - { -#endif /* STM32F101xG || STM32F103xG */ - /* Proceed to program the new data */ - SET_BIT(FLASH->CR, FLASH_CR_PG); -#if defined(STM32F101xG) || defined(STM32F103xG) - } - else - { - /* Proceed to program the new data */ - SET_BIT(FLASH->CR2, FLASH_CR2_PG); - } -#endif /* STM32F101xG || STM32F103xG */ - - /* Write data in the address */ - *(__IO uint16_t*)Address = Data; -} - -/** - * @brief Set the specific FLASH error flag. - * @retval None - */ -void FLASH_SetErrorCode(void) -{ -#if defined(STM32F101xG) || defined(STM32F103xG) - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2)) -#else - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) -#endif /* STM32F101xG || STM32F103xG */ - { - pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; - } -#if defined(STM32F101xG) || defined(STM32F103xG) - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)) -#else - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) -#endif /* STM32F101xG || STM32F103xG */ - { - pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG; - } - - if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) - { - pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV; - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); - } - - /* Clear FLASH error pending bits */ -#if defined(STM32F101xG) || defined(STM32F103xG) - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2); -#else - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR); -#endif /* STM32F101xG || STM32F103xG */ -} - -/** * @brief Erase the specified FLASH memory page - * @param PageAddress: FLASH page to erase + * @param PageAddress FLASH page to erase * The value of this parameter depend on device used within the same series * * @retval None @@ -1612,7 +1104,7 @@ /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; -#if defined(STM32F101xG) || defined(STM32F103xG) +#if defined(FLASH_BANK2_END) if(PageAddress > FLASH_BANK1_END) { /* Proceed to erase the page */ @@ -1621,13 +1113,15 @@ SET_BIT(FLASH->CR2, FLASH_CR2_STRT); } else -#endif /* STM32F101xG || STM32F103xG */ { +#endif /* FLASH_BANK2_END */ /* Proceed to erase the page */ SET_BIT(FLASH->CR, FLASH_CR_PER); WRITE_REG(FLASH->AR, PageAddress); SET_BIT(FLASH->CR, FLASH_CR_STRT); +#if defined(FLASH_BANK2_END) } +#endif /* FLASH_BANK2_END */ } /** @@ -1638,10 +1132,6 @@ * @} */ -/** - * @} - */ - #endif /* HAL_FLASH_MODULE_ENABLED */ /** * @}