Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
initial Commit
  • Loading branch information
danyhm authored Mar 2, 2018
1 parent 12b4a3d commit 374b3ee
Show file tree
Hide file tree
Showing 3 changed files with 346 additions and 0 deletions.
256 changes: 256 additions & 0 deletions eeprom.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
#include "eeprom.h"
#include "eepromConfig.h"

//##########################################################################################################
#define _X_BYTE_ROUNDUP(Dividend,Divisor) ((Dividend/Divisor)+(Dividend%Divisor==0?0:1))
//##########################################################################################################
//copy page to transfer page excluding the bad data
static bool EE_PageTransfer(uint32_t PageAddress,uint16_t BadDataOffset,uint16_t BadDataNum);
static uint32_t EE_FindPageAddressOfVirtualAddress(uint16_t VirtualAddress);
static uint16_t EE_FindVirtualAddressOffset(uint16_t VirtualAddress);
//##########################################################################################################
bool EE_FormatPage(uint32_t PageAddress)
{
uint32_t error;
FLASH_EraseInitTypeDef flashErase;
HAL_FLASH_Unlock();
flashErase.NbPages=1;
#if(_CORTEX_!=M0)
flashErase.Banks = FLASH_BANK_1;
#endif
flashErase.TypeErase = FLASH_TYPEERASE_PAGES;
flashErase.PageAddress = PageAddress;
if(HAL_FLASHEx_Erase(&flashErase,&error)==HAL_OK)
{
HAL_FLASH_Lock();
if(error != 0xFFFFFFFF)
return false;
else
return true;
}
HAL_FLASH_Lock();
return false;
}
//##########################################################################################################
bool EE_Read(uint16_t VirtualAddress, uint32_t* Data)
{
if(VirtualAddress >= _EEPROM_End_VirtualAddr)
return false;
*Data = (*(__IO uint32_t*)((VirtualAddress*4)+_EEPROM_START_FLASH_PAGE_ADDRESS));
return true;
}
//##########################################################################################################
bool EE_Reads(uint16_t StartVirtualAddress,uint16_t HowMuchToRead,uint32_t* Data)
{
if((StartVirtualAddress+HowMuchToRead) > _EEPROM_End_VirtualAddr)
return false;
for(uint16_t i=StartVirtualAddress ; i<HowMuchToRead+StartVirtualAddress ; i++)
{
*Data = (*(__IO uint32_t*)((i*4)+_EEPROM_START_FLASH_PAGE_ADDRESS));
Data++;
}
return true;
}
//##########################################################################################################
bool EE_ReadBytes(uint16_t StartVirtualAddress,uint16_t HowManyBytesToRead,void* Data)
{
union{uint8_t sbyte[4];uint32_t fbyte;}temp;
uint8_t *DataP = (uint8_t *)Data;

//check address validation
if((StartVirtualAddress + _X_BYTE_ROUNDUP(HowManyBytesToRead,4)) > _EEPROM_End_VirtualAddr)
return false;

for(uint16_t i=StartVirtualAddress , currentbyte=0 ; i < _X_BYTE_ROUNDUP(HowManyBytesToRead,4)+StartVirtualAddress ; i++)
{
temp.fbyte = (*(__IO uint32_t*)((i*4)+_EEPROM_START_FLASH_PAGE_ADDRESS));
// Fill bytes
for(uint8_t j=0;j<4;j++)
{
if (currentbyte<HowManyBytesToRead)
{
*DataP = temp.sbyte[j];
++currentbyte;
if (currentbyte<HowManyBytesToRead)
DataP++;
}
else
break;
}
}
return true;
}
//##########################################################################################################
bool EE_Write(uint16_t VirtualAddress, uint32_t Data)
{
if(VirtualAddress >= _EEPROM_End_VirtualAddr)
return false;

//If flash space is not empty make it empty
if((*(__IO uint32_t*)((VirtualAddress*4)+_EEPROM_START_FLASH_PAGE_ADDRESS)) != 0xFFFFFFFF)
{
//create backup of that page excluding bad data
EE_PageTransfer(EE_FindPageAddressOfVirtualAddress(VirtualAddress),EE_FindVirtualAddressOffset(VirtualAddress),1);
}
//Write data
if(Data!=0xFFFFFFFF)
{
HAL_FLASH_Unlock();
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(VirtualAddress*4)+_EEPROM_START_FLASH_PAGE_ADDRESS,(uint64_t)Data)==HAL_OK)
{
HAL_FLASH_Lock();
return true;
}
else
{
HAL_FLASH_Lock();
return false;
}
}
HAL_FLASH_Lock();
return true;

}
//##########################################################################################################
bool EE_Writes(uint16_t StartVirtualAddress,uint16_t HowMuchToWrite,uint32_t* Data)
{
//check address validation
if((StartVirtualAddress+HowMuchToWrite) > _EEPROM_End_VirtualAddr)
return false;

//If flash space is not empty make it empty
for(uint16_t i=StartVirtualAddress ; i<StartVirtualAddress + HowMuchToWrite ; i++)
{
if((*(__IO uint32_t*)((i*4)+_EEPROM_START_FLASH_PAGE_ADDRESS)) != 0xFFFFFFFF)
{
//create backup of that page excluding bad data
EE_PageTransfer(EE_FindPageAddressOfVirtualAddress(StartVirtualAddress),EE_FindVirtualAddressOffset(StartVirtualAddress),HowMuchToWrite);
break;
}
}

//Write new data
HAL_FLASH_Unlock();
for(uint16_t i=StartVirtualAddress ; i<StartVirtualAddress + HowMuchToWrite ; i++, Data++)
{
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(i*4)+_EEPROM_START_FLASH_PAGE_ADDRESS,(uint64_t)*Data)!=HAL_OK)
{
HAL_FLASH_Lock();
return false;
}
}

