/** * @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 Program byte, halfword, word or double word at a specified address * @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; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { switch(TypeProgram) { case FLASH_TYPEPROGRAM_BYTE : { /*Program byte (8-bit) at a specified address.*/ FLASH_Program_Byte(Address, (uint8_t) Data); break; } case FLASH_TYPEPROGRAM_HALFWORD : { /*Program halfword (16-bit) at a specified address.*/ FLASH_Program_HalfWord(Address, (uint16_t) Data); break; } case FLASH_TYPEPROGRAM_WORD : { /*Program word (32-bit) at a specified address.*/ FLASH_Program_Word(Address, (uint32_t) Data); break; } case FLASH_TYPEPROGRAM_DOUBLEWORD : { /*Program double word (64-bit) at a specified address.*/ FLASH_Program_DoubleWord(Address, Data); break; } default : break; } /* 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 */ FLASH->CR &= (~FLASH_CR_PG); } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief Program byte, halfword, word or double 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 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)); /* 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_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\ FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_ERSERR); pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; pFlash.Address = Address; switch(TypeProgram) { case FLASH_TYPEPROGRAM_BYTE : { /*Program byte (8-bit) at a specified address.*/ FLASH_Program_Byte(Address, (uint8_t) Data); break; } case FLASH_TYPEPROGRAM_HALFWORD : { /*Program halfword (16-bit) at a specified address.*/ FLASH_Program_HalfWord(Address, (uint16_t) Data); break; } case FLASH_TYPEPROGRAM_WORD : { /*Program word (32-bit) at a specified address.*/ FLASH_Program_Word(Address, (uint32_t) Data); break; } case FLASH_TYPEPROGRAM_DOUBLEWORD : { /*Program double word (64-bit) at a specified address.*/ FLASH_Program_DoubleWord(Address, Data); break; } default : break; } return status; }
/** * @brief Program byte, halfword, word or double 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 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)); /* Enable End of FLASH Operation interrupt */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); /* Enable Error source interrupt */ __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; pFlash.Address = Address; if(TypeProgram == FLASH_TYPEPROGRAM_BYTE) { /*Program byte (8-bit) at a specified address.*/ FLASH_Program_Byte(Address, (uint8_t) Data); } else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) { /*Program halfword (16-bit) at a specified address.*/ FLASH_Program_HalfWord(Address, (uint16_t) Data); } else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) { /*Program word (32-bit) at a specified address.*/ FLASH_Program_Word(Address, (uint32_t) Data); } else { /*Program double word (64-bit) at a specified address.*/ FLASH_Program_DoubleWord(Address, Data); } 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; }
/** * @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 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; } } } }