/** * @brief Configure the Proprietary code readout protection of the desired addresses * * @note To configure the PCROP options, the option lock bit OPTLOCK must be * cleared with the call of the HAL_FLASH_OB_Unlock() function. * @note To validate the PCROP options, the option bytes must be reloaded * through the call of the HAL_FLASH_OB_Launch() function. * * @param PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not * when RDP level decreased from Level 1 to Level 0. * This parameter must be a value of @arg FLASH_OB_PCROP_RDP enumeration * * @param PCROPStartAddr specifies the start address of the Proprietary code readout protection * This parameter can be an address between begin and end of the bank * * @param PCROPEndAddr specifies the end address of the Proprietary code readout protection * This parameter can be an address between PCROPStartAddr and end of the bank * * @param Banks the specific bank to apply PCROP sectors * This parameter can be one of the following values: * @arg FLASH_BANK_1: PCROP on specified bank1 area * @arg FLASH_BANK_2: PCROP on specified bank2 area * @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks) * * @retval HAL Status */ static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_FLASH_BANK(Banks)); assert_param(IS_OB_PCROP_RDP(PCROPConfig)); assert_param(IS_FLASH_PROGRAM_ADDRESS(PCROPStartAddr)); assert_param(IS_FLASH_PROGRAM_ADDRESS(PCROPEndAddr)); if((Banks & FLASH_BANK_1) == FLASH_BANK_1) { assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr)); assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE,FLASH_BANK_1); if(status == HAL_OK) { /* Configure the Proprietary code readout protection */ FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8); FLASH->PRAR_PRG1 |= (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << POSITION_VAL(FLASH_PRAR_PROT_AREA_END)) ; FLASH->PRAR_PRG1 |= PCROPConfig; /* Wait for last operation to be completed */ status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); }
/** * @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); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); #if defined(FLASH_BANK2_END) /* If procedure already ongoing, reject the next one */ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) { return HAL_ERROR; } 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); } #else /* Enable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); #endif /* FLASH_BANK2_END */ 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 Erases a specified page in program memory. * @note To correctly run this function, the FLASH_Unlock() function must be called before. * @note Call the FLASH_Lock() to disable the flash memory access (recommended * to protect the FLASH memory against possible unwanted operation) * @param Page_Address: The page address in program memory to be erased. * @note A Page is erased in the Program memory only if the address to load * is the start address of a page (multiple of 1024 bytes). * @retval FLASH Status: The returned value can be: * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(Page_Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); if(status == FLASH_COMPLETE) { /* If the previous operation is completed, proceed to erase the page */ FLASH->CR |= FLASH_CR_PER; FLASH->AR = Page_Address; FLASH->CR |= FLASH_CR_STRT; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); /* Disable the PER Bit */ FLASH->CR &= ~FLASH_CR_PER; } /* Return the Erase Status */ return status; }
/** * @brief Program word at a specified address with interrupt enabled. * @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(&ProcFlash); /* Check the parameters */ assert_param(IS_TYPEPROGRAMFLASH(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Enable End of FLASH Operation interrupt */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); /* Enable Error source interrupt */ __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); /* Clear pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_MASK); ProcFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; ProcFlash.Address = Address; if(TypeProgram == TYPEPROGRAM_WORD) { /*Program word (32-bit) at a specified address.*/ *(__IO uint32_t *)Address = Data; } /* Process Unlocked */ __HAL_UNLOCK(&ProcFlash); return status; }
/** * @brief Programs a word at a specified address. * @note To correctly run this function, the FLASH_Unlock() function * must be called before. * Call the FLASH_Lock() to disable the flash memory access * (recommended to protect the FLASH memory against possible unwanted operation) * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) { FLASH_Status status = FLASH_COMPLETE; __IO uint32_t tmp = 0; /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); if (status == FLASH_COMPLETE) { /* If the previous operation is completed, proceed to program the new first half word */ FLASH->CR |= FLASH_CR_PG; *(__IO uint16_t*)Address = (uint16_t)Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); if (status == FLASH_COMPLETE) { /* If the previous operation is completed, proceed to program the new second half word */ tmp = Address + 2; *(__IO uint16_t*) tmp = Data >> 16; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); /* Disable the PG Bit */ FLASH->CR &= ~FLASH_CR_PG; } else {
/** * @brief Program word at a specified address with interrupt enabled. * * @param TypeProgram Indicate the way to program at a specified address. * This parameter can be a value of @ref FLASH_Type_Program * @param Address Specifie the address to be programmed. * @param Data Specifie the data to be programmed * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t Data) { HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Enable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); pFlash.Address = Address; pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; if(TypeProgram == FLASH_TYPEPROGRAM_WORD) { /* Program word (32-bit) at a specified address. */ *(__IO uint32_t *)Address = Data; } return status; }
/** * @brief Program word at a specified address * @note To correctly run this function, the HAL_FLASH_Unlock() function * must be called before. * Call the HAL_FLASH_Lock() to disable the flash memory access * (recommended to protect the FLASH memory against possible unwanted operation). * * @param TypeProgram Indicate the way to program at a specified address. * This parameter can be a value of @ref FLASH_Type_Program * @param Address Specifie the address to be programmed. * @param Data Specifie the data to be programmed * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data) { HAL_StatusTypeDef status = HAL_ERROR; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; /*Program word (32-bit) at a specified address.*/ *(__IO uint32_t *)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) { if (!(IS_FLASH_PROGRAM_ADDRESS(address))) { return MBED_FLASH_INVALID_SIZE; } else { return FLASH_PAGE_SIZE; } }
/** * @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. * * @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_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { if(TypeProgram == TYPEPROGRAM_HALFWORD) { /* Program halfword (16-bit) at a specified address. */ nbiterations = 1; } else if(TypeProgram == 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))); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE); /* Check FLASH End of Operation flag */ if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); } /* If the program operation is completed, disable the PG Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PG); } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @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 Specifie the address to be programmed. * @param Data Specifie 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 = 0U; uint8_t nbiterations = 0U; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) { /* Program halfword (16-bit) at a specified address. */ nbiterations = 1U; } else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) { /* Program word (32-bit = 2*16-bit) at a specified address. */ nbiterations = 2U; } else { /* Program double word (64-bit = 4*16-bit) at a specified address. */ nbiterations = 4U; } for (index = 0U; index < nbiterations; index++) { FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*index))); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); /* If the program operation is completed, disable the PG Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PG); /* In case of error, stop programation procedure */ if (status != HAL_OK) { break; } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief Program word (32-bit) at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval None */ static void FLASH_Program_Word(uint32_t Address, uint32_t Data) { /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Clean the error context */ ProcFlash.ErrorCode = HAL_FLASH_ERROR_NONE; *(__IO uint32_t*)Address = Data; }
/** * @brief Program word (32-bit) at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval None */ static void FLASH_Program_Word(uint32_t Address, uint32_t Data) { /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Set PROG bit */ FLASH->PECR |= FLASH_PECR_PROG; *(__IO uint32_t*)Address = Data; }
/** * @brief Program double-word (64-bit) at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval None */ static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data) { /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Set PG bit */ SET_BIT(FLASH->CR, FLASH_CR_PG); /* Program the double word */ *(__IO uint32_t*)Address = (uint32_t)Data; *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32); }
/** * @brief This function writes the NDEF file from the RAM to the FLASH * @param dataToWrite : The buffer which contains the memory to be written * @param size : The buffer size * @param address : The destination address inside the FLASH * @retval FLASH_OK : The file is written successfully * @retval FLASH_ERROR_SIZE : The NDEF size is higher than the FLASH available */ uint8_t writeNDEFToFlash(uint8_t *dataToWrite, uint32_t size, uint32_t address) { #ifndef DISABLE_NDEF_FLASH int32_t j; uint32_t data=0; uint32_t *pdata; uint32_t EraseCounter = 0x0; uint32_t NbrOfPage = 0; FLASH_Status FLASHStatus = FLASH_COMPLETE; /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (!IS_FLASH_PROGRAM_ADDRESS(size + FLASH_MAGIC_NUMBER_LENTH + address)) { return FLASH_ERROR_SIZE; } /* Unlock the FLASH */ FLASH_Unlock(); /* Clear All pending flags */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); /* Erase the needed pages where the user application will be loaded */ /* Define the number of page to be erased */ NbrOfPage = FLASH_PagesMask(size + FLASH_MAGIC_NUMBER_LENTH); /* Erase the FLASH pages */ for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(address + (PAGE_SIZE * EraseCounter)); } pdata = (uint32_t*)(dataToWrite); /* Write the magic number */ FLASH_ProgramWord(address,FLASH_MAGIC_NUMBER); address+=FLASH_MAGIC_NUMBER_LENTH; for(j=0;j<size;j+=4) { data = *pdata; FLASH_ProgramWord(address,data); pdata++; address += 4; } /* Lock the FLASH */ FLASH_Lock(); #endif return FLASH_OK; }
/** * @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 */ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) { 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_TYPEERASE(pEraseInit->TypeErase)); /* Enable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); #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); #endif if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; FLASH_MassErase(pEraseInit->Banks); } else { /* Erase by page to be done*/ /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE; pFlash.DataRemaining = pEraseInit->NbPages; pFlash.Address = pEraseInit->PageAddress; /*Erase 1st page and wait for IT*/ FLASH_PageErase(pEraseInit->PageAddress); } 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); /* Check the parameters */ assert_param(IS_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* Enable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_ENABLE_IT((FLASH_IT_EOP | FLASH_IT_ERR)); pFlash.Address = Address; pFlash.Data = Data; if(TypeProgram == TYPEPROGRAM_HALFWORD) { pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD; /*Program halfword (16-bit) at a specified address.*/ pFlash.DataRemaining = 1; } else if(TypeProgram == 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; }
int32_t flash_erase_sector(flash_t *obj, uint32_t address) { uint32_t PAGEError = 0; FLASH_EraseInitTypeDef EraseInitStruct; int32_t status = 0; if (!(IS_FLASH_PROGRAM_ADDRESS(address))) { return -1; } if (flash_unlock() != HAL_OK) { return -1; } // Clear Flash status register's flags __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_OPTVERR); /* MBED HAL erases 1 sector at a time */ /* Fill EraseInit structure*/ EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = address; EraseInitStruct.NbPages = 1; /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache, you have to make sure that these data are rewritten before they are accessed during code execution. If this cannot be done safely, it is recommended to flush the caches by setting the DCRST and ICRST bits in the FLASH_CR register. */ if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) { status = -1; } flash_lock(); return status; }
/** * @brief Perform a mass erase or erase the specified FLASH memory pages * @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 * contains the configuration information on faulty page in case of error * (0xFFFFFFFF means that all the pages have been correctly erased) * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError) { HAL_StatusTypeDef status = HAL_ERROR; uint32_t address = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { #if defined(FLASH_BANK2_END) if (pEraseInit->Banks == FLASH_BANK_BOTH) { /* Mass Erase requested for Bank1 and Bank2 */ /* Wait for last operation to be completed */ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)) { /*Mass erase to be done*/ FLASH_MassErase(FLASH_BANK_BOTH); /* Wait for last operation to be completed */ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)) { status = HAL_OK; } /* If the erase operation is completed, disable the MER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_MER); CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); } } else if (pEraseInit->Banks == FLASH_BANK_2) { /* Mass Erase requested for Bank2 */ /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Mass erase to be done*/ FLASH_MassErase(FLASH_BANK_2); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the MER Bit */ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); } } else #endif /* FLASH_BANK2_END */ { /* Mass Erase requested for Bank1 */ /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Mass erase to be done*/ FLASH_MassErase(FLASH_BANK_1); /* 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 { /* Page Erase is requested */ /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); #if defined(FLASH_BANK2_END) /* Page Erase requested on address located on bank2 */ if(pEraseInit->PageAddress > FLASH_BANK1_END) { /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Initialization of PageError variable*/ *PageError = 0xFFFFFFFF; /* Erase by page by page to be done*/ for(address = pEraseInit->PageAddress; address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE); address += FLASH_PAGE_SIZE) { FLASH_PageErase(address); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the PER Bit */ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER); if (status != HAL_OK) { /* In case of error, stop erase procedure and return the faulty address */ *PageError = address; break; } } } } else #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) { /*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) { 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; } } } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) { uint32_t StartAddress = 0; int32_t status = 0; if (!(IS_FLASH_PROGRAM_ADDRESS(address))) { return -1; } if ((size % MIN_PROG_SIZE) != 0) { return -1; } if (flash_unlock() != HAL_OK) { return -1; } /* Program the user Flash area word by word */ StartAddress = address; /* HW needs an aligned address to program flash, which data parameter doesn't ensure */ if ((uint32_t) data % 4 != 0) { volatile uint32_t data32; while (address < (StartAddress + size) && (status == 0)) { for (uint8_t i = 0; i < MIN_PROG_SIZE; i++) { *(((uint8_t *) &data32) + i) = *(data + i); } if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) { address = address + MIN_PROG_SIZE; data = data + MIN_PROG_SIZE; } else { status = -1; } } } else { /* case where data is aligned, so let's avoid any copy */ while ((address < (StartAddress + size)) && (status == 0)) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) { address = address + MIN_PROG_SIZE; data = data + MIN_PROG_SIZE; } else { status = -1; } } } flash_lock(); return status; }