-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial Commit
- Loading branch information
Showing
3 changed files
with
346 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
//########################################################################################################## |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |