void SaveCalibrationToFlash(U16 add_off, U8 packet_length) { U8 flashCheckWrite[3] = {0xFF,0xFE,0xFD}; // Erase our configuration Flash page // And copy our Calibration data into it add_off = add_off << 4; if(add_off == 0) { // Erase our configuration Flash page FLASH_PageErase( (FLADDR)(&CalInfo1[0]) ); // And copy our updated data into it FLASH_Write( (FLADDR)(&CalFlashCheck[0]), (U8 *)(&flashCheckWrite[0]), 3); } FLASH_Write( (FLADDR)(&CalInfo1[0]) + add_off, (U8 xdata *)(&MainRegister[SET_SENSOR6]), packet_length); }
/** * @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; }
HAL_StatusTypeDef ee_format(SavedDomain_t* page) { HAL_StatusTypeDef status; status = HAL_FLASH_Unlock(); if(status != HAL_OK) { return status; } //FLASH_PageErase(PAGE0_BASE_ADDRESS); FLASH_PageErase((uint32_t)page); status = FLASH_WaitForLastOperation(FLASH_TIMEOUT); if(status != HAL_OK) { return status; } CLEAR_BIT(FLASH->CR, FLASH_CR_PER); HAL_FLASH_Lock(); return status; }
/* begin_addr,被写数据Flash开始地址;counter,连续写多少个字节; array[],数据来源 */ UCHAR sequential_write_flash_in_one_sector(UINT begin_addr, UINT counter, UCHAR array[]) { UINT i = 0; UINT in_sector_begin_addr = 0; UINT sector_addr = 0; FLASH_PageErase(begin_addr); for(i=0; i<counter; i++) { /* 写一个字节 */ FLASH_ByteWrite(begin_addr, array[i]); /* 比较对错 */ if (FLASH_ByteRead(begin_addr) != array[i]) { IAP_Disable(); return 0; } begin_addr++; } IAP_Disable(); return 1; }
/** * @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; }
/** * @brief This function handles FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t addresstmp; /* If the operation is completed, disable the PG, PER and MER Bits */ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER)); /* 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(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; 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) { /*MassErase ended. Return the selected bank*/ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(0); /* Stop Mass Erase procedure*/ 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); /*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; } }
/** * @brief Handle FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t tmp_page; /* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_MER2 | FLASH_CR_PER | FLASH_CR_PNB)); /* Disable the FSTPG Bit only if it is the last row programmed */ if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST) { CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG); } /* Check FLASH operation error flags */ if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_MISERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_FASTERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD))) { /*Save the error code*/ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE) { HAL_FLASH_EndOfOperationCallback(pFlash.Page); } else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASS_ERASE) { HAL_FLASH_EndOfOperationCallback(pFlash.Bank); } else if((pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) || (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)) { HAL_FLASH_OperationErrorCallback(pFlash.Address); } HAL_FLASH_OperationErrorCallback(pFlash.Address); /*Stop the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* 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(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE) { /* Nb of pages to erased can be decreased */ pFlash.NbPagesToErase--; /* Check if there are still pages to erase*/ if(pFlash.NbPagesToErase != 0) { /* Indicate user which page has been erased*/ HAL_FLASH_EndOfOperationCallback(pFlash.Page); /* Increment page number */ pFlash.Page++; tmp_page = pFlash.Page; FLASH_PageErase(tmp_page, pFlash.Bank); } else { /* No more pages to Erase */ /* Reset Address and stop Erase pages procedure */ pFlash.Page = 0xFFFFFFFF; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches() ; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Page); } } else { if(pFlash.ProcedureOnGoing == FLASH_PROC_MASS_ERASE) { /* MassErase ended. Return the selected bank */ /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches() ; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Bank); } else if((pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) || (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)) { /* Program ended. Return the selected address */ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Address); } /*Clear the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { /* Disable End of Operation and Error interrupts */ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR); /* Process Unlocked */ __HAL_UNLOCK(&pFlash); } }
/** * @brief This function handles FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t addresstmp = 0; /* Check FLASH operation error flags */ #if defined(FLASH_BANK2_END) 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))) #else if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) #endif /* FLASH_BANK2_END */ { /*return the faulty address*/ addresstmp = pFlash.Address; /* Reset address */ pFlash.Address = 0xFFFFFFFF; /*Save the Error code*/ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ HAL_FLASH_OperationErrorCallback(addresstmp); /* Stop the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* Check FLASH End of Operation flag */ #if defined(FLASH_BANK2_END) if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1); #else if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); #endif /* FLASH_BANK2_END */ /* 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--; /* Check if there are still pages to erase*/ if(pFlash.DataRemaining != 0) { addresstmp = pFlash.Address; /*Indicate user which sector has been erased*/ HAL_FLASH_EndOfOperationCallback(addresstmp); /*Increment sector number*/ addresstmp = pFlash.Address + FLASH_PAGE_SIZE; pFlash.Address = addresstmp; /* If the erase operation is completed, disable the PER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PER); FLASH_PageErase(addresstmp); } else { /*No more pages to Erase, user callback can be called.*/ /*Reset Sector and stop Erase pages procedure*/ pFlash.Address = addresstmp = 0xFFFFFFFF; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(addresstmp); } } else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) { /* Operation is completed, disable the MER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_MER); #if defined(FLASH_BANK2_END) /* Stop Mass Erase procedure if no pending mass erase on other bank */ if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER)) { #endif /* FLASH_BANK2_END */ /* MassErase ended. Return the selected bank*/ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(0); /* Stop Mass Erase procedure*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } #if defined(FLASH_BANK2_END) } #endif /* FLASH_BANK2_END */ 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; } } } }
/** * @brief This function handles FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t addresstmp = 0U; /* Check FLASH operation error flags */ if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) || #if defined(FLASH_SR_RDERR) __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) || #endif /* FLASH_SR_RDERR */ #if defined(FLASH_SR_OPTVERRUSR) __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR) || #endif /* FLASH_SR_OPTVERRUSR */ __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ) { if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { /* Return the faulty sector */ addresstmp = pFlash.Page; pFlash.Page = 0xFFFFFFFFU; } else { /* Return the faulty address */ addresstmp = pFlash.Address; } /* Save the Error code */ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ HAL_FLASH_OperationErrorCallback(addresstmp); /* Stop the procedure ongoing */ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* 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); /* 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.NbPagesToErase--; /* Check if there are still pages to erase */ if(pFlash.NbPagesToErase != 0U) { addresstmp = pFlash.Page; /*Indicate user which sector has been erased */ HAL_FLASH_EndOfOperationCallback(addresstmp); /*Increment sector number*/ addresstmp = pFlash.Page + FLASH_PAGE_SIZE; pFlash.Page = addresstmp; /* If the erase operation is completed, disable the ERASE Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE); FLASH_PageErase(addresstmp); } else { /* No more pages to Erase, user callback can be called. */ /* Reset Sector and stop Erase pages procedure */ pFlash.Page = addresstmp = 0xFFFFFFFFU; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(addresstmp); } } else { /* If the program operation is completed, disable the PROG Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG); /* Program ended. Return the selected address */ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Address); /* Reset Address and stop Program procedure */ pFlash.Address = 0xFFFFFFFFU; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } } if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { /* Operation is completed, disable the PROG and ERASE */ CLEAR_BIT(FLASH->PECR, (FLASH_PECR_ERASE | FLASH_PECR_PROG)); /* Disable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); /* Process Unlocked */ __HAL_UNLOCK(&pFlash); } }
/** * @brief This function handles FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t addresstmp = 0; /* Check FLASH operation error flags */ /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices, * (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving * as expected. If the user run an application using the first * cut of the STM32L031xx device or the first cut of the STM32L041xx * device, the check on the FLASH_FLAG_OPTVERR bit should be ignored. * * Note :The revId of the device can be retrieved via the HAL_GetREVID() * function. * */ if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) ) { if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { /* Return the faulty sector */ addresstmp = pFlash.Page; pFlash.Page = 0xFFFFFFFFU; } else { /* Return the faulty address */ addresstmp = pFlash.Address; } /* Save the Error code */ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ HAL_FLASH_OperationErrorCallback(addresstmp); /* Stop the procedure ongoing */ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* 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); /* 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.NbPagesToErase--; /* Check if there are still pages to erase */ if(pFlash.NbPagesToErase != 0U) { addresstmp = pFlash.Page; /*Indicate user which sector has been erased */ HAL_FLASH_EndOfOperationCallback(addresstmp); /*Increment sector number*/ addresstmp = pFlash.Page + FLASH_PAGE_SIZE; pFlash.Page = addresstmp; /* If the erase operation is completed, disable the ERASE Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE); FLASH_PageErase(addresstmp); } else { /* No more pages to Erase, user callback can be called. */ /* Reset Sector and stop Erase pages procedure */ pFlash.Page = addresstmp = 0xFFFFFFFFU; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(addresstmp); } } else { /* If the program operation is completed, disable the PROG Bit */ CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG); /* Program ended. Return the selected address */ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Address); /* Reset Address and stop Program procedure */ pFlash.Address = 0xFFFFFFFFU; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } } if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { /* Operation is completed, disable the PROG and ERASE */ CLEAR_BIT(FLASH->PECR, (FLASH_PECR_ERASE | FLASH_PECR_PROG)); /* Disable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); /* Process Unlocked */ __HAL_UNLOCK(&pFlash); } }
//----------------------------------------------------------------------------- // FLASH_Clear //----------------------------------------------------------------------------- // // This routine erases <numbytes> starting from the FLASH addressed by // <dest> by performing a read-modify-write operation using <FLASH_TEMP> as // a temporary holding area. This function accepts <numbytes> up to // <FLASH_PAGESIZE>. // void FLASH_Clear (FLADDR dest, unsigned numbytes) { FLADDR dest_1_page_start; // first address in 1st page // containing <dest> FLADDR dest_1_page_end; // last address in 1st page // containing <dest> FLADDR dest_2_page_start; // first address in 2nd page // containing <dest> FLADDR dest_2_page_end; // last address in 2nd page // containing <dest> unsigned numbytes_remainder; // when crossing page boundary, // number of <src> bytes on 2nd page unsigned FLASH_pagesize; // size of FLASH page to update FLADDR wptr; // write address FLADDR rptr; // read address unsigned length; FLASH_pagesize = FLASH_PAGESIZE; dest_1_page_start = dest & ~(FLASH_pagesize - 1); dest_1_page_end = dest_1_page_start + FLASH_pagesize - 1; dest_2_page_start = (dest + numbytes) & ~(FLASH_pagesize - 1); dest_2_page_end = dest_2_page_start + FLASH_pagesize - 1; if (dest_1_page_end == dest_2_page_end) { // 1. Erase Scratch page FLASH_PageErase (FLASH_TEMP); // 2. Copy bytes from first byte of dest page to dest-1 to Scratch page wptr = FLASH_TEMP; rptr = dest_1_page_start; length = dest - dest_1_page_start; FLASH_Copy (wptr, rptr, length); // 3. Copy from (dest+numbytes) to dest_page_end to Scratch page wptr = FLASH_TEMP + dest - dest_1_page_start + numbytes; rptr = dest + numbytes; length = dest_1_page_end - dest - numbytes + 1; FLASH_Copy (wptr, rptr, length); // 4. Erase destination page FLASH_PageErase (dest_1_page_start); // 5. Copy Scratch page to destination page wptr = dest_1_page_start; rptr = FLASH_TEMP; length = FLASH_pagesize; FLASH_Copy (wptr, rptr, length); } else { // value crosses page boundary // 1. Erase Scratch page FLASH_PageErase (FLASH_TEMP); // 2. Copy bytes from first byte of dest page to dest-1 to Scratch page wptr = FLASH_TEMP; rptr = dest_1_page_start; length = dest - dest_1_page_start; FLASH_Copy (wptr, rptr, length); // 3. Erase destination page 1 FLASH_PageErase (dest_1_page_start); // 4. Copy Scratch page to destination page 1 wptr = dest_1_page_start; rptr = FLASH_TEMP; length = FLASH_pagesize; FLASH_Copy (wptr, rptr, length); // now handle 2nd page // 5. Erase Scratch page FLASH_PageErase (FLASH_TEMP); // 6. Copy bytes from numbytes remaining to dest-2_page_end to Scratch page numbytes_remainder = numbytes - (dest_1_page_end - dest + 1); wptr = FLASH_TEMP + numbytes_remainder; rptr = dest_2_page_start + numbytes_remainder; length = FLASH_pagesize - numbytes_remainder; FLASH_Copy (wptr, rptr, length); // 7. Erase destination page 2 FLASH_PageErase (dest_2_page_start); // 8. Copy Scratch page to destination page 2 wptr = dest_2_page_start; rptr = FLASH_TEMP; length = FLASH_pagesize; FLASH_Copy (wptr, rptr, length); } }
void main (void) { unsigned char temp_byte = 0x00; FLADDR start_address = 0x5FFE; char test_write_buff[8] = "ABCDEFG"; char test_write_buff2[3] = "HIJ"; char test_read_buff[8] = {0}; char test_compare_buff[8] = "ABCDEFG"; unsigned char i; bit error_flag = 0; PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer // enable) if ((RSTSRC & 0x02) != 0x02) { if ((RSTSRC & 0x40) == 0x40) { LED = 0; while(1); // Last reset was caused by a Flash // Error Device Reset // LED is off and loop forever to // indicate error } } Oscillator_Init(); // Initialize the internal oscillator // to 24.5 MHz VDDMon_Init(); Port_Init(); LED = 1; SFRPAGE = LEGACY_PAGE; // Initially erase the test page of Flash FLASH_PageErase(start_address); //BEGIN TEST================================================================ // Check if able to Write and Read the Flash-------------------------------- FLASH_ByteWrite(start_address, 0xA5); temp_byte = FLASH_ByteRead(start_address); if (temp_byte != 0xA5) { error_flag = 1; } //-------------------------------------------------------------------------- // Check if able to Erase a page of the Flash------------------------------- FLASH_PageErase(start_address); temp_byte = FLASH_ByteRead(start_address); if (temp_byte != 0xFF) { error_flag = 1; } //-------------------------------------------------------------------------- // Check if able to write and read a series of bytes------------------------ FLASH_Write(start_address, test_write_buff, sizeof(test_write_buff)); FLASH_Read(test_read_buff, start_address, sizeof(test_write_buff)); for (i = 0; i < sizeof(test_write_buff); i++) { if (test_read_buff[i] != test_write_buff[i]) { error_flag = 1; } } //-------------------------------------------------------------------------- // Check if able to Erase a few bytes--------------------------------------- FLASH_Clear(start_address, 2); FLASH_Read(test_read_buff, start_address, sizeof(test_write_buff)); // Simulate the same changes to a data array for comparison test_compare_buff[0] = 0xFF; test_compare_buff[1] = 0xFF; for (i = 0; i < sizeof(test_compare_buff); i++) { if (test_read_buff[i] != test_compare_buff[i]) { error_flag = 1; } } //-------------------------------------------------------------------------- // Check if able to "update" (erase then re-write) a few bytes-------------- FLASH_Update (start_address, test_write_buff2, 3); FLASH_Read(test_read_buff, start_address, sizeof(test_write_buff)); // Simulate the same changes to a data array for comparison test_compare_buff[0] = test_write_buff2[0]; test_compare_buff[1] = test_write_buff2[1]; test_compare_buff[2] = test_write_buff2[2]; for (i = 0; i < sizeof(test_compare_buff); i++) { if (test_read_buff[i] != test_compare_buff[i]) { error_flag = 1; } } //-------------------------------------------------------------------------- // Check if able to copy data in the Flash---------------------------------- FLASH_Copy (start_address+sizeof(test_write_buff), start_address, sizeof(test_write_buff)); FLASH_Read(test_read_buff, start_address+sizeof(test_write_buff), sizeof(test_read_buff)); for (i = 0; i < sizeof(test_write_buff); i++) { if (test_read_buff[i] != test_compare_buff[i]) { error_flag = 1; } } //-------------------------------------------------------------------------- // FLASH test routines------------------------------------------------------ FLASH_Fill (start_address+sizeof(test_write_buff)*2, sizeof(test_write_buff), 0x5A); FLASH_Read(test_read_buff, start_address+sizeof(test_write_buff)*2, sizeof(test_write_buff)); for (i = 0; i < sizeof(test_write_buff); i++) { if (test_read_buff[i] != 0x5A) { error_flag = 1; } } //-------------------------------------------------------------------------- //END OF TEST=============================================================== while (1) // Loop forever { // Blink LED to indicate success if (error_flag == 0) { LED = ~LED; Timer0_Delay_ms (100); } else { LED = 0; } } }