Update on eeprom emulation (#424)

* Fix building for FRAM with globals.h setting

On request of vitor boss. A lot has been changed around  to make the selection of EEPROM emulation  type from the globals.h (including FRAM selection)

* Add support for EEPROM emulation on internal flash of STM32F7

* Updates on SPI Flash EEPROM

* Fix building for BACKUPSRAM as EEPROM.

* Add put() and get() functions to the EEPROM emulation. This is needed for the latest terminstor and other calibrations routines

Co-authored-by: Tjeerd <tjeerdie@users.noreply.github.com>
This commit is contained in:
Tjeerd 2020-08-10 00:58:00 +02:00 committed by GitHub
parent d4899c0200
commit 6faab8e485
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 340 additions and 109 deletions

View File

@ -79,7 +79,6 @@ board = black_f407ve
;lib_deps = EEPROM
board_build.core = stm32
build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DARDUINO_BLACK_F407VE -DCORE_STM32_OFFICIAL -DENABLE_HWSERIAL2 -DENABLE_HWSERIAL3 -DUSBCON -DHAL_PCD_MODULE_ENABLED -DUSBD_USE_CDC -DHAL_UART_MODULE_ENABLED
;-DUSE_SPI_EEPROM=56
upload_protocol = dfu
debug_tool = stlink
monitor_speed = 115200

View File

@ -24,26 +24,7 @@
#define COUNTER_TYPE uint16_t
#define micros_safe() micros() //timer5 method is not used on anything but AVR, the micros_safe() macro is simply an alias for the normal micros()
#define TIMER_RESOLUTION 4
#if defined(SRAM_AS_EEPROM)
#define EEPROM_LIB_H "src/BackupSram/BackupSramAsEEPROM.h"
#elif defined(FRAM_AS_EEPROM) //https://github.com/VitorBoss/FRAM
#define EEPROM_LIB_H <Fram.h>
#else
#define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h"
#endif
#ifndef LED_BUILTIN
#define LED_BUILTIN PA7
#endif
#if defined(FRAM_AS_EEPROM)
#include <Fram.h>
#if defined(ARDUINO_BLACK_F407VE)
FramClass EEPROM(PB5, PB4, PB3, PB0); /*(mosi, miso, sclk, ssel, clockspeed) 31/01/2020*/
#else
FramClass EEPROM(PB15, PB14, PB13, PB12); //Blue/Black Pills
#endif
#endif
#define USE_SERIAL3
void initBoard();
@ -66,6 +47,55 @@ extern "C" char* sbrk(int incr);
#endif
#endif
#ifndef LED_BUILTIN
#define LED_BUILTIN PA7
#endif
/*
***********************************************************************************************************
* EEPROM emulation
*/
#if defined(SRAM_AS_EEPROM)
#define EEPROM_LIB_H "src/BackupSram/BackupSramAsEEPROM.h"
#include EEPROM_LIB_H
BackupSramAsEEPROM EEPROM;
#elif defined(USE_SPI_EEPROM)
#define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h"
#include EEPROM_LIB_H
SPIClass SPI_for_flash(PB5, PB4, PB3); //SPI1_MOSI, SPI1_MISO, SPI1_SCK
//windbond W25Q16 SPI flash EEPROM emulation
EEPROM_Emulation_Config EmulatedEEPROMMconfig{255UL, 4096UL, 31, 0x00100000UL};
Flash_SPI_Config SPIconfig{USE_SPI_EEPROM, SPI_for_flash};
SPI_EEPROM_Class EEPROM(EmulatedEEPROMMconfig, SPIconfig);
#elif defined(FRAM_AS_EEPROM) //https://github.com/VitorBoss/FRAM
#define EEPROM_LIB_H <Fram.h>
#include EEPROM_LIB_H
#if defined(ARDUINO_BLACK_F407VE)
FramClass EEPROM(PB5, PB4, PB3, PB0); /*(mosi, miso, sclk, ssel, clockspeed) 31/01/2020*/
#else
FramClass EEPROM(PB15, PB14, PB13, PB12); //Blue/Black Pills
#endif
#elif defined(STM32F7xx)
#define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h"
#include EEPROM_LIB_H
#if defined(DUAL_BANK)
EEPROM_Emulation_Config EmulatedEEPROMMconfig{4UL, 131072UL, 2047UL, 0x08120000UL};
#else
EEPROM_Emulation_Config EmulatedEEPROMMconfig{2UL, 262144UL, 4095UL, 0x08180000UL};
#endif
InternalSTM32F7_EEPROM_Class EEPROM(EmulatedEEPROMMconfig);
#else //default case, internal flash as EEPROM for STM32F4
#define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h"
#include EEPROM_LIB_H
EEPROM_Emulation_Config EmulatedEEPROMMconfig{4UL, 131072UL, 2047UL, 0x08080000UL};
InternalSTM32F4_EEPROM_Class EEPROM(EmulatedEEPROMMconfig);
#endif
/*
***********************************************************************************************************
* Schedules

View File

@ -52,9 +52,9 @@
#define IGN_CHANNELS 5
#endif
//Select one for EEPROM, default are emulated and is very slow
//#define SRAM_AS_EEPROM /*Use RTC registers, requires a 3V battery connected to Vbat pin */
//#define SPIFLASH_AS_EEPROM /*Use M25Qxx SPI flash */
//Select one for EEPROM,the default is EEPROM emulation on internal flash.
//#define SRAM_AS_EEPROM /*Use 4K battery backed SRAM, requires a 3V continuous source (like battery) connected to Vbat pin */
#define USE_SPI_EEPROM PB0 /*Use M25Qxx SPI flash */
//#define FRAM_AS_EEPROM /*Use FRAM like FM25xxx, MB85RSxxx or any SPI compatible */
#ifndef word

View File

@ -1,5 +1,5 @@
//#if defined(ARDUINO_BLACK_F407VE)
#if defined(CORE_STM32_OFFICIAL) && defined(SRAM_AS_EEPROM)
#if defined(ARDUINO_ARCH_STM32)
#include "BackupSramAsEEPROM.h"
BackupSramAsEEPROM::BackupSramAsEEPROM(){
@ -77,6 +77,8 @@
return 0;
}
BackupSramAsEEPROM EEPROM;
#endif

View File

@ -1,11 +1,9 @@
//Backup sram stores data in the battery backuped sram portion.
//The backup battery is available on the ebay stm32F407VET6 black boards.
#if defined(CORE_STM32_OFFICIAL) && defined(SRAM_AS_EEPROM)
#ifndef BACKUPSRAMASEEPROM_H
#define BACKUPSRAMASEEPROM_H
#if defined(ARDUINO_ARCH_STM32)
//UGLY HACK TO PREVENT EEPROM LIBRARY BEING IMPORTED FIRST!!
//Use with black_F407VE board
#ifndef EEPROM_h
#define EEPROM_h
#include <stdint.h>
#include "stm32f407xx.h"
@ -21,9 +19,21 @@ class BackupSramAsEEPROM {
uint8_t read(uint16_t address);
int8_t write(uint16_t address, uint8_t val);
int8_t update(uint16_t address, uint8_t val);
template< typename T > T &get( int idx, T &t ){
uint16_t e = idx;
uint8_t *ptr = (uint8_t*) &t;
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = read(e);
return t;
}
template< typename T > const T &put( int idx, const T &t ){
const uint8_t *ptr = (const uint8_t*) &t;
uint16_t e = idx;
for( int count = sizeof(T) ; count ; --count, ++e ) write(e, *ptr++);
return t;
}
};
extern BackupSramAsEEPROM EEPROM;
#endif
#endif
#endif

View File

@ -2,6 +2,7 @@
* Copyright (C) 2020 by Tjeerd Hoogendijk
* Created by Tjeerd Hoogendijk - 21/09/2019
* Updated by Tjeerd Hoogendijk - 19/04/2020
* Updated by Tjeerd Hoogendijk - 21/07/2020 no new version number
*
* This file is part of the Speeduino project. This library started out for
* Winbond SPI flash memory modules. As of version 2.0 it also works with internal
@ -24,20 +25,8 @@
* along with the Speeduino SPIAsEEPROM Library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#if !defined(FRAM_AS_EEPROM) && !defined(SRAM_AS_EEPROM)
#if defined(USE_SPI_EEPROM) | defined(STM32F407xx) | defined(STM32F103xB)
#include "SPIAsEEPROM.h"
static EEPROM_Emulation_Config EmulatedEEPROMMconfig{
FLASH_SECTORS_USED,
FLASH_SECTOR_SIZE,
EEPROM_BYTES_PER_SECTOR,
EEPROM_FLASH_BASEADRESS
};
// EmulatedEEPROMMconfig.Flash_Sectors_Used = FLASH_SECTORS_USED;
FLASH_EEPROM_BaseClass::FLASH_EEPROM_BaseClass(EEPROM_Emulation_Config config)
{
@ -254,23 +243,22 @@ int8_t FLASH_EEPROM_BaseClass::readFlashBytes(uint32_t address , byte* buffer, u
int8_t FLASH_EEPROM_BaseClass::writeFlashBytes(uint32_t address, byte* buffer, uint32_t length){return -1;}
int8_t FLASH_EEPROM_BaseClass::eraseFlashSector(uint32_t address, uint32_t length){return -1;}
#endif
#if defined(USE_SPI_EEPROM)
SPI_EEPROM_Class::SPI_EEPROM_Class(EEPROM_Emulation_Config config):FLASH_EEPROM_BaseClass(config)
#if defined(ARDUINO_ARCH_STM32)
SPI_EEPROM_Class::SPI_EEPROM_Class(EEPROM_Emulation_Config EmulationConfig, Flash_SPI_Config SPIConfig):FLASH_EEPROM_BaseClass(EmulationConfig)
{
_configSPI = SPIConfig;
}
byte SPI_EEPROM_Class::read(uint16_t addressEEPROM){
//Check if emulated EEPROM is available if not yet start it first.
if(!_EmulatedEEPROMAvailable){
//22.5Mhz is highest it could get with this. But should be ~45Mhz :-(.
SPISettings settings(22500000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(settings);
begin(SPI, USE_SPI_EEPROM);
if(!_EmulatedEEPROMAvailable){
SPISettings settings(22500000, MSBFIRST, SPI_MODE0); //22.5Mhz is highest it could get with this. But should be ~45Mhz :-(.
_configSPI.SPIport.beginTransaction(settings);
begin(_configSPI.SPIport, _configSPI.pinChipSelect);
}
return FLASH_EEPROM_BaseClass::read(addressEEPROM);
}
@ -300,9 +288,10 @@ int8_t SPI_EEPROM_Class::eraseFlashSector(uint32_t address, uint32_t length){
return 0;
}
#endif
//THIS IS NOT WORKING! FOR STM32F103 YOU CAN ONLY WRITE IN JUST ERASED HALFWORDS(UINT16_T). THE PHILISOPHY IS FLAWWED THERE.
// #elif defined(STM32F103xB)
//#if defined(STM32F103xB)
// InternalSTM32F1_EEPROM_Class::InternalSTM32F1_EEPROM_Class(EEPROM_Emulation_Config config):FLASH_EEPROM_BaseClass(config)
// {
@ -358,8 +347,26 @@ int8_t SPI_EEPROM_Class::eraseFlashSector(uint32_t address, uint32_t length){
// HAL_FLASH_Lock();
// return EraseSucceed;
// }
//#endif
#if defined(STM32F4)
//Look in the datasheet for more information about flash sectors and sizes
//This is the correct sector allocation for the STM32F407 all types
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base address of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base address of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base address of Sector 11, 128 Kbytes */
#define FLASH_END_ADDRESS ((uint32_t)0x08100000) /* END address of Sector 11, 128 Kbytes */
#elif defined(STM32F407xx)
InternalSTM32F4_EEPROM_Class::InternalSTM32F4_EEPROM_Class(EEPROM_Emulation_Config config) : FLASH_EEPROM_BaseClass(config)
{
@ -410,18 +417,19 @@ int8_t InternalSTM32F4_EEPROM_Class::eraseFlashSector(uint32_t address, uint32_t
//Look in the datasheet for more information about flash sectors and sizes
//This is the correct sector allocation for the STM32F407 all types
if ((realAddress>=0x08000000UL)&(realAddress<=0x08003FFFUL)){_Sector = 0;}
if ((realAddress>=0x08004000UL)&(realAddress<=0x08007FFFUL)){_Sector = 1;}
if ((realAddress>=0x08008000UL)&(realAddress<=0x0800BFFFUL)){_Sector = 2;}
if ((realAddress>=0x0800C000UL)&(realAddress<=0x0800FFFFUL)){_Sector = 3;}
if ((realAddress>=0x08010000UL)&(realAddress<=0x0801FFFFUL)){_Sector = 4;}
if ((realAddress>=0x08020000UL)&(realAddress<=0x0803FFFFUL)){_Sector = 5;}
if ((realAddress>=0x08040000UL)&(realAddress<=0x0805FFFFUL)){_Sector = 6;}
if ((realAddress>=0x08050000UL)&(realAddress<=0x0807FFFFUL)){_Sector = 7;}
if ((realAddress>=0x08080000UL)&(realAddress<=0x0809FFFFUL)){_Sector = 8;}
if ((realAddress>=0x080A0000UL)&(realAddress<=0x080BFFFFUL)){_Sector = 9;}
if ((realAddress>=0x080C0000UL)&(realAddress<=0x080DFFFFUL)){_Sector = 10;}
if ((realAddress>=0x080E0000UL)&(realAddress<=0x080FFFFFUL)){_Sector = 11;}
if((realAddress < ADDR_FLASH_SECTOR_1) && (realAddress >= ADDR_FLASH_SECTOR_0)){_Sector = 0;}
if((realAddress < ADDR_FLASH_SECTOR_2) && (realAddress >= ADDR_FLASH_SECTOR_1)){_Sector = 1;}
if((realAddress < ADDR_FLASH_SECTOR_3) && (realAddress >= ADDR_FLASH_SECTOR_2)){_Sector = 2;}
if((realAddress < ADDR_FLASH_SECTOR_4) && (realAddress >= ADDR_FLASH_SECTOR_3)){_Sector = 3;}
if((realAddress < ADDR_FLASH_SECTOR_5) && (realAddress >= ADDR_FLASH_SECTOR_4)){_Sector = 4;}
if((realAddress < ADDR_FLASH_SECTOR_6) && (realAddress >= ADDR_FLASH_SECTOR_5)){_Sector = 5;}
if((realAddress < ADDR_FLASH_SECTOR_7) && (realAddress >= ADDR_FLASH_SECTOR_6)){_Sector = 6;}
if((realAddress < ADDR_FLASH_SECTOR_8) && (realAddress >= ADDR_FLASH_SECTOR_7)){_Sector = 7;}
if((realAddress < ADDR_FLASH_SECTOR_9) && (realAddress >= ADDR_FLASH_SECTOR_8)){_Sector = 8;}
if((realAddress < ADDR_FLASH_SECTOR_10) && (realAddress >= ADDR_FLASH_SECTOR_9)){_Sector = 9;}
if((realAddress < ADDR_FLASH_SECTOR_11) && (realAddress >= ADDR_FLASH_SECTOR_10)){_Sector = 10;}
if((realAddress < FLASH_END_ADDRESS) && (realAddress >= ADDR_FLASH_SECTOR_11)){_Sector = 11;}
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
@ -435,12 +443,141 @@ int8_t InternalSTM32F4_EEPROM_Class::eraseFlashSector(uint32_t address, uint32_t
}
#endif
#if defined(USE_SPI_EEPROM)
SPI_EEPROM_Class EEPROM(EmulatedEEPROMMconfig);
#elif defined(STM32F407xx) & !defined(SRAM_AS_EEPROM)
InternalSTM32F4_EEPROM_Class EEPROM(EmulatedEEPROMMconfig);
#if defined(STM32F7xx)
#if defined(DUAL_BANK)
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base address of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base address of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base address of Sector 11, 128 Kbytes */
#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base address of Sector 12, 16 Kbytes */
#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base address of Sector 13, 16 Kbytes */
#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base address of Sector 14, 16 Kbytes */
#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base address of Sector 15, 16 Kbytes */
#define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base address of Sector 16, 64 Kbytes */
#define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base address of Sector 17, 128 Kbytes */
#define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base address of Sector 18, 128 Kbytes */
#define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base address of Sector 19, 128 Kbytes */
#define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base address of Sector 20, 128 Kbytes */
#define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base address of Sector 21, 128 Kbytes */
#define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base address of Sector 22, 128 Kbytes */
#define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base address of Sector 23, 128 Kbytes */
#else
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 32 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base address of Sector 1, 32 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base address of Sector 2, 32 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base address of Sector 3, 32 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base address of Sector 4, 128 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base address of Sector 5, 256 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base address of Sector 6, 256 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base address of Sector 7, 256 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base address of Sector 8, 256 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base address of Sector 9, 256 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base address of Sector 10, 256 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base address of Sector 11, 256 Kbytes */
#endif /* DUAL_BANK */
InternalSTM32F7_EEPROM_Class::InternalSTM32F7_EEPROM_Class(EEPROM_Emulation_Config config) : FLASH_EEPROM_BaseClass(config)
{
}
byte InternalSTM32F7_EEPROM_Class::read(uint16_t addressEEPROM){
if(!_EmulatedEEPROMAvailable){
FLASH_EEPROM_BaseClass::initialize(true);
}
return FLASH_EEPROM_BaseClass::read(addressEEPROM);
}
int8_t InternalSTM32F7_EEPROM_Class::readFlashBytes(uint32_t address, byte *buf, uint32_t length){
memcpy(buf, (uint8_t *)(_config.EEPROM_Flash_BaseAddress + address), length);
return 0;
}
int8_t InternalSTM32F7_EEPROM_Class::writeFlashBytes(uint32_t flashAddress, byte *buf, uint32_t length){
{
uint32_t translatedAddress = flashAddress+_config.EEPROM_Flash_BaseAddress;
uint32_t data = 0;
uint32_t offset = 0;
uint32_t countaddress = translatedAddress;
HAL_FLASH_Unlock();
while (countaddress < translatedAddress + length) {
memcpy(&data, buf + offset, sizeof(uint32_t));
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, countaddress, data) == HAL_OK) {
countaddress += 4;
offset += 4;
} else {
countaddress = translatedAddress + length + 1;
}
}
}
HAL_FLASH_Lock();
return 0;
}
int8_t InternalSTM32F7_EEPROM_Class::eraseFlashSector(uint32_t address, uint32_t length){
FLASH_EraseInitTypeDef EraseInitStruct;
// uint32_t offset = 0;
uint32_t realAddress = _config.EEPROM_Flash_BaseAddress+address;
// uint32_t address_end = FLASH_BASE_ADDRESS + E2END;
bool EraseSucceed=false;
uint32_t SectorError = 0;
uint32_t _Sector = 11;
//Look in the datasheet for more information about flash sectors and sizes
//This is the correct sector allocation for the STM32F407 all types
if((realAddress < ADDR_FLASH_SECTOR_1) && (realAddress >= ADDR_FLASH_SECTOR_0)){_Sector = 0;}
if((realAddress < ADDR_FLASH_SECTOR_2) && (realAddress >= ADDR_FLASH_SECTOR_1)){_Sector = 1;}
if((realAddress < ADDR_FLASH_SECTOR_3) && (realAddress >= ADDR_FLASH_SECTOR_2)){_Sector = 2;}
if((realAddress < ADDR_FLASH_SECTOR_4) && (realAddress >= ADDR_FLASH_SECTOR_3)){_Sector = 3;}
if((realAddress < ADDR_FLASH_SECTOR_5) && (realAddress >= ADDR_FLASH_SECTOR_4)){_Sector = 4;}
if((realAddress < ADDR_FLASH_SECTOR_6) && (realAddress >= ADDR_FLASH_SECTOR_5)){_Sector = 5;}
if((realAddress < ADDR_FLASH_SECTOR_7) && (realAddress >= ADDR_FLASH_SECTOR_6)){_Sector = 6;}
if((realAddress < ADDR_FLASH_SECTOR_8) && (realAddress >= ADDR_FLASH_SECTOR_7)){_Sector = 7;}
if((realAddress < ADDR_FLASH_SECTOR_9) && (realAddress >= ADDR_FLASH_SECTOR_8)){_Sector = 8;}
if((realAddress < ADDR_FLASH_SECTOR_10) && (realAddress >= ADDR_FLASH_SECTOR_9)){_Sector = 9;}
if((realAddress < ADDR_FLASH_SECTOR_11) && (realAddress >= ADDR_FLASH_SECTOR_10)){_Sector = 10;}
else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11) */
{
{_Sector = 11;}
}
#if defined(DUAL_BANK)
if((realAddress < ADDR_FLASH_SECTOR_13) && (realAddress >= ADDR_FLASH_SECTOR_12)){_Sector = 12;}
if((realAddress < ADDR_FLASH_SECTOR_14) && (realAddress >= ADDR_FLASH_SECTOR_13)){_Sector = 13;}
if((realAddress < ADDR_FLASH_SECTOR_15) && (realAddress >= ADDR_FLASH_SECTOR_14)){_Sector = 14;}
if((realAddress < ADDR_FLASH_SECTOR_16) && (realAddress >= ADDR_FLASH_SECTOR_15)){_Sector = 15;}
if((realAddress < ADDR_FLASH_SECTOR_17) && (realAddress >= ADDR_FLASH_SECTOR_16)){_Sector = 16;}
if((realAddress < ADDR_FLASH_SECTOR_18) && (realAddress >= ADDR_FLASH_SECTOR_17)){_Sector = 17;}
if((realAddress < ADDR_FLASH_SECTOR_19) && (realAddress >= ADDR_FLASH_SECTOR_18)){_Sector = 18;}
if((realAddress < ADDR_FLASH_SECTOR_20) && (realAddress >= ADDR_FLASH_SECTOR_19)){_Sector = 19;}
if((realAddress < ADDR_FLASH_SECTOR_21) && (realAddress >= ADDR_FLASH_SECTOR_20)){_Sector = 20;}
if((realAddress < ADDR_FLASH_SECTOR_22) && (realAddress >= ADDR_FLASH_SECTOR_21)){_Sector = 21;}
if((realAddress < ADDR_FLASH_SECTOR_23) && (realAddress >= ADDR_FLASH_SECTOR_22)){_Sector = 22;}
else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23) */
{
{_Sector = 23;}
}
#endif /* DUAL_BANK */
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Sector = _Sector;
EraseInitStruct.NbSectors = 1;
HAL_FLASH_Unlock();
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) == HAL_OK){EraseSucceed=true;}
HAL_FLASH_Lock();
return EraseSucceed;
}
#endif
#endif

View File

@ -2,6 +2,7 @@
* Copyright (C) 2020 by Tjeerd Hoogendijk
* Created by Tjeerd Hoogendijk - 21/09/2019
* Updated by Tjeerd Hoogendijk - 19/04/2020
* Updated by Tjeerd Hoogendijk - 21/07/2020 no new version number
*
* This file is part of the Speeduino project. This library started out for
* Winbond SPI flash memory modules. As of version 2.0 it also works with internal
@ -110,29 +111,14 @@
#include "winbondflash.h"
#include <SPI.h>
#if defined(USE_SPI_EEPROM)
//windbond W25Q16 SPI flash EEPROM emulation
#define FLASH_SECTORS_USED 255UL //This can be any number from 1 to many.
#define FLASH_SECTOR_SIZE 4096UL //Flash sector size this is determined by the physical device. This is the smallest block that can be erased at one time
#define EEPROM_BYTES_PER_SECTOR 31 //(FLASH_SECTOR_SIZE/EEPROM_BYTES_PER_SECTOR+1) Must be integer number and aligned with page size of flash used. For windbond align with 256bytes.
#define EEPROM_FLASH_BASEADRESS 0x00100000UL //address to start from can be zero or any other place in flash. make sure EEPROM_FLASH_BASEADRESS+FLASH_SIZE_USED is not over end of flash
#elif defined(STM32F407xx)
#include "stm32_def.h"
//Internal flash STM32F407 EEPROM emulation
#define FLASH_SECTORS_USED 4UL //This can be any number from 1 to many.
#define FLASH_SECTOR_SIZE 131072UL //Flash sector size this is determined by the physical device. This is the smallest block that can be erased at one time
#define EEPROM_BYTES_PER_SECTOR 2047UL //(FLASH_SECTOR_SIZE/EEPROM_BYTES_PER_SECTOR+1) Must be integer number and aligned with page size of flash used.
#define EEPROM_FLASH_BASEADRESS 0x08080000UL //address to start from can be zero or any other place in flash. make sure EEPROM_FLASH_BASEADRESS+FLASH_SIZE_USED is not over end of flash
#elif defined(STM32F103xB)
#include "stm32_def.h"
//Internal flash STM32F407 EEPROM emulation
#define FLASH_SECTORS_USED 9UL //This can be any number from 1 to many.
#define FLASH_SECTOR_SIZE 1024UL //Flash sector size this is determined by the physical device. This is the smallest block that can be erased at one time
#define EEPROM_BYTES_PER_SECTOR 127UL //(FLASH_SECTOR_SIZE/EEPROM_BYTES_PER_SECTOR+1) Must be integer number and aligned with page size of flash used.
#define EEPROM_FLASH_BASEADRESS 0x801D400UL //address to start from can be zero or any other place in flash. make sure EEPROM_FLASH_BASEADRESS+FLASH_SIZE_USED is not over end of flash
#endif
// #elif defined(STM32F103xB)
// #include "stm32_def.h"
// //Internal flash STM32F407 EEPROM emulation
// #define FLASH_SECTORS_USED 9UL //This can be any number from 1 to many.
// #define FLASH_SECTOR_SIZE 1024UL //Flash sector size this is determined by the physical device. This is the smallest block that can be erased at one time
// #define EEPROM_BYTES_PER_SECTOR 127UL //(FLASH_SECTOR_SIZE/EEPROM_BYTES_PER_SECTOR+1) Must be integer number and aligned with page size of flash used.
// #define EEPROM_FLASH_BASEADRESS 0x801D400UL //address to start from can be zero or any other place in flash. make sure EEPROM_FLASH_BASEADRESS+FLASH_SIZE_USED is not over end of flash
// #endif
#define MAGICNUMBER1 0xC0
#define MAGICNUMBER2 0xFF
@ -143,12 +129,16 @@
#define BITS_PER_BYTE 8
typedef struct {
uint32_t Flash_Sectors_Used;
uint32_t Flash_Sector_Size;
uint32_t EEPROM_Bytes_Per_Sector;
uint32_t EEPROM_Flash_BaseAddress;
uint32_t Flash_Sectors_Used; //This the number of flash sectors used for EEPROM emulation can be any number from 1 to many.
uint32_t Flash_Sector_Size; //Flash sector size: This is determined by the physical device. This is the smallest block that can be erased at one time
uint32_t EEPROM_Bytes_Per_Sector; //EEPROM bytes per sector: (Flash sector size/EEPROM bytes per sector+1) -> Must be integer number and aligned with page size of flash used.
uint32_t EEPROM_Flash_BaseAddress; //Flash address to start Emulation from, can be zero or any other place in flash. make sure EEPROM_FLASH_BASEADRESS+FLASH_SIZE_USED is not over end of flash
} EEPROM_Emulation_Config;
typedef struct {
uint16_t pinChipSelect;
SPIClass SPIport;
} Flash_SPI_Config;
//Base class for flash read and write. SPI and internal flash inherrit from this class.
class FLASH_EEPROM_BaseClass
@ -186,6 +176,31 @@ class FLASH_EEPROM_BaseClass
*/
int8_t update(uint16_t, uint8_t);
/**
* Read AnyTypeOfData from eeprom
* @param address
* @return AnyTypeOfData
*/
template< typename T > T &get( int idx, T &t ){
uint16_t e = idx;
uint8_t *ptr = (uint8_t*) &t;
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = read(e);
return t;
}
/**
* Write AnyTypeOfData to eeprom
* @param address
* @param AnyTypeOfData
* @return number of bytes written to flash
*/
template< typename T > const T &put( int idx, const T &t ){
const uint8_t *ptr = (const uint8_t*) &t;
uint16_t e = idx;
for( int count = sizeof(T) ; count ; --count, ++e ) write(e, *ptr++);
return t;
}
/**
* Clear emulated eeprom sector
* @return sectorsCleared
@ -282,12 +297,12 @@ class SPI_EEPROM_Class : public FLASH_EEPROM_BaseClass
{
public:
SPI_EEPROM_Class(EEPROM_Emulation_Config);
SPI_EEPROM_Class(EEPROM_Emulation_Config, Flash_SPI_Config);
/**
* begin emulated EEPROM in flash
* @param Chip_select_pin
* @param SPI_Instance
* @param SPI_object
* @return succes
*/
int8_t begin(SPIClass&, uint8_t);
@ -330,6 +345,9 @@ class SPI_EEPROM_Class : public FLASH_EEPROM_BaseClass
//winbond flash class instance for interacting with the spi flash chip
winbondFlashSPI winbondSPIFlash;
//SPI configuration struct. Now only the CS pins is used, future extension can be the use SPI object or MOSI/MISO/SCK pins
Flash_SPI_Config _configSPI;
};
//Internal flash class for flash EEPROM emulation. Inherrit most from the base class.
@ -420,10 +438,45 @@ class InternalSTM32F4_EEPROM_Class : public FLASH_EEPROM_BaseClass
// int8_t eraseFlashSector(uint32_t, uint32_t);
// };
#if defined(USE_SPI_EEPROM)
extern SPI_EEPROM_Class EEPROM;
#elif defined(STM32F407xx) && !defined(SRAM_AS_EEPROM)
extern InternalSTM32F4_EEPROM_Class EEPROM;
#endif
class InternalSTM32F7_EEPROM_Class : public FLASH_EEPROM_BaseClass
{
public:
InternalSTM32F7_EEPROM_Class(EEPROM_Emulation_Config);
/**
* Read an eeprom cell
* @param address
* @return value
*/
byte read(uint16_t);
/**
* Read bytes from the flash storage
* @param address
* @param buffer
* @param length
* @return succes
*/
int8_t readFlashBytes(uint32_t , byte*, uint32_t);
/**
* Write bytes to the flash storage
* @param address
* @param buffer
* @param length
* @return succes
*/
int8_t writeFlashBytes(uint32_t, byte*, uint32_t);
/**
* Erase a flash sector. Adress determines the flash sector to erase.
* length is specified in number of bytes. if number of bytes > sector size, more than one sector is erased
* @param address
* @param length
* @return succes
*/
int8_t eraseFlashSector(uint32_t, uint32_t);
};
#endif