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:
parent
d4899c0200
commit
6faab8e485
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue