OT_WEAK ot_u8 vprom_write(vaddr addr, ot_u16 value) { /// 1. Resolve actual address from virtual address -- simple /// 2. If the address is at the start of the block, erase the block /// 3. Write the value to the place it must go #if (VPROM_SIZE <= 0) return ~0; #else static ot_u32 word; // storage for word-write using halfwords ot_u32 paddr; FLASH_Status err; ot_int offset; err = FLASH_COMPLETE; paddr = _vprom_base + addr; // STM32L0 uses 128 byte flash pages. Erase page if on page-start address if ((paddr & (FLASH_PAGE_SIZE-1)) == 0) { err = FLASH_Erase_Page(paddr); } offset = (paddr & 2); *(((ot_u8*)&word) + offset) = value; // Prepare the word and write it, but only when a full word is supplied // We also do unlocking and locking immediately around the write, because // there is some importance in protecting flash memory. if (offset != 0) { FLASH->PRGKEYR = FLASH_PRGKEY1; FLASH->PRGKEYR = FLASH_PRGKEY2; err = FLASH_Program_Word(paddr, word); FLASH->PECR |= FLASH_PECR_PRGLOCK; } return err; #endif }
/** * @brief This function handles FLASH interrupt request. * @param None * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t temp; /* If the program operation is completed, disable the PROG Bit */ FLASH->PECR &= (~FLASH_PECR_PROG); /* If the erase operation is completed, disable the ERASE Bit */ FLASH->PECR &= (~FLASH_PECR_ERASE); /* Check FLASH End of Operation flag */ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { /*Nb of sector to erased can be decreased*/ pFlash.NbPagesToErase--; /* Check if there are still sectors to erase*/ if(pFlash.NbPagesToErase != 0) { temp = pFlash.Page; /*Indicate user which sector has been erased*/ HAL_FLASH_EndOfOperationCallback(temp); /* Clear pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_ENDHV | FLASH_FLAG_WRPERR |\ FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR| FLASH_FLAG_OPTVERR |\ FLASH_FLAG_RDERR | FLASH_FLAG_NOTZEROERR); /*Increment sector number*/ temp = pFlash.Page + PAGESIZE; pFlash.Page = pFlash.Page + PAGESIZE; FLASH_Erase_Page(temp); } else { /*No more sectors to Erase, user callback can be called.*/ /*Reset Sector and stop Erase sectors procedure*/ pFlash.Page = temp = 0xFFFFFFFF; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(temp); /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); } } else { if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) { /*Program ended. Return the selected address*/ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Address); } pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); } } /* Check FLASH operation error flags */ if( (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ENDHV) != RESET) || \ (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)|| (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET) || \ (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) != RESET)|| (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) != RESET) || \ (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) != RESET)) { if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { /*return the faulty sector*/ temp = pFlash.Page; pFlash.Page = 0xFFFFFFFF; } else { /*retrun the faulty address*/ temp = pFlash.Address; } /*Save the Error code*/ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ HAL_FLASH_OperationErrorCallback(temp); /* Clear FLASH error pending bits */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_ENDHV | FLASH_FLAG_WRPERR |\ FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR| FLASH_FLAG_OPTVERR |\ FLASH_FLAG_RDERR | FLASH_FLAG_NOTZEROERR); /*Stop the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { /* Disable End of FLASH Operation interrupt */ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP); /* Disable Error source interrupt */ __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR); /* Process Unlocked */ __HAL_UNLOCK(&pFlash); } }