/** ****************************************************************************** * @file EEPROM_Emul/Porting/STM32L4/flash_interface.c * @author MCD Application Team * @brief This file provides all the EEPROM emulation flash interface functions. ****************************************************************************** * @attention * *

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "eeprom_emul.h" #include "flash_interface.h" #include "snprintf.h" #include static inline void FI_Raw_ProgramHalfword(uint32_t Address, uint16_t value) { *(__IO uint16_t *) (Address) = value; /* Wait programmation completion */ while (FLASH->SR & FLASH_SR_BSY) { } } static inline void FI_Raw_ProgramWord(uint32_t Address, uint32_t value) { FI_Raw_ProgramHalfword(Address, value & 0xFFFF); FI_Raw_ProgramHalfword(Address + 2, value >> 16); } static void FI_Raw_ProgramDoubleWord(uint32_t Address, uint64_t value) { FI_Raw_ProgramWord(Address, value & 0xFFFFFFFFUL); FI_Raw_ProgramWord(Address + 4, value >> 32); } /** @addtogroup EEPROM_Private_Functions * @{ */ static void UnlockFlash() { FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; } static void LockFlash() { FLASH->CR |= FLASH_CR_LOCK; } /** * @brief Write a double word at the given address in Flash * @param Address Where to write * @param Data What to write * @retval EE_Status * - EE_OK: on success * - EE_WRITE_ERROR: if an error occurs */ EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data) { PRINTF("FI wr %p, val %016"PRIx64"\r\n", (void *) Address, Data); EE_Status status = EE_OK; if (FLASH->CR & FLASH_CR_LOCK) { UnlockFlash(); } /* Set FLASH Programmation bit */ FLASH->CR |= FLASH_CR_PG; /* Program double word of value 0 */ FI_Raw_ProgramDoubleWord(Address, Data); /* Check if error occured */ if (FLASH->SR & (FLASH_SR_WRPRTERR | FLASH_SR_PGERR)) { PUTS("Flash write error\r\n"); status = EE_WRITE_ERROR; } /* Check FLASH End of Operation flag */ if (FLASH->SR & FLASH_SR_EOP) { /* Clear FLASH End of Operation pending bit */ FLASH->SR = FLASH_SR_EOP; } /* Clear FLASH Programmation bit */ FLASH->CR &= ~FLASH_CR_PG; LockFlash(); return status; } /** * @brief Erase a page in polling mode * @param Page Page number * @param NbPages Number of pages to erase * @retval EE_Status * - EE_OK: on success * - EE error code: if an error occurs */ EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) { PRINTF("FI erase page %d, nbr %d\r\n", Page, NbPages); EE_Status status = EE_OK; if (FLASH->CR & FLASH_CR_LOCK) { UnlockFlash(); } /* Set FLASH Programmation bit */ FLASH->CR |= FLASH_CR_PER; while (NbPages-- > 0) { FLASH->AR = Page * FLASH_PAGE_SIZE; FLASH->CR |= FLASH_CR_STRT; /* Wait programmation completion */ while (FLASH->SR & FLASH_SR_BSY) { } Page++; } FLASH->CR &= ~FLASH_CR_PER; LockFlash(); return status; } /** * @brief Flush the caches if needed to keep coherency when the flash content is modified */ void FI_CacheFlush() { // f1 doesn't have cache } /** * @brief Delete corrupted Flash address, can be called from NMI. No Timeout. * @param Address Address of the FLASH Memory to delete * @retval EE_Status * - EE_OK: on success * - EE error code: if an error occurs */ EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) { EE_Status rv = FI_WriteDoubleWord(Address, 0); if (rv == EE_WRITE_ERROR) { rv = EE_DELETE_ERROR; } return rv; } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/