HAL_FLASH_Lock();
return true;
}
//##########################################################################################################
bool EE_WriteBytes(uint16_t StartVirtualAddress,uint16_t HowManyBytesToWrite,void* Data)
{
union{uint8_t sbyte[4];uint32_t fbyte;}temp;
uint8_t *DataP = (uint8_t *)Data;

//check address validation
if((StartVirtualAddress+_X_BYTE_ROUNDUP(HowManyBytesToWrite,4)) > _EEPROM_End_VirtualAddr)
return false;

//If flash space is not empty make it empty
for(uint16_t i=StartVirtualAddress ; i<StartVirtualAddress + _X_BYTE_ROUNDUP(HowManyBytesToWrite,4) ; i++)
{
if((*(__IO uint32_t*)((i*4)+_EEPROM_START_FLASH_PAGE_ADDRESS)) != 0xFFFFFFFF)
{
//create backup of that page excluding bad data
EE_PageTransfer(EE_FindPageAddressOfVirtualAddress(StartVirtualAddress),EE_FindVirtualAddressOffset(StartVirtualAddress),_X_BYTE_ROUNDUP(HowManyBytesToWrite,4));
break;
}
}

//Write new data
HAL_FLASH_Unlock();
for(uint16_t i=StartVirtualAddress, currentbyte=0 ; i<StartVirtualAddress + _X_BYTE_ROUNDUP(HowManyBytesToWrite,4) ; i++)
{
//Convert Bytes to uint32_t and pad the end if more than indicated size
for(uint8_t j=0;j<4;j++)
{
if (currentbyte<HowManyBytesToWrite)
{
temp.sbyte[j] = *DataP;
++currentbyte;
if (currentbyte<HowManyBytesToWrite)
DataP++;
}
else
temp.sbyte[j] = 0;
}
// program
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(i*4)+_EEPROM_START_FLASH_PAGE_ADDRESS,(uint64_t)temp.fbyte)!=HAL_OK)
{
HAL_FLASH_Lock();
return false;
}
}

HAL_FLASH_Lock();
return true;
}
//##########################################################################################################
static bool EE_PageTransfer(uint32_t PageAddress,uint16_t BadDataOffset,uint16_t BadDataNum)
{
uint32_t tempdata;
//format transfer page
if(EE_FormatPage(_EEPROM_TRANSFER_PAGE_ADDRESS)==false)
return false;

//Write to transfer page but exclude the bad data
HAL_FLASH_Unlock();
for(uint16_t i=0 ; i<_EEPROM_FLASH_PAGE_SIZE/4 ; i++)
{
if(i>=BadDataOffset && i<BadDataOffset+BadDataNum)
{
continue;
}
//read original data
tempdata = (*(__IO uint32_t*)((i*4)+PageAddress));
//write to transfer page
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(i*4)+_EEPROM_TRANSFER_PAGE_ADDRESS,(uint64_t)tempdata)!=HAL_OK)
{
HAL_FLASH_Lock();
return false;
}
}

//format original page
if(EE_FormatPage(PageAddress)==false)
return false;

HAL_FLASH_Unlock();
//Write back to Original Page
for(uint16_t i=0 ; i<_EEPROM_FLASH_PAGE_SIZE/4 ; i++)
{
tempdata = (*(__IO uint32_t*)((i*4)+_EEPROM_TRANSFER_PAGE_ADDRESS));
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,(i*4)+PageAddress,(uint64_t)tempdata)!=HAL_OK)
{
HAL_FLASH_Lock();
return false;
}
}

HAL_FLASH_Lock();
return true;
}
//##########################################################################################################
static uint32_t EE_FindPageAddressOfVirtualAddress(uint16_t VirtualAddress)
{
uint32_t temp;
temp = _EEPROM_Num_VirtualAdd_IN_PAGE;
temp = _EEPROM_START_FLASH_PAGE_ADDRESS + (VirtualAddress/temp)*((uint32_t)FLASH_PAGE_SIZE);
return temp;
}
//##########################################################################################################
static uint16_t EE_FindVirtualAddressOffset(uint16_t VirtualAddress)
{
uint16_t temp;
temp = _EEPROM_Num_VirtualAdd_IN_PAGE;
temp = (VirtualAddress % temp);
return temp;
}
//##########################################################################################################
20 changes: 20 additions & 0 deletions eeprom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __EEPROM_H
#define __EEPROM_H

