You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.3 KiB
174 lines
4.3 KiB
2 years ago
|
/**
|
||
|
******************************************************************************
|
||
|
* @file EEPROM_Emul/Porting/STM32L4/flash_interface.c
|
||
|
* @author MCD Application Team
|
||
|
* @brief This file provides all the EEPROM emulation flash interface functions.
|
||
|
******************************************************************************
|
||
|
* @attention
|
||
|
*
|
||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
||
|
* All rights reserved.</center></h2>
|
||
|
*
|
||
|
* 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 <inttypes.h>
|
||
|
|
||
|
|
||
|
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****/
|