diff --git a/platformio.ini b/platformio.ini index 68e0d3e2..a2948d6c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -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 diff --git a/speeduino/board_stm32_official.h b/speeduino/board_stm32_official.h index afb38591..97987b00 100644 --- a/speeduino/board_stm32_official.h +++ b/speeduino/board_stm32_official.h @@ -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 -#else - #define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h" -#endif -#ifndef LED_BUILTIN - #define LED_BUILTIN PA7 -#endif - -#if defined(FRAM_AS_EEPROM) - #include - #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 + #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 diff --git a/speeduino/globals.h b/speeduino/globals.h index a9b0930f..0da2ca2b 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -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 diff --git a/speeduino/src/BackupSram/BackupSramAsEEPROM.cpp b/speeduino/src/BackupSram/BackupSramAsEEPROM.cpp index de60e737..6e46a14b 100644 --- a/speeduino/src/BackupSram/BackupSramAsEEPROM.cpp +++ b/speeduino/src/BackupSram/BackupSramAsEEPROM.cpp @@ -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 + diff --git a/speeduino/src/BackupSram/BackupSramAsEEPROM.h b/speeduino/src/BackupSram/BackupSramAsEEPROM.h index 4d996a56..cea25b21 100644 --- a/speeduino/src/BackupSram/BackupSramAsEEPROM.h +++ b/speeduino/src/BackupSram/BackupSramAsEEPROM.h @@ -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 #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 \ No newline at end of file diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp index 61a9e146..de4b9188 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp @@ -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 * . */ - -#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 - - diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h index 529e1910..e6c9da39 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h @@ -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 -#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