#include <stdbool.h>
//include the Correct HAL version here according to the Cortex core.
//#include "stm32f1xx_hal.h"
#include "stm32f0xx_hal.h"


//################################################################################################################
bool EE_FormatPage(uint32_t PageAddress);
bool EE_Read(uint16_t VirtualAddress, uint32_t* Data);
bool EE_Reads(uint16_t StartVirtualAddress,uint16_t HowMuchToRead,uint32_t* Data);
bool EE_ReadBytes(uint16_t StartVirtualAddress,uint16_t HowManyBytesToRead,void* Data);
bool EE_Write(uint16_t VirtualAddress, uint32_t Data);
bool EE_Writes(uint16_t StartVirtualAddress,uint16_t HowMuchToWrite,uint32_t* Data);
bool EE_WriteBytes(uint16_t StartVirtualAddress,uint16_t HowManyBytesToWrite,void* Data);
//################################################################################################################

#endif
70 changes: 70 additions & 0 deletions eepromConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef __EEPROMCONFIG_H
#define __EEPROMCONFIG_H

/*
References for further development:
https://github.com/whatcall/stm32f0-emulated-eeprom
https://github.com/nimaltd/EEPROM
@TODO check for compiler options to reserve the flash space.
@TODO Check for 16 bit Flash Writing
@TODO implement way to detect data being written on overlapping pages
*/
/*
Low Density : From Page 0 to Page 31 , Page Size : 0x400 = 1024
Medium Density : From Page 0 to Page 63 , Page Size : 0x400 = 1024
High Density : From Page 0 to Page 127 , Page Size : 0x800 = 2048
*/

// Use RTOS so be carefull not to interrupt in critical areas
#ifndef _USE_RTOS
#define _USE_RTOS 0
#endif

// Valid Values: M0 , M0P , M3 , M7
#define _CORTEX_ M0

// Valid Values: LOW , MEDIUM , HIGH
#define _DENSITY_ LOW

#define _EEPROM_PAGES_TO_USE 2 //The number of pages needed to be used (excluding the transfer page)
#define _EEPROM_START_FLASH_PAGE 29
#define _EEPROM_TRANSFER_PAGE 31 //Should be last page of memory - this is the temp page for updating other pages without using RAM

/*################################################################################################################################*/
/*######################DO NOT EDIT ANYTHING BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING!!!!!!#############################*/
/*################################################################################################################################*/
#if(_EEPROM_PAGES_TO_USE+_EEPROM_START_FLASH_PAGE>_EEPROM_TRANSFER_PAGE)
#error "Transfer Page is overlapping Data Pages"
#endif
#if(_EEPROM_PAGES_TO_USE+_EEPROM_START_FLASH_PAGE!=_EEPROM_TRANSFER_PAGE)
#warning "Page Gap between User Data and Transfer Page"
#endif

/* Emulated data and virtual address bits */
#define EE_DATA_16BIT 16
#define EE_DATA_32BIT 32
#define EE_DATA_WIDTH (uint32_t)EE_DATA_32BIT

// Valid Values: 0x400 , 0x800
#define _EEPROM_FLASH_PAGE_SIZE (uint32_t)FLASH_PAGE_SIZE /* Page size --> From HAL Library */

#define _EEPROM_Num_VirtualAdd_IN_PAGE ((uint32_t)FLASH_PAGE_SIZE)/(EE_DATA_WIDTH/8)

// Virtual Address points to uint32_t types of data so we divide it by 32bits=4byes
#define _EEPROM_End_VirtualAddr (_EEPROM_FLASH_PAGE_SIZE/4)*_EEPROM_PAGES_TO_USE

/* Base address of the Flash sectors */
#define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000000) /* Base @ of Page 0 */
#define _EEPROM_START_FLASH_PAGE_ADDRESS (uint32_t)(ADDR_FLASH_PAGE_0|(_EEPROM_FLASH_PAGE_SIZE*_EEPROM_START_FLASH_PAGE))
#define _EEPROM_TRANSFER_PAGE_ADDRESS (uint32_t)(ADDR_FLASH_PAGE_0|(_EEPROM_FLASH_PAGE_SIZE*_EEPROM_TRANSFER_PAGE))

#if(_DENSITY_==LOW&&_EEPROM_USE_FLASH_PAGE>31)
#error "Please Enter currect value _EEPROM_USE_FLASH_PAGE (0 to 31)"
#elseif(_DENSITY_==MEDIUM&&_EEPROM_USE_FLASH_PAGE>63)
#error "Please Enter currect value _EEPROM_USE_FLASH_PAGE (0 to 63)"
#elseif(_DENSITY_==HIGH&&_EEPROM_USE_FLASH_PAGE>127)
#error "Please Enter currect value _EEPROM_USE_FLASH_PAGE (0 to 127)"
#endif

#endif

0 comments on commit 374b3ee

Please sign in to comment.