From 2137969b7ccc886d9fe92ba4486e0ecd7ae4f41d Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Thu, 19 Sep 2019 12:20:26 +0200 Subject: [PATCH 01/11] Added new board "case 60" for development of the BLACK STM32F407VET6 boards from ebay. Creating a shield for speeduino for the board --- speeduino/init.ino | 122 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 7 deletions(-) diff --git a/speeduino/init.ino b/speeduino/init.ino index 5b601ea2..a13e29e2 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -1037,13 +1037,13 @@ void setPinMapping(byte boardID) pinCoil3 = PD2; //Pin for coil 3 pinCoil4 = PD3; //Pin for coil 4 pinCoil5 = PD4; //Pin for coil 5 - pinTPS = A0; //TPS input pin - pinMAP = A1; //MAP sensor pin - pinIAT = A2; //IAT sensor pin - pinCLT = A3; //CLT sensor pin - pinO2 = A4; //O2 Sensor pin - pinBat = A5; //Battery reference voltage pin - pinBaro = A9; + pinTPS = PA0; //TPS input pin + pinMAP = PA1; //MAP sensor pin + pinIAT = PA2; //IAT sensor pin + pinCLT = PA3; //CLT sensor pin + pinO2 = PA4; //O2 Sensor pin + pinBat = PA5; //Battery reference voltage pin + pinBaro = PA9; pinIdle1 = PB8; //Single wire idle control pinIdle2 = PB9; //2 wire idle control pinBoost = PE0; //Boost control @@ -1566,6 +1566,114 @@ void setPinMapping(byte boardID) pinSpareLOut1 = 21; //low current output spare1 break; #endif + + #if defined(STM32F407) + case 60: + //Pin definitions for experimental board Tjeerd + //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 + + //****************************************** + //******** PORTA CONNECTIONS *************** + //****************************************** + // = PA0 //Wakeup ADC123 + pinTPS = PA1 //ADC123 + pinMAP = PA2 //ADC123 + pinIAT = PA3 //ADC123 + pinCLT = PA4 //ADC12 + pinO2 = PA5 //ADC12 + pinFan = PA6 //ADC12 LED_BUILTIN_1 + pinFuelPump = PA7 //ADC12 LED_BUILTIN_2 + pinIdle1 = PA8 // + // = PA9 //TXD1 + // = PA10 //RXD1 + // = PA11 //(DO NOT USE FOR SPEEDUINO) USB + // = PA12 //(DO NOT USE FOR SPEEDUINO) USB + // = PA13 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA14 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA15 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + + //****************************************** + //******** PORTB CONNECTIONS *************** + //****************************************** + pinBat = PB0; //ADC12 + pinBaro = PB1; //ADC12 + // = PB2; //(DO NOT USE FOR SPEEDUINO) BOOT1 + // = PB3; //(DO NOT USE FOR SPEEDUINO) SPI1_SCK FLASH CHIP + // = PB4; //(DO NOT USE FOR SPEEDUINO) SPI1_MISO FLASH CHIP + // = PB5; //(DO NOT USE FOR SPEEDUINO) SPI1_MOSI FLASH CHIP + // = PB6; //NRF_CE + // = PB7; //NRF_CS + // = PB8; //NRF_IRQ + pinIdle2 = PB9; // + // = PB10; //TXD3 + // = PB11; //RXD3 + pinBoost = PB12; // + // = PB13; //SPI2_SCK + // = PB14; //SPI2_MISO + // = PB15; //SPI2_MOSI + + //****************************************** + //******** PORTC CONNECTIONS *************** + //****************************************** + // = PC0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin + // = PC1; //ADC123 + // = PC2; //ADC123 + // = PC3; //ADC123 + // = PC4; //ADC12 + // = PC5; //ADC12 + pinVVT_1 = PC6; // + pinDisplayReset = PC7; // + // = PC8; //(DO NOT USE FOR SPEEDUINO) //SDIO_D0 + // = PC9; //(DO NOT USE FOR SPEEDUINO) //SDIO_D1 + // = PC10; //(DO NOT USE FOR SPEEDUINO) //SDIO_D2 + // = PC11; //(DO NOT USE FOR SPEEDUINO) //SDIO_D3 + // = PC12; //(DO NOT USE FOR SPEEDUINO) //SDIO_SCK + pinTachOut = PC13; // + // = PC14; //(DO NOT USE FOR SPEEDUINO) //OSC32_IN + // = PC15; //(DO NOT USE FOR SPEEDUINO) //OSC32_OUT + + //****************************************** + //******** PORTD CONNECTIONS *************** + //****************************************** + // = PD0; //CANRX + // = PD1; //CANTX + // = PD2; //(DO NOT USE FOR SPEEDUINO) //SDIO_CMD + pinCoil1 = PD3; // + pinCoil2 = PD4; // + // = PD5;//TXD2 + // = PD6; //RXD2 + pinCoil3 = PD7; // + pinCoil4 = PD8; // + pinCoil5 = PD9;// + // = PD10; // + // = PD11; // + // = PD12; // + // = PD13; // + // = PD14; // + // = PD15; // + + //****************************************** + //******** PORTE CONNECTIONS *************** + //****************************************** + pinStepperDir = PE0; // + pinStepperStep = PE1; // + pinStepperEnable = PE2; // + // = PE3; //ONBOARD KEY1 + // = PE4; //ONBOARD KEY2 + pinFlex = PE5; // + pinTrigger = PE6; // + pinInjector1 = PE7; // + pinInjector2 = PE8; // + pinInjector3 = PE9; // + pinInjector4 = PE10; // + pinInjector5 = PE11; // + pinInjector6 = PE12; // + pinTrigger2 = PE13; // + // = PE14; // + // = PE15; // + + break; + #endif default: #if defined(STM32F4) From 08904904d5590cc474f80834d2773836a8143a18 Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Thu, 19 Sep 2019 20:32:44 +0200 Subject: [PATCH 02/11] Bugfix writing temperature calibrations Bug fix sram region to large --- speeduino/comms.ino | 7 +- speeduino/init.ino | 141 +++++++++++++----- speeduino/src/BackupSram/BackupSramAsEEPROM.h | 2 +- 3 files changed, 108 insertions(+), 42 deletions(-) diff --git a/speeduino/comms.ino b/speeduino/comms.ino index 33143f99..5104e85e 100644 --- a/speeduino/comms.ino +++ b/speeduino/comms.ino @@ -1641,9 +1641,10 @@ void receiveCalibration(byte tableID) bool every2nd = true; int x; int counter = 0; - pinMode(LED_BUILTIN, OUTPUT); //pinMode(13, OUTPUT); + // stm32 board has buildin led used as fuel pump + // pinMode(LED_BUILTIN, OUTPUT); //pinMode(13, OUTPUT); - digitalWrite(LED_BUILTIN, LOW); //digitalWrite(13, LOW); + // digitalWrite(LED_BUILTIN, LOW); //digitalWrite(13, LOW); for (x = 0; x < 1024; x++) { //UNlike what is listed in the protocol documentation, the O2 sensor values are sent as bytes rather than ints @@ -1682,6 +1683,8 @@ void receiveCalibration(byte tableID) every2nd = false; #if defined(CORE_STM32) digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + #elif defined(CORE_STM32_OFFICIAL) + //Of core offical do nothing. led is reserved for fuel pump #else analogWrite(LED_BUILTIN, (counter % 50) ); //analogWrite(13, (counter % 50) ); #endif diff --git a/speeduino/init.ino b/speeduino/init.ino index a13e29e2..87c778c0 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -1020,6 +1020,7 @@ void setPinMapping(byte boardID) pinCoil3 = 30; pinO2 = A22; #elif defined(STM32F4) + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 //PC8~PC12 SDio //PA13~PA15 & PB4 SWD(debug) pins @@ -1677,46 +1678,108 @@ void setPinMapping(byte boardID) default: #if defined(STM32F4) + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 - //PC8~PC12 SDio - //PA13~PA15 & PB4 SWD(debug) pins - //PB0 EEPROM CS pin - //PA9 & PD10 Serial1 - //PD5 & PD6 Serial2 - pinInjector1 = PE7; //Output pin injector 1 is on - pinInjector2 = PE8; //Output pin injector 2 is on - pinInjector3 = PE9; //Output pin injector 3 is on - pinInjector4 = PE10; //Output pin injector 4 is on - pinInjector5 = PE11; //Output pin injector 5 is on - pinInjector6 = PE12; //Output pin injector 6 is on - pinCoil1 = PD0; //Pin for coil 1 - pinCoil2 = PD1; //Pin for coil 2 - pinCoil3 = PD2; //Pin for coil 3 - pinCoil4 = PD3; //Pin for coil 4 - pinCoil5 = PD4; //Pin for coil 5 - pinTPS = A0; //TPS input pin - pinMAP = A1; //MAP sensor pin - pinIAT = A2; //IAT sensor pin - pinCLT = A3; //CLT sensor pin - pinO2 = A4; //O2 Sensor pin - pinBat = A5; //Battery reference voltage pin - pinBaro = A9; - pinIdle1 = PB8; //Single wire idle control - pinIdle2 = PB9; //2 wire idle control - pinBoost = PE0; //Boost control - pinVVT_1 = PE1; //Default VVT output - pinStepperDir = PD8; //Direction pin for DRV8825 driver - pinStepperStep = PB15; //Step pin for DRV8825 driver - pinStepperEnable = PD9; //Enable pin for DRV8825 - pinDisplayReset = PE1; // OLED reset pin - pinFan = PE2; //Pin for the fan output - pinFuelPump = PC0; //Fuel pump output - pinTachOut = PC1; //Tacho output pin - //external interrupt enabled pins - //external interrupts could be enalbed in any pin, except same port numbers (PA4,PE4) - pinFlex = PE2; // Flex sensor (Must be external interrupt enabled) - pinTrigger = PE3; //The CAS pin - pinTrigger2 = PE4; //The Cam Sensor pin + + //****************************************** + //******** PORTA CONNECTIONS *************** + //****************************************** + // = PA0 //Wakeup ADC123 + pinTPS = PA1; //ADC123 + pinMAP = PA2; //ADC123 + pinIAT = PA3; //ADC123 + pinCLT = PA4; //ADC12 + pinO2 = PA5; //ADC12 + pinFan = PA6; //ADC12 LED_BUILTIN_1 + pinFuelPump = PA7; //ADC12 LED_BUILTIN_2 + pinIdle1 = PA8; // + // = PA9; //TXD1 + // = PA10; //RXD1 + // = PA11; //(DO NOT USE FOR SPEEDUINO) USB + // = PA12; //(DO NOT USE FOR SPEEDUINO) USB + // = PA13; //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA14; //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA15; //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + + //****************************************** + //******** PORTB CONNECTIONS *************** + //****************************************** + pinBat = PB0; //ADC12 + pinBaro = PB1; //ADC12 + // = PB2; //(DO NOT USE FOR SPEEDUINO) BOOT1 + // = PB3; //(DO NOT USE FOR SPEEDUINO) SPI1_SCK FLASH CHIP + // = PB4; //(DO NOT USE FOR SPEEDUINO) SPI1_MISO FLASH CHIP + // = PB5; //(DO NOT USE FOR SPEEDUINO) SPI1_MOSI FLASH CHIP + // = PB6; //NRF_CE + // = PB7; //NRF_CS + // = PB8; //NRF_IRQ + pinIdle2 = PB9; // + // = PB10; //TXD3 + // = PB11; //RXD3 + pinBoost = PB12; // + // = PB13; //SPI2_SCK + // = PB14; //SPI2_MISO + // = PB15; //SPI2_MOSI + + //****************************************** + //******** PORTC CONNECTIONS *************** + //****************************************** + // = PC0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin + // = PC1; //ADC123 + // = PC2; //ADC123 + // = PC3; //ADC123 + // = PC4; //ADC12 + // = PC5; //ADC12 + pinVVT_1 = PC6; // + pinDisplayReset = PC7; // + // = PC8; //(DO NOT USE FOR SPEEDUINO) //SDIO_D0 + // = PC9; //(DO NOT USE FOR SPEEDUINO) //SDIO_D1 + // = PC10; //(DO NOT USE FOR SPEEDUINO) //SDIO_D2 + // = PC11; //(DO NOT USE FOR SPEEDUINO) //SDIO_D3 + // = PC12; //(DO NOT USE FOR SPEEDUINO) //SDIO_SCK + pinTachOut = PC13; // + // = PC14; //(DO NOT USE FOR SPEEDUINO) //OSC32_IN + // = PC15; //(DO NOT USE FOR SPEEDUINO) //OSC32_OUT + + //****************************************** + //******** PORTD CONNECTIONS *************** + //****************************************** + // = PD0; //CANRX + // = PD1; //CANTX + // = PD2; //(DO NOT USE FOR SPEEDUINO) //SDIO_CMD + pinCoil1 = PD3; // + pinCoil2 = PD4; // + // = PD5;//TXD2 + // = PD6; //RXD2 + pinCoil3 = PD7; // + pinCoil4 = PD8; // + pinCoil5 = PD9;// + // = PD10; // + // = PD11; // + // = PD12; // + // = PD13; // + // = PD14; // + // = PD15; // + + //****************************************** + //******** PORTE CONNECTIONS *************** + //****************************************** + pinStepperDir = PE0; // + pinStepperStep = PE1; // + pinStepperEnable = PE2; // + // = PE3; //ONBOARD KEY1 + // = PE4; //ONBOARD KEY2 + pinFlex = PE5; // + pinTrigger = PE6; // + pinInjector1 = PE7; // + pinInjector2 = PE8; // + pinInjector3 = PE9; // + pinInjector4 = PE10; // + pinInjector5 = PE11; // + pinInjector6 = PE12; // + pinTrigger2 = PE13; // + // = PE14; // + // = PE15; // #else #ifndef SMALL_FLASH_MODE //No support for bluepill here anyway //Pin mappings as per the v0.2 shield diff --git a/speeduino/src/BackupSram/BackupSramAsEEPROM.h b/speeduino/src/BackupSram/BackupSramAsEEPROM.h index b79da490..4d996a56 100644 --- a/speeduino/src/BackupSram/BackupSramAsEEPROM.h +++ b/speeduino/src/BackupSram/BackupSramAsEEPROM.h @@ -12,7 +12,7 @@ class BackupSramAsEEPROM { private: - const uint16_t backup_size = 0x4000; //maximum of 4kb backuped sram available. + const uint16_t backup_size = 4096; //maximum of 4kb backuped sram available. int8_t write_byte( uint8_t *data, uint16_t bytes, uint16_t offset ); int8_t read_byte( uint8_t *data, uint16_t bytes, uint16_t offset ); From 30acafe300db9d96fee1f24ed572ad6b33cd5971 Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Sat, 21 Sep 2019 22:52:01 +0200 Subject: [PATCH 03/11] Add SPI Flash storage as EEPROM onboard the Black STM32F407VET6 from ebay. --- speeduino/board_stm32_official.h | 2 +- speeduino/init.ino | 194 ++-- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp | 307 +++++- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h | 53 +- speeduino/src/SPIAsEEPROM/winbondflash.cpp | 389 ++++++++ speeduino/src/SPIAsEEPROM/winbondflash.h | 104 ++ speeduino/storage.ino | 1051 ++++++++++++++------ 7 files changed, 1683 insertions(+), 417 deletions(-) create mode 100644 speeduino/src/SPIAsEEPROM/winbondflash.cpp create mode 100644 speeduino/src/SPIAsEEPROM/winbondflash.h diff --git a/speeduino/board_stm32_official.h b/speeduino/board_stm32_official.h index 96c3379d..dd74654e 100644 --- a/speeduino/board_stm32_official.h +++ b/speeduino/board_stm32_official.h @@ -15,7 +15,7 @@ #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() #if defined(SRAM_AS_EEPROM) #define EEPROM_LIB_H "src/BackupSram/BackupSramAsEEPROM.h" -#elif defined(SPI_AS_EEPROM) +#elif defined(SPIFLASH_AS_EEPROM) #define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h" #else #define EEPROM_LIB_H diff --git a/speeduino/init.ino b/speeduino/init.ino index 87c778c0..5576ec3f 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -20,6 +20,8 @@ void initialiseAll() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); + startstorage(); + table3D_setSize(&fuelTable, 16); table3D_setSize(&fuelTable2, 16); table3D_setSize(&ignitionTable, 16); @@ -31,14 +33,13 @@ void initialiseAll() table3D_setSize(&trim2Table, 6); table3D_setSize(&trim3Table, 6); table3D_setSize(&trim4Table, 6); - loadConfig(); doUpdates(); //Check if any data items need updating (Occurs with firmware updates) //Always start with a clean slate on the bootloader capabilities level //This should be 0 until we hear otherwise from the 16u2 configPage4.bootloaderCaps = 0; - + initBoard(); //This calls the current individual boards init function. See the board_xxx.ino files for these. initialiseTimers(); @@ -1020,47 +1021,108 @@ void setPinMapping(byte boardID) pinCoil3 = 30; pinO2 = A22; #elif defined(STM32F4) - //Pin definitions for experimental board Tjeerd + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 - //PC8~PC12 SDio - //PA13~PA15 & PB4 SWD(debug) pins - //PB0 EEPROM CS pin - //PA9 & PD10 Serial1 - //PD5 & PD6 Serial2 - pinInjector1 = PE7; //Output pin injector 1 is on - pinInjector2 = PE8; //Output pin injector 2 is on - pinInjector3 = PE9; //Output pin injector 3 is on - pinInjector4 = PE10; //Output pin injector 4 is on - pinInjector5 = PE11; //Output pin injector 5 is on - pinInjector6 = PE12; //Output pin injector 6 is on - pinCoil1 = PD0; //Pin for coil 1 - pinCoil2 = PD1; //Pin for coil 2 - pinCoil3 = PD2; //Pin for coil 3 - pinCoil4 = PD3; //Pin for coil 4 - pinCoil5 = PD4; //Pin for coil 5 - pinTPS = PA0; //TPS input pin - pinMAP = PA1; //MAP sensor pin - pinIAT = PA2; //IAT sensor pin - pinCLT = PA3; //CLT sensor pin - pinO2 = PA4; //O2 Sensor pin - pinBat = PA5; //Battery reference voltage pin - pinBaro = PA9; - pinIdle1 = PB8; //Single wire idle control - pinIdle2 = PB9; //2 wire idle control - pinBoost = PE0; //Boost control - pinVVT_1 = PE1; //Default VVT output - pinStepperDir = PD8; //Direction pin for DRV8825 driver - pinStepperStep = PB15; //Step pin for DRV8825 driver - pinStepperEnable = PD9; //Enable pin for DRV8825 - pinDisplayReset = PE1; // OLED reset pin - pinFan = PE2; //Pin for the fan output - pinFuelPump = PC0; //Fuel pump output - pinTachOut = PC1; //Tacho output pin - //external interrupt enabled pins - //external interrupts could be enalbed in any pin, except same port numbers (PA4,PE4) - pinFlex = PE2; // Flex sensor (Must be external interrupt enabled) - pinTrigger = PE3; //The CAS pin - pinTrigger2 = PE4; //The Cam Sensor pin + + //****************************************** + //******** PORTA CONNECTIONS *************** + //****************************************** + // = PA0 //Wakeup ADC123 + pinTPS = PA1; //ADC123 + pinMAP = PA2; //ADC123 + pinIAT = PA3; //ADC123 + pinCLT = PA4; //ADC12 + pinO2 = PA5; //ADC12 + pinFan = PA6; //ADC12 LED_BUILTIN_1 + pinFuelPump = PA7; //ADC12 LED_BUILTIN_2 + pinIdle1 = PA8; // + // = PA9 //TXD1 + // = PA10 //RXD1 + // = PA11 //(DO NOT USE FOR SPEEDUINO) USB + // = PA12 //(DO NOT USE FOR SPEEDUINO) USB + // = PA13 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA14 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA15 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + + //****************************************** + //******** PORTB CONNECTIONS *************** + //****************************************** + // = PB0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin + pinBaro = PB1; //ADC12 + // = PB2; //(DO NOT USE FOR SPEEDUINO) BOOT1 + // = PB3; //(DO NOT USE FOR SPEEDUINO) SPI1_SCK FLASH CHIP + // = PB4; //(DO NOT USE FOR SPEEDUINO) SPI1_MISO FLASH CHIP + // = PB5; //(DO NOT USE FOR SPEEDUINO) SPI1_MOSI FLASH CHIP + // = PB6; //NRF_CE + // = PB7; //NRF_CS + // = PB8; //NRF_IRQ + pinIdle2 = PB9; // + // = PB10; //TXD3 + // = PB11; //RXD3 + pinBoost = PB12; // + // = PB13; //SPI2_SCK + // = PB14; //SPI2_MISO + // = PB15; //SPI2_MOSI + + //****************************************** + //******** PORTC CONNECTIONS *************** + //****************************************** + // = PC0; //ADC123 + pinBat = PC1; //ADC123 + // = PC2; //ADC123 + // = PC3; //ADC123 + // = PC4; //ADC12 + // = PC5; //ADC12 + pinVVT_1 = PC6; // + pinDisplayReset = PC7; // + // = PC8; //(DO NOT USE FOR SPEEDUINO) //SDIO_D0 + // = PC9; //(DO NOT USE FOR SPEEDUINO) //SDIO_D1 + // = PC10; //(DO NOT USE FOR SPEEDUINO) //SDIO_D2 + // = PC11; //(DO NOT USE FOR SPEEDUINO) //SDIO_D3 + // = PC12; //(DO NOT USE FOR SPEEDUINO) //SDIO_SCK + pinTachOut = PC13; // + // = PC14; //(DO NOT USE FOR SPEEDUINO) //OSC32_IN + // = PC15; //(DO NOT USE FOR SPEEDUINO) //OSC32_OUT + + //****************************************** + //******** PORTD CONNECTIONS *************** + //****************************************** + // = PD0; //CANRX + // = PD1; //CANTX + // = PD2; //(DO NOT USE FOR SPEEDUINO) //SDIO_CMD + pinCoil1 = PD3; // + pinCoil2 = PD4; // + // = PD5;//TXD2 + // = PD6; //RXD2 + pinCoil3 = PD7; // + pinCoil4 = PD8; // + pinCoil5 = PD9;// + // = PD10; // + // = PD11; // + // = PD12; // + // = PD13; // + // = PD14; // + // = PD15; // + + //****************************************** + //******** PORTE CONNECTIONS *************** + //****************************************** + pinStepperDir = PE0; // + pinStepperStep = PE1; // + pinStepperEnable = PE2; // + // = PE3; //ONBOARD KEY1 + // = PE4; //ONBOARD KEY2 + pinFlex = PE5; // + pinTrigger = PE6; // + pinInjector1 = PE7; // + pinInjector2 = PE8; // + pinInjector3 = PE9; // + pinInjector4 = PE10; // + pinInjector5 = PE11; // + pinInjector6 = PE12; // + pinTrigger2 = PE13; // + // = PE14; // + // = PE15; // #elif defined(CORE_STM32) //blue pill wiki.stm32duino.com/index.php?title=Blue_Pill //Maple mini wiki.stm32duino.com/index.php?title=Maple_Mini @@ -1568,23 +1630,23 @@ void setPinMapping(byte boardID) break; #endif - #if defined(STM32F407) + #if defined(STM32F4) case 60: - //Pin definitions for experimental board Tjeerd + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 //****************************************** //******** PORTA CONNECTIONS *************** //****************************************** // = PA0 //Wakeup ADC123 - pinTPS = PA1 //ADC123 - pinMAP = PA2 //ADC123 - pinIAT = PA3 //ADC123 - pinCLT = PA4 //ADC12 - pinO2 = PA5 //ADC12 - pinFan = PA6 //ADC12 LED_BUILTIN_1 - pinFuelPump = PA7 //ADC12 LED_BUILTIN_2 - pinIdle1 = PA8 // + pinTPS = PA1; //ADC123 + pinMAP = PA2; //ADC123 + pinIAT = PA3; //ADC123 + pinCLT = PA4; //ADC12 + pinO2 = PA5; //ADC12 + pinFan = PA6; //ADC12 LED_BUILTIN_1 + pinFuelPump = PA7; //ADC12 LED_BUILTIN_2 + pinIdle1 = PA8; // // = PA9 //TXD1 // = PA10 //RXD1 // = PA11 //(DO NOT USE FOR SPEEDUINO) USB @@ -1596,7 +1658,7 @@ void setPinMapping(byte boardID) //****************************************** //******** PORTB CONNECTIONS *************** //****************************************** - pinBat = PB0; //ADC12 + // = PB0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin pinBaro = PB1; //ADC12 // = PB2; //(DO NOT USE FOR SPEEDUINO) BOOT1 // = PB3; //(DO NOT USE FOR SPEEDUINO) SPI1_SCK FLASH CHIP @@ -1616,8 +1678,8 @@ void setPinMapping(byte boardID) //****************************************** //******** PORTC CONNECTIONS *************** //****************************************** - // = PC0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin - // = PC1; //ADC123 + // = PC0; //ADC123 + pinBat = PC1; //ADC123 // = PC2; //ADC123 // = PC3; //ADC123 // = PC4; //ADC12 @@ -1678,7 +1740,7 @@ void setPinMapping(byte boardID) default: #if defined(STM32F4) - //Pin definitions for experimental board Tjeerd + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 //****************************************** @@ -1693,18 +1755,18 @@ void setPinMapping(byte boardID) pinFan = PA6; //ADC12 LED_BUILTIN_1 pinFuelPump = PA7; //ADC12 LED_BUILTIN_2 pinIdle1 = PA8; // - // = PA9; //TXD1 - // = PA10; //RXD1 - // = PA11; //(DO NOT USE FOR SPEEDUINO) USB - // = PA12; //(DO NOT USE FOR SPEEDUINO) USB - // = PA13; //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK - // = PA14; //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK - // = PA15; //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA9 //TXD1 + // = PA10 //RXD1 + // = PA11 //(DO NOT USE FOR SPEEDUINO) USB + // = PA12 //(DO NOT USE FOR SPEEDUINO) USB + // = PA13 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA14 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK + // = PA15 //(DO NOT USE FOR SPEEDUINO) //NOT ON GPIO //DEBUG ST-LINK //****************************************** //******** PORTB CONNECTIONS *************** //****************************************** - pinBat = PB0; //ADC12 + // = PB0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin pinBaro = PB1; //ADC12 // = PB2; //(DO NOT USE FOR SPEEDUINO) BOOT1 // = PB3; //(DO NOT USE FOR SPEEDUINO) SPI1_SCK FLASH CHIP @@ -1724,8 +1786,8 @@ void setPinMapping(byte boardID) //****************************************** //******** PORTC CONNECTIONS *************** //****************************************** - // = PC0; (DO NOT USE FOR SPEEDUINO)//ADC123 //SPI FLASH CHIP CS pin - // = PC1; //ADC123 + // = PC0; //ADC123 + pinBat = PC1; //ADC123 // = PC2; //ADC123 // = PC3; //ADC123 // = PC4; //ADC12 diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp index 0142a80a..1ed91055 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp @@ -2,40 +2,307 @@ * This file implements a shim layer for the SPIMemory library (https://github.com/Marzogh/SPIMemory) to mimic a minimal * subset of the standard Arduino EEPROM library */ -#if defined(SPI_AS_EEPROM) +//Working example on BLACK_STM32F407VET6 with official stm32 core from ST + +#if defined(CORE_STM32_OFFICIAL) && defined(SPIFLASH_AS_EEPROM) #include "SPIAsEEPROM.h" -#include "SPIMemory.h" -#include +#include "SPI.h" + +//winbondSPIFlash flash(SS1, &SPI); //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus -//SPIFlash flash; -SPIFlash flash(SS1, &SPI); //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus SPIAsEEPROM::SPIAsEEPROM() { - //Do some init stuff here + pinMode(PB0, OUTPUT); + magicbuf[0] = MAGICNUMBER1; + magicbuf[1] = MAGICNUMBER2; + magicbuf[2] = MAGICNUMBER3; + magicbuf[3] = 0x00; - flash.begin(); - //To use a custom flash memory size (if using memory from manufacturers not officially supported by the library) - declare a size variable according to the list in defines.h - //flash.begin(MB(1)); + } + uint8_t SPIAsEEPROM::begin() { + uint8_t SpiFlashAvialable = 0; + SpiFlashAvialable = winbondSPIFlash.begin(_W25Q16,SPI,PB0); + // winbondSPIFlash.WE(); + // winbondSPIFlash.eraseAll(); + // while(winbondSPIFlash.busy()); + + //Debugging + // if(val){Serial.println("OK");} + uint8_t formatted = 0; + if(SpiFlashAvialable){ + //check for magic numbers + formatted = 1; + uint8_t buf[MAGICNUMBER_OFFSET]; + for(uint16_t i=0; i< FLASHSIZEUSED/SECTORSIZE; i++ ){ + winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); + if(buf[0] != MAGICNUMBER1 | buf[1] != MAGICNUMBER2 | buf[2] != MAGICNUMBER3 ){ + formatted = 0; + } + } + + if(!formatted){ + formatFlashForUse(); + } + + //check if format succeeded + formatted = 1; + for(uint16_t i=0; i< FLASHSIZEUSED/SECTORSIZE; i++ ){ + winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); + if(buf[0] != MAGICNUMBER1 | buf[1] != MAGICNUMBER2 | buf[2] != MAGICNUMBER3 ){ + formatted = 0; + } + } + + // Serial.print("formatted"); + // Serial.println(formatted, DEC); + } + if(formatted & SpiFlashAvialable){return true;}else{return false;} + } + +int8_t SPIAsEEPROM::write(uint16_t addressEEPROM, uint8_t writeValue){ + if (addressEEPROM >= FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2)){addressEEPROM = FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2);} + uint8_t readValue = read(addressEEPROM); + + // Serial.print("readValue"); + // Serial.println(readValue, DEC); + // Serial.print("writeValue"); + // Serial.println(writeValue, DEC); + + //After reading the byte all global variables containing inforamtion about the address are set correctly. + + //only write if value is changed. + if (readValue != writeValue){ + + //Check if buffer is full + if (nrOfOnes < 1){ + //Serial.println("A sector gets erased and hoppfully writen back"); + //now the buffer is full and an erase must be done + + //First read all the values in this sector that will get distroyed when erasing + uint8_t tempBuf[14]; + for(uint8_t i = 0; i<14; i++){ + tempBuf[i] = read((sectorNumber*14) + i); + } + + //now erase the sector + writeMagicNumber(sectorNumber); + + //write all the values back + // Serial.println("Start re-writing values"); + for(uint8_t i=0; i<14; i++){ + write((sectorNumber*14) + i, tempBuf[i]); + } + // Serial.println("End re-writing values"); + + write(addressEEPROM, writeValue); + + // Serial.println("New value re-writing"); + return 0; + + } + + //determine the adress of the byte in the infoblock where one bit must be reset when writing new values + uint8_t RelativeAdressInInfoBlock = (nrOfOnes - 1)/8; + + // Serial.print("RelativeAdressInInfoBlock"); + // Serial.println(RelativeAdressInInfoBlock, DEC); + + //determine value of the infoblock byte after writing one more time. + uint8_t ValueInInfoBlock = 0xFF << (8 - (nrOfOnes - 1 - ((RelativeAdressInInfoBlock) * 8))); + + // Serial.print("ValueInInfoBlock"); + // Serial.println(ValueInInfoBlock, DEC); + + uint8_t ByteBuf[1]; + + // Serial.print("dataFlashAddress"); + // Serial.println(dataFlashAddress, DEC); + + // Serial.print("sizeof(ByteBuf)"); + // Serial.println(sizeof(ByteBuf), DEC); + + //write the new value at the new location + ByteBuf[0] = writeValue; + winbondSPIFlash.WE(); + winbondSPIFlash.writePage(dataFlashAddress - 1, ByteBuf, sizeof(ByteBuf)); + while(winbondSPIFlash.busy()); + + // Serial.print("infoFlashAddress"); + // Serial.println(infoFlashAddress, DEC); + + //write where read can find the new value + ByteBuf[0] = ValueInInfoBlock; + winbondSPIFlash.WE(); + winbondSPIFlash.writePage(infoFlashAddress + RelativeAdressInInfoBlock, ByteBuf, sizeof(ByteBuf)); + while(winbondSPIFlash.busy()); + + //read the infoblock and put into the buffer + // uint8_t buf[256]; + // winbondSPIFlash.read(infoFlashAddress, buf, sizeof(buf) - 1); + // while(winbondSPIFlash.busy()); + + // Serial.print("Buffer: "); + // for (uint16_t i = 0; i=FLASHSIZEUSED/SECTORSIZE){ + sectorNumber = (FLASHSIZEUSED/SECTORSIZE - 1); + } + // Serial.print("Sector number to erase"); + // Serial.println(sectorNumber); + winbondSPIFlash.WE(); + winbondSPIFlash.eraseSector(sectorNumber*SECTORSIZE); + while(winbondSPIFlash.busy()); + winbondSPIFlash.WE(); + winbondSPIFlash.writePage(sectorNumber*SECTORSIZE, magicbuf, MAGICNUMBER_OFFSET); + while(winbondSPIFlash.busy()); + + // Serial.print("sizeof(magicbuf)"); + // Serial.println(sizeof(magicbuf), DEC); + + + // uint8_t buf[256]; + // winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); + // Serial.print("Buffer: "); + // for (uint16_t i = 0; i= FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2)){addressEEPROM = FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2);} - return val; + // Serial.print("byte adress"); + // Serial.println(addressEEPROM, DEC); + uint8_t buf[INFOBYTES_PER_BYTE]; + + //Check at what sector number the adress resides. 14 bytes per sector + sectorNumber = addressEEPROM/(SECTORSIZE/FLASH_PAGESIZE - 2); + + // Serial.print("sectorNumber"); + // Serial.println(sectorNumber, DEC); + + //Check at what page number in the sector the adress can be found (16 pages per sector, 14 used) + pageNumber = addressEEPROM - (sectorNumber * ((SECTORSIZE/FLASH_PAGESIZE) - 2)); + + // Serial.print("pageNumber"); + // Serial.println(pageNumber, DEC); + + //The absulute adress of the infoblock of the byte in flash adress + infoFlashAddress = sectorNumber*SECTORSIZE + pageNumber * INFOBYTES_PER_BYTE + MAGICNUMBER_OFFSET; + + //read the infoblock and put into the buffer + winbondSPIFlash.read(infoFlashAddress, buf, sizeof(buf)); + + // Serial.print("InfoblockBuffer: "); + // for (uint16_t i = 0; i>1;//right shift + } + return count; } SPIAsEEPROM EEPROM; diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h index 0acaf828..a491f330 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h @@ -1,21 +1,60 @@ #ifndef SPI_AS_EEPROM_H #define SPI_AS_EEPROM_H -#if defined(SPI_AS_EEPROM) +#if defined(CORE_STM32_OFFICIAL) && defined(SPIFLASH_AS_EEPROM) + +// //UGLY HACK TO PREVENT EEPROM LIBRARY BEING IMPORTED FIRST!! +// //Use with black_F407VE board +// #ifndef EEPROM_h +// #define EEPROM_h + + +#define FLASHSIZEUSED 1245184 //must be a multiple of sectorsize //1245184 = 4228 bytes of EEPROM +#define BYTESPERSECTOR 14 +#define SECTORSIZE 4096 +#define INFOBYTESSECTOROFFSET 512 +#define FLASH_PAGESIZE 256 +#define MAGICNUMBER1 0xC0 +#define MAGICNUMBER2 0xFF +#define MAGICNUMBER3 0xEE +#define MAGICNUMBER_OFFSET 4 +#define BITS_PER_BYTE 8 + +//Need one bit per byte to determine location actual data +//256bits/8 so 32 bytes +#define INFOBYTES_PER_BYTE FLASH_PAGESIZE/BITS_PER_BYTE #include +#include +#include "winbondflash.h" + +// winbondFlashSPI winbondSPIFlash; class SPIAsEEPROM { private: - + winbondFlashSPI winbondSPIFlash; + uint8_t ReadOutBuffer[BYTESPERSECTOR]; + uint8_t magicbuf[4]; + uint16_t sectorNumber; + uint16_t pageNumber; + uint16_t nrOfOnes; + uint32_t dataFlashAddress; + uint32_t infoFlashAddress; + uint8_t writeMagicNumber(uint16_t sectorNumber); + uint16_t count(uint8_t buf[FLASH_PAGESIZE/BITS_PER_BYTE]); + public: + SPIAsEEPROM(); - uint8_t read(uint16_t address); - int8_t write(uint16_t address, uint8_t val); + uint8_t begin(); + uint8_t formatFlashForUse(); + uint8_t read(uint16_t addressEEPROM); + int8_t write(uint16_t addressEEPROM, uint8_t val); int8_t update(uint16_t address, uint8_t val); }; -extern SPIAsEEPROM EEPROM; - #endif -#endif \ No newline at end of file +#endif +// #endif + +extern SPIAsEEPROM EEPROM; diff --git a/speeduino/src/SPIAsEEPROM/winbondflash.cpp b/speeduino/src/SPIAsEEPROM/winbondflash.cpp new file mode 100644 index 00000000..c1fc58be --- /dev/null +++ b/speeduino/src/SPIAsEEPROM/winbondflash.cpp @@ -0,0 +1,389 @@ +/* + Winbond spi flash memory chip operating library for Arduino + by WarMonkey (luoshumymail@gmail.com) + for more information, please visit bbs.kechuang.org + latest version available on http://code.google.com/p/winbondflash +*/ + +#include +#include +#include +#include "winbondflash.h" + +//COMMANDS +#define W_EN 0x06 //write enable +#define W_DE 0x04 //write disable +#define R_SR1 0x05 //read status reg 1 +#define R_SR2 0x35 //read status reg 2 +#define W_SR 0x01 //write status reg +#define PAGE_PGM 0x02 //page program +#define QPAGE_PGM 0x32 //quad input page program +#define BLK_E_64K 0xD8 //block erase 64KB +#define BLK_E_32K 0x52 //block erase 32KB +#define SECTOR_E 0x20 //sector erase 4KB +#define CHIP_ERASE 0xc7 //chip erase +#define CHIP_ERASE2 0x60 //=CHIP_ERASE +#define E_SUSPEND 0x75 //erase suspend +#define E_RESUME 0x7a //erase resume +#define PDWN 0xb9 //power down +#define HIGH_PERF_M 0xa3 //high performance mode +#define CONT_R_RST 0xff //continuous read mode reset +#define RELEASE 0xab //release power down or HPM/Dev ID (deprecated) +#define R_MANUF_ID 0x90 //read Manufacturer and Dev ID (deprecated) +#define R_UNIQUE_ID 0x4b //read unique ID (suggested) +#define R_JEDEC_ID 0x9f //read JEDEC ID = Manuf+ID (suggested) +#define READ 0x03 +#define FAST_READ 0x0b + +#define SR1_BUSY_MASK 0x01 +#define SR1_WEN_MASK 0x02 + +#define WINBOND_MANUF 0xef + +#define DEFAULT_TIMEOUT 200 + +typedef struct { + winbondFlashClass::partNumber pn; + uint16_t id; + uint32_t bytes; + uint16_t pages; + uint16_t sectors; + uint16_t blocks; +}pnListType; + +static const pnListType pnList[] PROGMEM = { + { winbondFlashClass::W25Q80, 0x4014,1048576, 4096, 256, 16 }, + { winbondFlashClass::W25Q16, 0x4015,2097152, 8192, 512, 32 }, + { winbondFlashClass::W25Q32, 0x4016,4194304, 16384,1024,64 }, + { winbondFlashClass::W25Q64, 0x4017,8388608, 32768,2048,128 }, + { winbondFlashClass::W25Q128,0x4018,16777216,65536,4096,256 } +}; + + +uint16_t winbondFlashClass::readSR() +{ + uint8_t r1,r2; + select(); + transfer(R_SR1); + r1 = transfer(0xff); + deselect(); + deselect();//some delay + select(); + transfer(R_SR2); + r2 = transfer(0xff); + deselect(); + return (((uint16_t)r2)<<8)|r1; +} + +uint8_t winbondFlashClass::readManufacturer() +{ + uint8_t c; + select(); + transfer(R_JEDEC_ID); + c = transfer(0x00); + transfer(0x00); + transfer(0x00); + deselect(); + return c; +} + +uint64_t winbondFlashClass::readUniqueID() +{ + uint64_t uid; + uint8_t *arr; + arr = (uint8_t*)&uid; + select(); + transfer(R_UNIQUE_ID); + transfer(0x00); + transfer(0x00); + transfer(0x00); + transfer(0x00); + //for little endian machine only + for(int i=7;i>=0;i--) + { + arr[i] = transfer(0x00); + } + deselect(); + return uid; +} + +uint16_t winbondFlashClass::readPartID() +{ + uint8_t a,b; + select(); + transfer(R_JEDEC_ID); + transfer(0x00); + a = transfer(0x00); + b = transfer(0x00); + deselect(); + return (a<<8)|b; +} + +bool winbondFlashClass::checkPartNo(partNumber _partno) +{ + uint8_t manuf; + uint16_t id; + + select(); + transfer(R_JEDEC_ID); + manuf = transfer(0x00); + id = transfer(0x00) << 8; + id |= transfer(0x00); + deselect(); + + //Serial1.print("MANUF=0x"); + //Serial1.print(manuf,HEX); + //Serial1.print(",ID=0x"); + //Serial1.print(id,HEX); + //Serial1.println(); + + //Serial1.print("MANUF=0x"); + //Serial1.println(WINBOND_MANUF,HEX); + + if(manuf != WINBOND_MANUF){ + //Serial1.println("MANUF NOT OK"); + return false; + } + + if(_partno == custom) + return true; + //Serial.println("Not a custom chip type"); + + if(_partno == autoDetect) + { + //Serial1.print("Autodetect..."); + for(int i=0;i3us + //Serial1.println("Chip Released"); + + if(!checkPartNo(_partno)) return false; + else return true; +} + +void winbondFlashClass::end() +{ + select(); + transfer(PDWN); + deselect(); + delayMicroseconds(15);//>3us +} + +uint16_t winbondFlashClass::read (uint32_t addr,uint8_t *buf,uint16_t n) +{ + if(busy()) + return 0; + + select(); + transfer(READ); + transfer(addr>>16); + transfer(addr>>8); + transfer(addr); + for(uint16_t i=0;i>16); + transfer(addr_start>>8); + transfer(addr_start); + + + for(uint16_t i=0; i < n; i++) + { + transfer(buf[i]); + } + + //uint8_t i=0; + //do { + // transfer(buf[i]); + // i++; + //}while(i!=sizeof(buf)); + + deselect(); +} + +void winbondFlashClass::eraseSector(uint32_t addr_start) +{ + select(); + transfer(SECTOR_E); + transfer(addr_start>>16); + transfer(addr_start>>8); + transfer(addr_start); + deselect(); +} + +void winbondFlashClass::erase32kBlock(uint32_t addr_start) +{ + select(); + transfer(BLK_E_32K); + transfer(addr_start>>16); + transfer(addr_start>>8); + transfer(addr_start); + deselect(); +} + +void winbondFlashClass::erase64kBlock(uint32_t addr_start) +{ + select(); + transfer(BLK_E_64K); + transfer(addr_start>>16); + transfer(addr_start>>8); + transfer(addr_start); + deselect(); +} + +void winbondFlashClass::eraseAll() +{ + select(); + transfer(CHIP_ERASE); + deselect(); +} + +void winbondFlashClass::eraseSuspend() +{ + select(); + transfer(E_SUSPEND); + deselect(); +} + +void winbondFlashClass::eraseResume() +{ + select(); + transfer(E_RESUME); + deselect(); +} + +bool winbondFlashSPI::begin(partNumber _partno,SPIClass &_spi,uint8_t _nss) +{ + //spi = _spi; + nss = _nss; + + // pinMode(MISO,INPUT_PULLUP); + SPI.begin(); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV16); + SPI.setDataMode(SPI_MODE0); + deselect(); + // Serial.println("SPI OK"); + + return winbondFlashClass::begin(_partno); +} + +void winbondFlashSPI::end() +{ + winbondFlashClass::end(); + SPI.end(); +} + + + diff --git a/speeduino/src/SPIAsEEPROM/winbondflash.h b/speeduino/src/SPIAsEEPROM/winbondflash.h new file mode 100644 index 00000000..0fda28b9 --- /dev/null +++ b/speeduino/src/SPIAsEEPROM/winbondflash.h @@ -0,0 +1,104 @@ +/* + Winbond spi flash memory chip operating library for Arduino + by WarMonkey (luoshumymail@gmail.com) + for more information, please visit bbs.kechuang.org + latest version available on http://code.google.com/p/winbondflash +*/ + +#ifndef _WINBONDFLASH_H__ +#define _WINBONDFLASH_H__ + +#include +#include + +//W25Q64 = 256_bytes_per_page * 16_pages_per_sector * 16_sectors_per_block * 128_blocks_per_chip +//= 256b*16*16*128 = 8Mbyte = 64MBits + +#define _W25Q80 winbondFlashClass::W25Q80 +#define _W25Q16 winbondFlashClass::W25Q16 +#define _W25Q32 winbondFlashClass::W25Q32 +#define _W25Q64 winbondFlashClass::W25Q64 +#define _W25Q128 winbondFlashClass::W25Q128 + +class winbondFlashClass { +public: + enum partNumber { + custom = -1, + autoDetect = 0, + W25Q80 = 1, + W25Q16 = 2, + W25Q32 = 4, + W25Q64 = 8, + W25Q128 = 16 + }; + + bool begin(partNumber _partno = autoDetect); + void end(); + + long bytes(); + uint16_t pages(); + uint16_t sectors(); + uint16_t blocks(); + + uint16_t read(uint32_t addr,uint8_t *buf,uint16_t n=256); + + void setWriteEnable(bool cmd = true); + inline void WE(bool cmd = true) {setWriteEnable(cmd);} + + //WE() every time before write or erase + void writePage(uint32_t addr_start,uint8_t *buf, uint16_t n);//addr is 8bit-aligned, 0x00ffff00 + //write a page, sizeof(buf) is 256 bytes + void eraseSector(uint32_t addr);//addr is 12bit-aligned, 0x00fff000 + //erase a sector ( 4096bytes ), return false if error + void erase32kBlock(uint32_t addr);//addr is 15bit-aligned, 0x00ff8000 + //erase a 32k block ( 32768b ) + void erase64kBlock(uint32_t addr);//addr is 16bit-aligned, 0x00ff0000 + //erase a 64k block ( 65536b ) + void eraseAll(); + //chip erase, return true if successfully started, busy()==false -> erase complete + + void eraseSuspend(); + void eraseResume(); + + bool busy(); + + uint8_t readManufacturer(); + uint16_t readPartID(); + uint64_t readUniqueID(); + uint16_t readSR(); + +private: + partNumber partno; + bool checkPartNo(partNumber _partno); + +protected: + virtual void select() = 0; + virtual uint8_t transfer(uint8_t x) = 0; + virtual void deselect() = 0; + +}; + +class winbondFlashSPI: public winbondFlashClass { +private: + uint8_t nss; + // SPIClass spi; + inline void select() { + digitalWrite(nss,LOW); + } + + inline uint8_t transfer(uint8_t x) { + byte y = SPI.transfer(x); + return y; + } + + inline void deselect() { + digitalWrite(nss,HIGH); + } + +public: + bool begin(partNumber _partno = autoDetect,SPIClass &_spi = SPI,uint8_t _nss = SS); + void end(); +}; + +#endif + diff --git a/speeduino/storage.ino b/speeduino/storage.ino index 0970bfc4..98215b20 100644 --- a/speeduino/storage.ino +++ b/speeduino/storage.ino @@ -11,6 +11,12 @@ A full copy of the license may be found in the projects root directory #include EEPROM_LIB_H //This is defined in the board .h files #include "storage.h" +void startstorage(){ + #if defined(SPIFLASH_AS_EEPROM) + EEPROM.begin(); + #endif +} + void writeAllConfig() { writeConfig(veSetPage); @@ -32,6 +38,727 @@ Takes the current configuration (config pages and maps) and writes them to EEPROM as per the layout defined in storage.h */ void writeConfig(byte tableNum) +{ + // EEPROM.begin(); + /* + We only ever write to the EEPROM where the new value is different from the currently stored byte + This is due to the limited write life of the EEPROM (Approximately 100,000 writes) + */ + + int offset; + int i, z, y; + int writeCounter = 0; + byte newVal; //Used for tempoerarily storing the new intended value + //Create a pointer to the config page + byte* pnt_configPage; + + switch(tableNum) + { + case veMapPage: + /*--------------------------------------------------- + | Fuel table (See storage.h for data layout) - Page 1 + | 16x16 table itself + the 16 values along each of the axis + -----------------------------------------------------*/ + if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); writeCounter++; } //Write the VE Tables RPM dimension size + if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); writeCounter++; } //Write the VE Tables MAP/TPS dimension size + for(int x=EEPROM_CONFIG1_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG1_MAP; + if( EEPROM.read(x) != (fuelTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map + } + + //RPM bins + for(int x=EEPROM_CONFIG1_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG1_XBINS; + if( EEPROM.read(x) != (byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG1_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG1_YBINS; + EEPROM.update(x, fuelTable.axisY[offset] / TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + } + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + break; + //That concludes the writing of the VE table + + case veSetPage: + EEPROM.read(0); + /*--------------------------------------------------- + | Config page 2 (See storage.h for data layout) + | 64 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory + for(int x=EEPROM_CONFIG2_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))); writeCounter++; } + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case ignMapPage: + /*--------------------------------------------------- + | Ignition table (See storage.h for data layout) - Page 1 + | 16x16 table itself + the 16 values along each of the axis + -----------------------------------------------------*/ + //Begin writing the Ignition table, basically the same thing as above + if(EEPROM.read(EEPROM_CONFIG3_XSIZE) != ignitionTable.xSize) { EEPROM.write(EEPROM_CONFIG3_XSIZE,ignitionTable.xSize); writeCounter++; } //Write the ignition Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG3_YSIZE) != ignitionTable.ySize) { EEPROM.write(EEPROM_CONFIG3_YSIZE,ignitionTable.ySize); writeCounter++; } //Write the ignition Table MAP/TPS dimension size + + for(int x=EEPROM_CONFIG3_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG3_MAP; + newVal = ignitionTable.values[15-(offset/16)][offset%16]; + if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //Write the 16x16 map with translation + } + //RPM bins + for(int x=EEPROM_CONFIG3_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG3_XBINS; + newVal = ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER; + if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG3_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG3_YBINS; + newVal = ignitionTable.axisY[offset]/TABLE_LOAD_MULTIPLIER; + if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //Table load is divided by 2 (Allows for MAP up to 511) + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case ignSetPage: + /*--------------------------------------------------- + | Config page 2 (See storage.h for data layout) + | 64 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 2 in memory + for(int x=EEPROM_CONFIG4_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))); writeCounter++; } + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case afrMapPage: + /*--------------------------------------------------- + | AFR table (See storage.h for data layout) - Page 5 + | 16x16 table itself + the 16 values along each of the axis + -----------------------------------------------------*/ + //Begin writing the Ignition table, basically the same thing as above + if(EEPROM.read(EEPROM_CONFIG5_XSIZE) != afrTable.xSize) { EEPROM.write(EEPROM_CONFIG5_XSIZE,afrTable.xSize); writeCounter++; } //Write the ignition Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG5_YSIZE) != afrTable.ySize) { EEPROM.write(EEPROM_CONFIG5_YSIZE,afrTable.ySize); writeCounter++; } //Write the ignition Table MAP/TPS dimension size + + for(int x=EEPROM_CONFIG5_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG5_MAP; + if(EEPROM.read(x) != (afrTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, afrTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map + } + //RPM bins + for(int x=EEPROM_CONFIG5_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG5_XBINS; + if(EEPROM.read(x) != byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG5_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG5_YBINS; + EEPROM.update(x, afrTable.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case afrSetPage: + /*--------------------------------------------------- + | Config page 3 (See storage.h for data layout) + | 64 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage6; //Create a pointer to Page 3 in memory + for(int x=EEPROM_CONFIG6_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))); writeCounter++; } + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case boostvvtPage: + /*--------------------------------------------------- + | Boost and vvt tables (See storage.h for data layout) - Page 8 + | 8x8 table itself + the 8 values along each of the axis + -----------------------------------------------------*/ + //Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1) + if(EEPROM.read(EEPROM_CONFIG7_XSIZE1) != boostTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE1,boostTable.xSize); writeCounter++; } //Write the boost Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG7_YSIZE1) != boostTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE1,boostTable.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size + if(EEPROM.read(EEPROM_CONFIG7_XSIZE2) != vvtTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE2,vvtTable.xSize); writeCounter++; } //Write the vvt Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG7_YSIZE2) != vvtTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE2,vvtTable.ySize); writeCounter++; } //Write the vvt Table MAP/TPS dimension size + if(EEPROM.read(EEPROM_CONFIG7_XSIZE3) != stagingTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE3,stagingTable.xSize); writeCounter++; } //Write the staging Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG7_YSIZE3) != stagingTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE3,stagingTable.ySize); writeCounter++; } //Write the staging Table MAP/TPS dimension size + + y = EEPROM_CONFIG7_MAP2; //We do the 3 maps together in the same loop + z = EEPROM_CONFIG7_MAP3; + for(int x=EEPROM_CONFIG7_MAP1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG7_MAP1; + if(EEPROM.read(x) != (boostTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(x, boostTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map + offset = y - EEPROM_CONFIG7_MAP2; + if(EEPROM.read(y) != (vvtTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(y, vvtTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map + offset = z - EEPROM_CONFIG7_MAP3; + if(EEPROM.read(z) != (stagingTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(z, stagingTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map + y++; + z++; + } + //RPM bins + y = EEPROM_CONFIG7_XBINS2; + z = EEPROM_CONFIG7_XBINS3; + for(int x=EEPROM_CONFIG7_XBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG7_XBINS1; + if(EEPROM.read(x) != byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + offset = y - EEPROM_CONFIG7_XBINS2; + if(EEPROM.read(y) != byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(y, byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + offset = z - EEPROM_CONFIG7_XBINS3; + if(EEPROM.read(z) != byte(stagingTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(z, byte(stagingTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + y++; + z++; + } + //TPS/MAP bins + y=EEPROM_CONFIG7_YBINS2; + z=EEPROM_CONFIG7_YBINS3; + for(int x=EEPROM_CONFIG7_YBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG7_YBINS1; + if(EEPROM.read(x) != boostTable.axisY[offset]) { EEPROM.write(x, boostTable.axisY[offset]); writeCounter++; } //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100) + offset = y - EEPROM_CONFIG7_YBINS2; + if(EEPROM.read(y) != vvtTable.axisY[offset]) { EEPROM.write(y, vvtTable.axisY[offset]); writeCounter++; } //TABLE_LOAD_MULTIPLIER is NOT used for VVT as it is TPS based (0-100) + offset = z - EEPROM_CONFIG7_YBINS3; + if(EEPROM.read(z) != byte(stagingTable.axisY[offset]/TABLE_LOAD_MULTIPLIER)) { EEPROM.write(z, byte(stagingTable.axisY[offset]/TABLE_LOAD_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + y++; + z++; + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case seqFuelPage: + /*--------------------------------------------------- + | Fuel trim tables (See storage.h for data layout) - Page 9 + | 6x6 tables itself + the 6 values along each of the axis + -----------------------------------------------------*/ + //Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1) + if(EEPROM.read(EEPROM_CONFIG8_XSIZE1) != trim1Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE1,trim1Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG8_YSIZE1) != trim1Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE1,trim1Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size + if(EEPROM.read(EEPROM_CONFIG8_XSIZE2) != trim2Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE2,trim2Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG8_YSIZE2) != trim2Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE2,trim2Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size + if(EEPROM.read(EEPROM_CONFIG8_XSIZE3) != trim3Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE3,trim3Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG8_YSIZE3) != trim3Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE3,trim3Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size + if(EEPROM.read(EEPROM_CONFIG8_XSIZE4) != trim4Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE4,trim4Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size + if(EEPROM.read(EEPROM_CONFIG8_YSIZE4) != trim4Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE4,trim4Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size + + y = EEPROM_CONFIG8_MAP2; //We do the 4 maps together in the same loop + z = EEPROM_CONFIG8_MAP3; //We do the 4 maps together in the same loop + i = EEPROM_CONFIG8_MAP4; //We do the 4 maps together in the same loop + + for(int x=EEPROM_CONFIG8_MAP1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG8_MAP1; + newVal = trim1Table.values[5-(offset/6)][offset%6]; + if (EEPROM.read(x) != newVal ) { EEPROM.update(x, newVal ); writeCounter++; } //Write the 6x6 map + + offset = y - EEPROM_CONFIG8_MAP2; + newVal = trim2Table.values[5-(offset/6)][offset%6]; + if (EEPROM.read(y) != newVal ) { EEPROM.update(y, newVal); writeCounter++; } //Write the 6x6 map + + offset = z - EEPROM_CONFIG8_MAP3; + newVal = trim3Table.values[5-(offset/6)][offset%6]; + if (EEPROM.read(z) != newVal ) { EEPROM.update(z, newVal); writeCounter++; } //Write the 6x6 map + + offset = i - EEPROM_CONFIG8_MAP4; + newVal = trim4Table.values[5-(offset/6)][offset%6]; + if (EEPROM.read(i) != newVal ) { EEPROM.update(i, newVal); writeCounter++; } //Write the 6x6 map + + y++; + z++; + i++; + } + //RPM bins + y = EEPROM_CONFIG8_XBINS2; + z = EEPROM_CONFIG8_XBINS3; + i = EEPROM_CONFIG8_XBINS4; + for(int x=EEPROM_CONFIG8_XBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG8_XBINS1; + EEPROM.update(x, byte(trim1Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + offset = y - EEPROM_CONFIG8_XBINS2; + EEPROM.update(y, byte(trim2Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + offset = z - EEPROM_CONFIG8_XBINS3; + EEPROM.update(z, byte(trim3Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + offset = i - EEPROM_CONFIG8_XBINS4; + EEPROM.update(i, byte(trim4Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + y++; + z++; + i++; + } + //TPS/MAP bins + y=EEPROM_CONFIG8_YBINS2; + z=EEPROM_CONFIG8_YBINS3; + i=EEPROM_CONFIG8_YBINS4; + for(int x=EEPROM_CONFIG8_YBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG8_YBINS1; + EEPROM.update(x, trim1Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + offset = y - EEPROM_CONFIG8_YBINS2; + EEPROM.update(y, trim2Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + offset = z - EEPROM_CONFIG8_YBINS3; + EEPROM.update(z, trim3Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + offset = i - EEPROM_CONFIG8_YBINS4; + EEPROM.update(i, trim4Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + y++; + z++; + i++; + } + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case canbusPage: + /*--------------------------------------------------- + | Config page 10 (See storage.h for data layout) + | 192 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage9; //Create a pointer to Page 10 in memory + for(int x=EEPROM_CONFIG9_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG9_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG9_START))); writeCounter++; } + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case warmupPage: + /*--------------------------------------------------- + | Config page 11 (See storage.h for data layout) + | 192 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage10; //Create a pointer to Page 11 in memory + //As there are no 3d tables in this page, all 192 bytes can simply be read in + for(int x=EEPROM_CONFIG10_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))); writeCounter++; } + } + + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + + break; + + case fuelMap2Page: + /*--------------------------------------------------- + | Fuel table (See storage.h for data layout) - Page 1 + | 16x16 table itself + the 16 values along each of the axis + -----------------------------------------------------*/ + EEPROM.update(EEPROM_CONFIG11_XSIZE, fuelTable2.xSize); writeCounter++; //Write the VE Tables RPM dimension size + EEPROM.update(EEPROM_CONFIG11_YSIZE, fuelTable2.ySize); writeCounter++; //Write the VE Tables MAP/TPS dimension size + for(int x=EEPROM_CONFIG11_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG11_MAP; + if( EEPROM.read(x) != (fuelTable2.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable2.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map + } + + //RPM bins + for(int x=EEPROM_CONFIG11_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG11_XBINS; + if( EEPROM.read(x) != (byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG11_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG11_YBINS; + EEPROM.update(x, fuelTable2.axisY[offset] / TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + } + if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } + else { eepromWritesPending = false; } + break; + //That concludes the writing of the 2nd fuel table + + default: + break; + } + +} + +void loadConfig() +{ + + int offset; + //Create a pointer to the config page + byte* pnt_configPage; + + + //Fuel table (See storage.h for data layout) + for(int x=EEPROM_CONFIG1_MAP; x Four = Least significant byte + byte four = (crc32_val & 0xFF); + byte three = ((crc32_val >> 8) & 0xFF); + byte two = ((crc32_val >> 16) & 0xFF); + byte one = ((crc32_val >> 24) & 0xFF); + + //Write the 4 bytes into the eeprom memory. + EEPROM.update(address, four); + EEPROM.update(address + 1, three); + EEPROM.update(address + 2, two); + EEPROM.update(address + 3, one); +} + +/* +Retrieves and returns the 4 byte CRC32 for a given page from EEPROM +*/ +uint32_t readPageCRC32(byte pageNo) +{ + uint16_t address; //Start address for the relevant page + address = EEPROM_PAGE_CRC32 + ((NUM_PAGES - pageNo) * 4); + + //Read the 4 bytes from the eeprom memory. + uint32_t four = EEPROM.read(address); + uint32_t three = EEPROM.read(address + 1); + uint32_t two = EEPROM.read(address + 2); + uint32_t one = EEPROM.read(address + 3); + + //Return the recomposed long by using bitshift. + return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF); +} + +// Utility functions. +// By having these in this file, it prevents other files from calling EEPROM functions directly. This is useful due to differences in the EEPROM libraries on different devces +byte readLastBaro() { return EEPROM.read(EEPROM_LAST_BARO); } +void storeLastBaro(byte newValue) { EEPROM.update(EEPROM_LAST_BARO, newValue); } +void storeCalibrationValue(uint16_t location, byte value) { EEPROM.update(location, value); } //This is essentially just an abstraction for EEPROM.update() +byte readEEPROMVersion() { return EEPROM.read(EEPROM_DATA_VERSION); } +void storeEEPROMVersion(byte newVersion) { EEPROM.update(EEPROM_DATA_VERSION, newVersion); } + + +void NewWriteConfig(byte tableNum) { /* We only ever write to the EEPROM where the new value is different from the currently stored byte @@ -424,326 +1151,4 @@ void writeConfig(byte tableNum) break; } -} - -void loadConfig() -{ - int offset; - //Create a pointer to the config page - byte* pnt_configPage; - - - //Fuel table (See storage.h for data layout) - for(int x=EEPROM_CONFIG1_MAP; x Four = Least significant byte - byte four = (crc32_val & 0xFF); - byte three = ((crc32_val >> 8) & 0xFF); - byte two = ((crc32_val >> 16) & 0xFF); - byte one = ((crc32_val >> 24) & 0xFF); - - //Write the 4 bytes into the eeprom memory. - EEPROM.update(address, four); - EEPROM.update(address + 1, three); - EEPROM.update(address + 2, two); - EEPROM.update(address + 3, one); -} - -/* -Retrieves and returns the 4 byte CRC32 for a given page from EEPROM -*/ -uint32_t readPageCRC32(byte pageNo) -{ - uint16_t address; //Start address for the relevant page - address = EEPROM_PAGE_CRC32 + ((NUM_PAGES - pageNo) * 4); - - //Read the 4 bytes from the eeprom memory. - uint32_t four = EEPROM.read(address); - uint32_t three = EEPROM.read(address + 1); - uint32_t two = EEPROM.read(address + 2); - uint32_t one = EEPROM.read(address + 3); - - //Return the recomposed long by using bitshift. - return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF); -} - -// Utility functions. -// By having these in this file, it prevents other files from calling EEPROM functions directly. This is useful due to differences in the EEPROM libraries on different devces -byte readLastBaro() { return EEPROM.read(EEPROM_LAST_BARO); } -void storeLastBaro(byte newValue) { EEPROM.update(EEPROM_LAST_BARO, newValue); } -void storeCalibrationValue(uint16_t location, byte value) { EEPROM.update(location, value); } //This is essentially just an abstraction for EEPROM.update() -byte readEEPROMVersion() { return EEPROM.read(EEPROM_DATA_VERSION); } -void storeEEPROMVersion(byte newVersion) { EEPROM.update(EEPROM_DATA_VERSION, newVersion); } +} \ No newline at end of file From e9ff7293c5dd7cc95c00b786ed6a0f64f89b9c68 Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Sun, 22 Sep 2019 13:35:31 +0200 Subject: [PATCH 04/11] Cleaned up debugging; Removed newConfig function; SPI flash clock much faster; --- speeduino/init.ino | 55 ++- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp | 189 +++------- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h | 47 ++- speeduino/src/SPIAsEEPROM/winbondflash.cpp | 22 +- speeduino/storage.ino | 397 --------------------- 5 files changed, 135 insertions(+), 575 deletions(-) diff --git a/speeduino/init.ino b/speeduino/init.ino index 5576ec3f..0d72aeb1 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -21,7 +21,6 @@ void initialiseAll() pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); startstorage(); - table3D_setSize(&fuelTable, 16); table3D_setSize(&fuelTable2, 16); table3D_setSize(&ignitionTable, 16); @@ -33,6 +32,7 @@ void initialiseAll() table3D_setSize(&trim2Table, 6); table3D_setSize(&trim3Table, 6); table3D_setSize(&trim4Table, 6); + loadConfig(); doUpdates(); //Check if any data items need updating (Occurs with firmware updates) @@ -1021,7 +1021,7 @@ void setPinMapping(byte boardID) pinCoil3 = 30; pinO2 = A22; #elif defined(STM32F4) - //Pin definitions for experimental board Tjeerd + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 //****************************************** @@ -1033,7 +1033,7 @@ void setPinMapping(byte boardID) pinIAT = PA3; //ADC123 pinCLT = PA4; //ADC12 pinO2 = PA5; //ADC12 - pinFan = PA6; //ADC12 LED_BUILTIN_1 + // = PA6; //ADC12 LED_BUILTIN_1 pinFuelPump = PA7; //ADC12 LED_BUILTIN_2 pinIdle1 = PA8; // // = PA9 //TXD1 @@ -1097,7 +1097,7 @@ void setPinMapping(byte boardID) pinCoil3 = PD7; // pinCoil4 = PD8; // pinCoil5 = PD9;// - // = PD10; // + pinFan = PD10; // // = PD11; // // = PD12; // // = PD13; // @@ -1632,7 +1632,7 @@ void setPinMapping(byte boardID) #if defined(STM32F4) case 60: - //Pin definitions for experimental board Tjeerd + //Pin definitions for experimental board Tjeerd //Black F407VE wiki.stm32duino.com/index.php?title=STM32F407 //****************************************** @@ -1644,7 +1644,7 @@ void setPinMapping(byte boardID) pinIAT = PA3; //ADC123 pinCLT = PA4; //ADC12 pinO2 = PA5; //ADC12 - pinFan = PA6; //ADC12 LED_BUILTIN_1 + // = PA6; //ADC12 LED_BUILTIN_1 pinFuelPump = PA7; //ADC12 LED_BUILTIN_2 pinIdle1 = PA8; // // = PA9 //TXD1 @@ -1708,7 +1708,7 @@ void setPinMapping(byte boardID) pinCoil3 = PD7; // pinCoil4 = PD8; // pinCoil5 = PD9;// - // = PD10; // + pinFan = PD10; // // = PD11; // // = PD12; // // = PD13; // @@ -1734,10 +1734,45 @@ void setPinMapping(byte boardID) pinTrigger2 = PE13; // // = PE14; // // = PE15; // - - break; + + #elif defined(CORE_STM32) + //blue pill wiki.stm32duino.com/index.php?title=Blue_Pill + //Maple mini wiki.stm32duino.com/index.php?title=Maple_Mini + //pins PA12, PA11 are used for USB or CAN couldn't be used for GPIO + pinInjector1 = PB7; //Output pin injector 1 is on + pinInjector2 = PB6; //Output pin injector 2 is on + pinInjector3 = PB5; //Output pin injector 3 is on + pinInjector4 = PB4; //Output pin injector 4 is on + pinCoil1 = PB3; //Pin for coil 1 + pinCoil2 = PA15; //Pin for coil 2 + pinCoil3 = PA14; //Pin for coil 3 + pinCoil4 = PA9; //Pin for coil 4 + pinCoil5 = PA8; //Pin for coil 5 + pinTPS = A0; //TPS input pin + pinMAP = A1; //MAP sensor pin + pinIAT = A2; //IAT sensor pin + pinCLT = A3; //CLS sensor pin + pinO2 = A4; //O2 Sensor pin + pinBat = A5; //Battery reference voltage pin + pinBaro = pinMAP; + pinIdle1 = PB2; //Single wire idle control + pinIdle2 = PA2; //2 wire idle control + pinBoost = PA1; //Boost control + pinVVT_1 = PA0; //Default VVT output + pinStepperDir = PC15; //Direction pin for DRV8825 driver + pinStepperStep = PC14; //Step pin for DRV8825 driver + pinStepperEnable = PC13; //Enable pin for DRV8825 + pinDisplayReset = PB2; // OLED reset pin + pinFan = PB1; //Pin for the fan output + pinFuelPump = PB11; //Fuel pump output + pinTachOut = PB10; //Tacho output pin + //external interrupt enabled pins + pinFlex = PB8; // Flex sensor (Must be external interrupt enabled) + pinTrigger = PA10; //The CAS pin + pinTrigger2 = PA13; //The Cam Sensor pin + #endif - + break; default: #if defined(STM32F4) //Pin definitions for experimental board Tjeerd diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp index 1ed91055..f235318b 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp @@ -1,17 +1,36 @@ -/* -* This file implements a shim layer for the SPIMemory library (https://github.com/Marzogh/SPIMemory) to mimic a minimal -* subset of the standard Arduino EEPROM library -*/ -//Working example on BLACK_STM32F407VET6 with official stm32 core from ST +/* Speeduino SPIAsEEPROM Library v.1.0.0 + * Copyright (C) 2019 by Tjeerd Hoogendijk + * Created by Tjeerd Hoogendijk - 21/09/2019 + * + * This file is part of the Speeduino project. This library is for + * Winbond SPI flash memory modules. In its current form it enables reading + * and writing individual bytes as if it where an AVR EEPROM. It uses some + * wear leveling (256x). When the begin() fuction is called for the first time + * it will "format" the flash chip. + * !!!!THIS DISTROYS ANY EXISTING DATA ON THE SPI FLASH!!! + * + * 1245184 bytes used of the SPI flash resulting in 4228 bytes of usable EEPROM + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License v3.0 + * along with the Arduino SPIMemory Library. If not, see + * . + */ #if defined(CORE_STM32_OFFICIAL) && defined(SPIFLASH_AS_EEPROM) #include "SPIAsEEPROM.h" #include "SPI.h" -//winbondSPIFlash flash(SS1, &SPI); //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus - - SPIAsEEPROM::SPIAsEEPROM() { pinMode(PB0, OUTPUT); @@ -24,13 +43,6 @@ SPIAsEEPROM::SPIAsEEPROM() uint8_t SPIAsEEPROM::begin() { uint8_t SpiFlashAvialable = 0; SpiFlashAvialable = winbondSPIFlash.begin(_W25Q16,SPI,PB0); - - // winbondSPIFlash.WE(); - // winbondSPIFlash.eraseAll(); - // while(winbondSPIFlash.busy()); - - //Debugging - // if(val){Serial.println("OK");} uint8_t formatted = 0; if(SpiFlashAvialable){ //check for magic numbers @@ -39,10 +51,11 @@ SPIAsEEPROM::SPIAsEEPROM() for(uint16_t i=0; i< FLASHSIZEUSED/SECTORSIZE; i++ ){ winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); if(buf[0] != MAGICNUMBER1 | buf[1] != MAGICNUMBER2 | buf[2] != MAGICNUMBER3 ){ + //if one of the SECTORS has no magic numbers it is not formatted formatted = 0; } } - + //If not formatted format flash. This takes 10 seconds or more! if(!formatted){ formatFlashForUse(); } @@ -55,31 +68,25 @@ SPIAsEEPROM::SPIAsEEPROM() formatted = 0; } } - - // Serial.print("formatted"); - // Serial.println(formatted, DEC); } if(formatted & SpiFlashAvialable){return true;}else{return false;} } -int8_t SPIAsEEPROM::write(uint16_t addressEEPROM, uint8_t writeValue){ +int8_t SPIAsEEPROM::write(uint16_t addressEEPROM, uint8_t writeValue){ + uint8_t ByteBuf[1]; + + //Check if adress is in the EEPROM space if (addressEEPROM >= FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2)){addressEEPROM = FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2);} + + //read the current value uint8_t readValue = read(addressEEPROM); - - // Serial.print("readValue"); - // Serial.println(readValue, DEC); - // Serial.print("writeValue"); - // Serial.println(writeValue, DEC); - - //After reading the byte all global variables containing inforamtion about the address are set correctly. + //After reading the current byte all global variables containing inforamtion about the address are set correctly. //only write if value is changed. if (readValue != writeValue){ - //Check if buffer is full + //Check if buffer is full and an erase must be performed. if (nrOfOnes < 1){ - //Serial.println("A sector gets erased and hoppfully writen back"); - //now the buffer is full and an erase must be done //First read all the values in this sector that will get distroyed when erasing uint8_t tempBuf[14]; @@ -91,15 +98,12 @@ int8_t SPIAsEEPROM::write(uint16_t addressEEPROM, uint8_t writeValue){ writeMagicNumber(sectorNumber); //write all the values back - // Serial.println("Start re-writing values"); for(uint8_t i=0; i<14; i++){ write((sectorNumber*14) + i, tempBuf[i]); } - // Serial.println("End re-writing values"); + //also do not forget to write the new value! write(addressEEPROM, writeValue); - - // Serial.println("New value re-writing"); return 0; } @@ -107,60 +111,21 @@ int8_t SPIAsEEPROM::write(uint16_t addressEEPROM, uint8_t writeValue){ //determine the adress of the byte in the infoblock where one bit must be reset when writing new values uint8_t RelativeAdressInInfoBlock = (nrOfOnes - 1)/8; - // Serial.print("RelativeAdressInInfoBlock"); - // Serial.println(RelativeAdressInInfoBlock, DEC); - //determine value of the infoblock byte after writing one more time. uint8_t ValueInInfoBlock = 0xFF << (8 - (nrOfOnes - 1 - ((RelativeAdressInInfoBlock) * 8))); - // Serial.print("ValueInInfoBlock"); - // Serial.println(ValueInInfoBlock, DEC); - - uint8_t ByteBuf[1]; - - // Serial.print("dataFlashAddress"); - // Serial.println(dataFlashAddress, DEC); - - // Serial.print("sizeof(ByteBuf)"); - // Serial.println(sizeof(ByteBuf), DEC); - //write the new value at the new location ByteBuf[0] = writeValue; winbondSPIFlash.WE(); winbondSPIFlash.writePage(dataFlashAddress - 1, ByteBuf, sizeof(ByteBuf)); while(winbondSPIFlash.busy()); - // Serial.print("infoFlashAddress"); - // Serial.println(infoFlashAddress, DEC); - //write where read can find the new value ByteBuf[0] = ValueInInfoBlock; winbondSPIFlash.WE(); winbondSPIFlash.writePage(infoFlashAddress + RelativeAdressInInfoBlock, ByteBuf, sizeof(ByteBuf)); while(winbondSPIFlash.busy()); - //read the infoblock and put into the buffer - // uint8_t buf[256]; - // winbondSPIFlash.read(infoFlashAddress, buf, sizeof(buf) - 1); - // while(winbondSPIFlash.busy()); - - // Serial.print("Buffer: "); - // for (uint16_t i = 0; i=FLASHSIZEUSED/SECTORSIZE){ sectorNumber = (FLASHSIZEUSED/SECTORSIZE - 1); } - // Serial.print("Sector number to erase"); - // Serial.println(sectorNumber); + + //First erase the sector (4KiB at the time) winbondSPIFlash.WE(); winbondSPIFlash.eraseSector(sectorNumber*SECTORSIZE); - while(winbondSPIFlash.busy()); + while(winbondSPIFlash.busy()); //if no spi flash present or accessible this hangs forever! + + //Write the magic numbers at the start of the sector for identification. winbondSPIFlash.WE(); winbondSPIFlash.writePage(sectorNumber*SECTORSIZE, magicbuf, MAGICNUMBER_OFFSET); - while(winbondSPIFlash.busy()); - - // Serial.print("sizeof(magicbuf)"); - // Serial.println(sizeof(magicbuf), DEC); - - - // uint8_t buf[256]; - // winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); - // Serial.print("Buffer: "); - // for (uint16_t i = 0; i= FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2)){addressEEPROM = FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2);} - - // Serial.print("byte adress"); - // Serial.println(addressEEPROM, DEC); - uint8_t buf[INFOBYTES_PER_BYTE]; + if (addressEEPROM >= FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2)){addressEEPROM = FLASHSIZEUSED/SECTORSIZE * (SECTORSIZE/FLASH_PAGESIZE - 2);} //Check at what sector number the adress resides. 14 bytes per sector sectorNumber = addressEEPROM/(SECTORSIZE/FLASH_PAGESIZE - 2); - // Serial.print("sectorNumber"); - // Serial.println(sectorNumber, DEC); - //Check at what page number in the sector the adress can be found (16 pages per sector, 14 used) pageNumber = addressEEPROM - (sectorNumber * ((SECTORSIZE/FLASH_PAGESIZE) - 2)); - // Serial.print("pageNumber"); - // Serial.println(pageNumber, DEC); - //The absulute adress of the infoblock of the byte in flash adress infoFlashAddress = sectorNumber*SECTORSIZE + pageNumber * INFOBYTES_PER_BYTE + MAGICNUMBER_OFFSET; - //read the infoblock and put into the buffer + //read the infoblock and put into the buffer winbondSPIFlash.read(infoFlashAddress, buf, sizeof(buf)); - - // Serial.print("InfoblockBuffer: "); - // for (uint16_t i = 0; i. + */ + #ifndef SPI_AS_EEPROM_H #define SPI_AS_EEPROM_H #if defined(CORE_STM32_OFFICIAL) && defined(SPIFLASH_AS_EEPROM) -// //UGLY HACK TO PREVENT EEPROM LIBRARY BEING IMPORTED FIRST!! -// //Use with black_F407VE board -// #ifndef EEPROM_h -// #define EEPROM_h - - -#define FLASHSIZEUSED 1245184 //must be a multiple of sectorsize //1245184 = 4228 bytes of EEPROM +#define FLASHSIZEUSED 1757184 //must be a multiple of sectorsize //1757184 = 6006 bytes of EEPROM #define BYTESPERSECTOR 14 #define SECTORSIZE 4096 #define INFOBYTESSECTOROFFSET 512 @@ -28,8 +50,6 @@ #include #include "winbondflash.h" -// winbondFlashSPI winbondSPIFlash; - class SPIAsEEPROM { private: winbondFlashSPI winbondSPIFlash; @@ -53,8 +73,9 @@ class SPIAsEEPROM { int8_t update(uint16_t address, uint8_t val); }; -#endif -#endif -// #endif - extern SPIAsEEPROM EEPROM; + +#endif +#endif + + diff --git a/speeduino/src/SPIAsEEPROM/winbondflash.cpp b/speeduino/src/SPIAsEEPROM/winbondflash.cpp index c1fc58be..f16444b9 100644 --- a/speeduino/src/SPIAsEEPROM/winbondflash.cpp +++ b/speeduino/src/SPIAsEEPROM/winbondflash.cpp @@ -131,39 +131,25 @@ bool winbondFlashClass::checkPartNo(partNumber _partno) id |= transfer(0x00); deselect(); - //Serial1.print("MANUF=0x"); - //Serial1.print(manuf,HEX); - //Serial1.print(",ID=0x"); - //Serial1.print(id,HEX); - //Serial1.println(); - - //Serial1.print("MANUF=0x"); - //Serial1.println(WINBOND_MANUF,HEX); - if(manuf != WINBOND_MANUF){ - //Serial1.println("MANUF NOT OK"); return false; } if(_partno == custom) return true; - //Serial.println("Not a custom chip type"); if(_partno == autoDetect) { - //Serial1.print("Autodetect..."); for(int i=0;i3us - //Serial1.println("Chip Released"); - + if(!checkPartNo(_partno)) return false; else return true; } @@ -307,7 +291,7 @@ void winbondFlashClass::writePage(uint32_t addr_start,uint8_t *buf, uint16_t n) //do { // transfer(buf[i]); // i++; - //}while(i!=sizeof(buf)); + //}while(i!=0); deselect(); } @@ -371,7 +355,7 @@ bool winbondFlashSPI::begin(partNumber _partno,SPIClass &_spi,uint8_t _nss) // pinMode(MISO,INPUT_PULLUP); SPI.begin(); SPI.setBitOrder(MSBFIRST); - SPI.setClockDivider(SPI_CLOCK_DIV16); + SPI.setClockDivider(SPI_CLOCK_DIV2); SPI.setDataMode(SPI_MODE0); deselect(); // Serial.println("SPI OK"); diff --git a/speeduino/storage.ino b/speeduino/storage.ino index 98215b20..2f8f47bc 100644 --- a/speeduino/storage.ino +++ b/speeduino/storage.ino @@ -88,7 +88,6 @@ void writeConfig(byte tableNum) //That concludes the writing of the VE table case veSetPage: - EEPROM.read(0); /*--------------------------------------------------- | Config page 2 (See storage.h for data layout) | 64 byte long config table @@ -756,399 +755,3 @@ void storeLastBaro(byte newValue) { EEPROM.update(EEPROM_LAST_BARO, newValue); } void storeCalibrationValue(uint16_t location, byte value) { EEPROM.update(location, value); } //This is essentially just an abstraction for EEPROM.update() byte readEEPROMVersion() { return EEPROM.read(EEPROM_DATA_VERSION); } void storeEEPROMVersion(byte newVersion) { EEPROM.update(EEPROM_DATA_VERSION, newVersion); } - - -void NewWriteConfig(byte tableNum) -{ - /* - We only ever write to the EEPROM where the new value is different from the currently stored byte - This is due to the limited write life of the EEPROM (Approximately 100,000 writes) - */ - - int offset; - int i, z, y; - int writeCounter = 0; - byte newVal; //Used for tempoerarily storing the new intended value - //Create a pointer to the config page - byte* pnt_configPage; - - switch(tableNum) - { - case veMapPage: - /*--------------------------------------------------- - | Fuel table (See storage.h for data layout) - Page 1 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); writeCounter++; } //Write the VE Tables RPM dimension size - if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); writeCounter++; } //Write the VE Tables MAP/TPS dimension size - for(int x=EEPROM_CONFIG1_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG1_MAP; - if( EEPROM.read(x) != (fuelTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map - } - - //RPM bins - for(int x=EEPROM_CONFIG1_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG1_XBINS; - if( EEPROM.read(x) != (byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - } - //TPS/MAP bins - for(int x=EEPROM_CONFIG1_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG1_YBINS; - EEPROM.update(x, fuelTable.axisY[offset] / TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - } - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - break; - //That concludes the writing of the VE table - - case veSetPage: - /*--------------------------------------------------- - | Config page 2 (See storage.h for data layout) - | 64 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory - for(int x=EEPROM_CONFIG2_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))); writeCounter++; } - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case ignMapPage: - /*--------------------------------------------------- - | Ignition table (See storage.h for data layout) - Page 1 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the Ignition table, basically the same thing as above - if(EEPROM.read(EEPROM_CONFIG3_XSIZE) != ignitionTable.xSize) { EEPROM.write(EEPROM_CONFIG3_XSIZE,ignitionTable.xSize); writeCounter++; } //Write the ignition Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG3_YSIZE) != ignitionTable.ySize) { EEPROM.write(EEPROM_CONFIG3_YSIZE,ignitionTable.ySize); writeCounter++; } //Write the ignition Table MAP/TPS dimension size - - for(int x=EEPROM_CONFIG3_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG3_MAP; - newVal = ignitionTable.values[15-(offset/16)][offset%16]; - if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //Write the 16x16 map with translation - } - //RPM bins - for(int x=EEPROM_CONFIG3_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG3_XBINS; - newVal = ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER; - if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - } - //TPS/MAP bins - for(int x=EEPROM_CONFIG3_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG3_YBINS; - newVal = ignitionTable.axisY[offset]/TABLE_LOAD_MULTIPLIER; - if(EEPROM.read(x) != newVal) { EEPROM.write(x, newVal); writeCounter++; } //Table load is divided by 2 (Allows for MAP up to 511) - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case ignSetPage: - /*--------------------------------------------------- - | Config page 2 (See storage.h for data layout) - | 64 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 2 in memory - for(int x=EEPROM_CONFIG4_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))); writeCounter++; } - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case afrMapPage: - /*--------------------------------------------------- - | AFR table (See storage.h for data layout) - Page 5 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the Ignition table, basically the same thing as above - if(EEPROM.read(EEPROM_CONFIG5_XSIZE) != afrTable.xSize) { EEPROM.write(EEPROM_CONFIG5_XSIZE,afrTable.xSize); writeCounter++; } //Write the ignition Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG5_YSIZE) != afrTable.ySize) { EEPROM.write(EEPROM_CONFIG5_YSIZE,afrTable.ySize); writeCounter++; } //Write the ignition Table MAP/TPS dimension size - - for(int x=EEPROM_CONFIG5_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG5_MAP; - if(EEPROM.read(x) != (afrTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, afrTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map - } - //RPM bins - for(int x=EEPROM_CONFIG5_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG5_XBINS; - if(EEPROM.read(x) != byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - } - //TPS/MAP bins - for(int x=EEPROM_CONFIG5_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG5_YBINS; - EEPROM.update(x, afrTable.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case afrSetPage: - /*--------------------------------------------------- - | Config page 3 (See storage.h for data layout) - | 64 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage6; //Create a pointer to Page 3 in memory - for(int x=EEPROM_CONFIG6_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))); writeCounter++; } - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case boostvvtPage: - /*--------------------------------------------------- - | Boost and vvt tables (See storage.h for data layout) - Page 8 - | 8x8 table itself + the 8 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1) - if(EEPROM.read(EEPROM_CONFIG7_XSIZE1) != boostTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE1,boostTable.xSize); writeCounter++; } //Write the boost Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG7_YSIZE1) != boostTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE1,boostTable.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size - if(EEPROM.read(EEPROM_CONFIG7_XSIZE2) != vvtTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE2,vvtTable.xSize); writeCounter++; } //Write the vvt Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG7_YSIZE2) != vvtTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE2,vvtTable.ySize); writeCounter++; } //Write the vvt Table MAP/TPS dimension size - if(EEPROM.read(EEPROM_CONFIG7_XSIZE3) != stagingTable.xSize) { EEPROM.write(EEPROM_CONFIG7_XSIZE3,stagingTable.xSize); writeCounter++; } //Write the staging Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG7_YSIZE3) != stagingTable.ySize) { EEPROM.write(EEPROM_CONFIG7_YSIZE3,stagingTable.ySize); writeCounter++; } //Write the staging Table MAP/TPS dimension size - - y = EEPROM_CONFIG7_MAP2; //We do the 3 maps together in the same loop - z = EEPROM_CONFIG7_MAP3; - for(int x=EEPROM_CONFIG7_MAP1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG7_MAP1; - if(EEPROM.read(x) != (boostTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(x, boostTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map - offset = y - EEPROM_CONFIG7_MAP2; - if(EEPROM.read(y) != (vvtTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(y, vvtTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map - offset = z - EEPROM_CONFIG7_MAP3; - if(EEPROM.read(z) != (stagingTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(z, stagingTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map - y++; - z++; - } - //RPM bins - y = EEPROM_CONFIG7_XBINS2; - z = EEPROM_CONFIG7_XBINS3; - for(int x=EEPROM_CONFIG7_XBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG7_XBINS1; - if(EEPROM.read(x) != byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - offset = y - EEPROM_CONFIG7_XBINS2; - if(EEPROM.read(y) != byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(y, byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - offset = z - EEPROM_CONFIG7_XBINS3; - if(EEPROM.read(z) != byte(stagingTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(z, byte(stagingTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - y++; - z++; - } - //TPS/MAP bins - y=EEPROM_CONFIG7_YBINS2; - z=EEPROM_CONFIG7_YBINS3; - for(int x=EEPROM_CONFIG7_YBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG7_YBINS1; - if(EEPROM.read(x) != boostTable.axisY[offset]) { EEPROM.write(x, boostTable.axisY[offset]); writeCounter++; } //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100) - offset = y - EEPROM_CONFIG7_YBINS2; - if(EEPROM.read(y) != vvtTable.axisY[offset]) { EEPROM.write(y, vvtTable.axisY[offset]); writeCounter++; } //TABLE_LOAD_MULTIPLIER is NOT used for VVT as it is TPS based (0-100) - offset = z - EEPROM_CONFIG7_YBINS3; - if(EEPROM.read(z) != byte(stagingTable.axisY[offset]/TABLE_LOAD_MULTIPLIER)) { EEPROM.write(z, byte(stagingTable.axisY[offset]/TABLE_LOAD_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - y++; - z++; - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case seqFuelPage: - /*--------------------------------------------------- - | Fuel trim tables (See storage.h for data layout) - Page 9 - | 6x6 tables itself + the 6 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1) - if(EEPROM.read(EEPROM_CONFIG8_XSIZE1) != trim1Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE1,trim1Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG8_YSIZE1) != trim1Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE1,trim1Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size - if(EEPROM.read(EEPROM_CONFIG8_XSIZE2) != trim2Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE2,trim2Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG8_YSIZE2) != trim2Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE2,trim2Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size - if(EEPROM.read(EEPROM_CONFIG8_XSIZE3) != trim3Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE3,trim3Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG8_YSIZE3) != trim3Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE3,trim3Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size - if(EEPROM.read(EEPROM_CONFIG8_XSIZE4) != trim4Table.xSize) { EEPROM.write(EEPROM_CONFIG8_XSIZE4,trim4Table.xSize); writeCounter++; } //Write the boost Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG8_YSIZE4) != trim4Table.ySize) { EEPROM.write(EEPROM_CONFIG8_YSIZE4,trim4Table.ySize); writeCounter++; } //Write the boost Table MAP/TPS dimension size - - y = EEPROM_CONFIG8_MAP2; //We do the 4 maps together in the same loop - z = EEPROM_CONFIG8_MAP3; //We do the 4 maps together in the same loop - i = EEPROM_CONFIG8_MAP4; //We do the 4 maps together in the same loop - - for(int x=EEPROM_CONFIG8_MAP1; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG8_MAP1; - newVal = trim1Table.values[5-(offset/6)][offset%6]; - if (EEPROM.read(x) != newVal ) { EEPROM.update(x, newVal ); writeCounter++; } //Write the 6x6 map - - offset = y - EEPROM_CONFIG8_MAP2; - newVal = trim2Table.values[5-(offset/6)][offset%6]; - if (EEPROM.read(y) != newVal ) { EEPROM.update(y, newVal); writeCounter++; } //Write the 6x6 map - - offset = z - EEPROM_CONFIG8_MAP3; - newVal = trim3Table.values[5-(offset/6)][offset%6]; - if (EEPROM.read(z) != newVal ) { EEPROM.update(z, newVal); writeCounter++; } //Write the 6x6 map - - offset = i - EEPROM_CONFIG8_MAP4; - newVal = trim4Table.values[5-(offset/6)][offset%6]; - if (EEPROM.read(i) != newVal ) { EEPROM.update(i, newVal); writeCounter++; } //Write the 6x6 map - - y++; - z++; - i++; - } - //RPM bins - y = EEPROM_CONFIG8_XBINS2; - z = EEPROM_CONFIG8_XBINS3; - i = EEPROM_CONFIG8_XBINS4; - for(int x=EEPROM_CONFIG8_XBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG8_XBINS1; - EEPROM.update(x, byte(trim1Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte - offset = y - EEPROM_CONFIG8_XBINS2; - EEPROM.update(y, byte(trim2Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte - offset = z - EEPROM_CONFIG8_XBINS3; - EEPROM.update(z, byte(trim3Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte - offset = i - EEPROM_CONFIG8_XBINS4; - EEPROM.update(i, byte(trim4Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte - y++; - z++; - i++; - } - //TPS/MAP bins - y=EEPROM_CONFIG8_YBINS2; - z=EEPROM_CONFIG8_YBINS3; - i=EEPROM_CONFIG8_YBINS4; - for(int x=EEPROM_CONFIG8_YBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG8_YBINS1; - EEPROM.update(x, trim1Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - offset = y - EEPROM_CONFIG8_YBINS2; - EEPROM.update(y, trim2Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - offset = z - EEPROM_CONFIG8_YBINS3; - EEPROM.update(z, trim3Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - offset = i - EEPROM_CONFIG8_YBINS4; - EEPROM.update(i, trim4Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - y++; - z++; - i++; - } - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case canbusPage: - /*--------------------------------------------------- - | Config page 10 (See storage.h for data layout) - | 192 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage9; //Create a pointer to Page 10 in memory - for(int x=EEPROM_CONFIG9_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG9_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG9_START))); writeCounter++; } - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case warmupPage: - /*--------------------------------------------------- - | Config page 11 (See storage.h for data layout) - | 192 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage10; //Create a pointer to Page 11 in memory - //As there are no 3d tables in this page, all 192 bytes can simply be read in - for(int x=EEPROM_CONFIG10_START; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))); writeCounter++; } - } - - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - - break; - - case fuelMap2Page: - /*--------------------------------------------------- - | Fuel table (See storage.h for data layout) - Page 1 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - EEPROM.update(EEPROM_CONFIG11_XSIZE, fuelTable2.xSize); writeCounter++; //Write the VE Tables RPM dimension size - EEPROM.update(EEPROM_CONFIG11_YSIZE, fuelTable2.ySize); writeCounter++; //Write the VE Tables MAP/TPS dimension size - for(int x=EEPROM_CONFIG11_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG11_MAP; - if( EEPROM.read(x) != (fuelTable2.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable2.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map - } - - //RPM bins - for(int x=EEPROM_CONFIG11_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG11_XBINS; - if( EEPROM.read(x) != (byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable2.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte - } - //TPS/MAP bins - for(int x=EEPROM_CONFIG11_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. - offset = x - EEPROM_CONFIG11_YBINS; - EEPROM.update(x, fuelTable2.axisY[offset] / TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) - } - if(writeCounter > EEPROM_MAX_WRITE_BLOCK) { eepromWritesPending = true; } - else { eepromWritesPending = false; } - break; - //That concludes the writing of the 2nd fuel table - - default: - break; - } - -} \ No newline at end of file From caa1c676f378c8c7407d321767b22ba7c158d21c Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Sun, 22 Sep 2019 19:31:23 +0200 Subject: [PATCH 05/11] Made platformio work with usb serial --- platformio.ini | 4 ++-- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp | 2 +- speeduino/src/SPIAsEEPROM/winbondflash.cpp | 2 +- speeduino/utils.h | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 934fe817..994f6b4c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -58,10 +58,10 @@ platform = ststm32 framework = arduino ;board = genericSTM32F407VET6 board = black_f407ve -lib_deps = EEPROM +;lib_deps = EEPROM board_build.core = stm32 ;build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DCORE_STM32_OFFICIAL -DSRAM_AS_EEPROM -build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DCORE_STM32_OFFICIAL -DSPI_AS_EEPROM -DMENU_USB_SERIAL +build_flags = -fpermissive -std=gnu++11 -UBOARD_NR_GPIO_PINS -DCORE_STM32_OFFICIAL -DSPIFLASH_AS_EEPROM -DUSBCON -DUSBD_VID=0x0483 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"BLACK_F407VE\"" -DHAL_PCD_MODULE_ENABLED -DUSBD_USE_CDC -DHAL_UART_MODULE_ENABLED upload_protocol = serial [env:bluepill_f103c8] diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp index f235318b..0fde6c0a 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp @@ -8,7 +8,7 @@ * wear leveling (256x). When the begin() fuction is called for the first time * it will "format" the flash chip. * !!!!THIS DISTROYS ANY EXISTING DATA ON THE SPI FLASH!!! - * + * * 1245184 bytes used of the SPI flash resulting in 4228 bytes of usable EEPROM * * This Library is free software: you can redistribute it and/or modify diff --git a/speeduino/src/SPIAsEEPROM/winbondflash.cpp b/speeduino/src/SPIAsEEPROM/winbondflash.cpp index f16444b9..fd1c5bfa 100644 --- a/speeduino/src/SPIAsEEPROM/winbondflash.cpp +++ b/speeduino/src/SPIAsEEPROM/winbondflash.cpp @@ -46,7 +46,7 @@ typedef struct { winbondFlashClass::partNumber pn; uint16_t id; uint32_t bytes; - uint16_t pages; + uint32_t pages; uint16_t sectors; uint16_t blocks; }pnListType; diff --git a/speeduino/utils.h b/speeduino/utils.h index 34cde4a6..56f737f6 100644 --- a/speeduino/utils.h +++ b/speeduino/utils.h @@ -6,6 +6,7 @@ These are some utility functions and variables used through the main code #include +#define CONCATS(s1, s2) (s1" " s2) //needed for some reason. not defined correctly because of utils.h file of speeduino (same name as one in arduino core) void setResetControlPinState(); byte pinTranslate(byte); uint32_t calculateCRC32(byte); From 05a2414d9f93b99f4916c85607d910c1b5bcab4c Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Tue, 24 Sep 2019 00:01:21 +0200 Subject: [PATCH 06/11] Ugly Hack to get rid of the startstorage() function. --- speeduino/init.ino | 1 - speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp | 6 +++++- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h | 1 + speeduino/storage.ino | 6 ------ 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/speeduino/init.ino b/speeduino/init.ino index 0d72aeb1..633f662e 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -20,7 +20,6 @@ void initialiseAll() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); - startstorage(); table3D_setSize(&fuelTable, 16); table3D_setSize(&fuelTable2, 16); table3D_setSize(&ignitionTable, 16); diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp index 0fde6c0a..96012e84 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp @@ -41,7 +41,7 @@ SPIAsEEPROM::SPIAsEEPROM() } uint8_t SPIAsEEPROM::begin() { - uint8_t SpiFlashAvialable = 0; + SpiFlashAvialable = winbondSPIFlash.begin(_W25Q16,SPI,PB0); uint8_t formatted = 0; if(SpiFlashAvialable){ @@ -174,6 +174,10 @@ uint8_t SPIAsEEPROM::read(uint16_t addressEEPROM){ //The first two pages will be used for the infoblock //The first 4 bytes of each page must have the magic number //version 0.1 does not check magic number + if(!SpiFlashAvialable){ + begin(); + } + uint8_t buf[INFOBYTES_PER_BYTE]; diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h index 7cb90a33..62dc1337 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.h @@ -53,6 +53,7 @@ class SPIAsEEPROM { private: winbondFlashSPI winbondSPIFlash; + uint8_t SpiFlashAvialable = 0; uint8_t ReadOutBuffer[BYTESPERSECTOR]; uint8_t magicbuf[4]; uint16_t sectorNumber; diff --git a/speeduino/storage.ino b/speeduino/storage.ino index 2f8f47bc..b81ac23d 100644 --- a/speeduino/storage.ino +++ b/speeduino/storage.ino @@ -11,12 +11,6 @@ A full copy of the license may be found in the projects root directory #include EEPROM_LIB_H //This is defined in the board .h files #include "storage.h" -void startstorage(){ - #if defined(SPIFLASH_AS_EEPROM) - EEPROM.begin(); - #endif -} - void writeAllConfig() { writeConfig(veSetPage); From f3c01cbdda3bf62525efc8ba58c76ed7255f936c Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Tue, 24 Sep 2019 00:04:29 +0200 Subject: [PATCH 07/11] Removed debug line --- speeduino/storage.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/speeduino/storage.ino b/speeduino/storage.ino index b81ac23d..b39350d5 100644 --- a/speeduino/storage.ino +++ b/speeduino/storage.ino @@ -33,7 +33,6 @@ and writes them to EEPROM as per the layout defined in storage.h */ void writeConfig(byte tableNum) { - // EEPROM.begin(); /* We only ever write to the EEPROM where the new value is different from the currently stored byte This is due to the limited write life of the EEPROM (Approximately 100,000 writes) From 7a957fe121ca60673cd05a06a9879dc9e552f520 Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Tue, 24 Sep 2019 19:37:34 +0200 Subject: [PATCH 08/11] Cleaned more warning during compile --- speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp | 6 +++--- speeduino/src/SPIAsEEPROM/winbondflash.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp index 96012e84..4a7a9faf 100644 --- a/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp +++ b/speeduino/src/SPIAsEEPROM/SPIAsEEPROM.cpp @@ -50,7 +50,7 @@ SPIAsEEPROM::SPIAsEEPROM() uint8_t buf[MAGICNUMBER_OFFSET]; for(uint16_t i=0; i< FLASHSIZEUSED/SECTORSIZE; i++ ){ winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); - if(buf[0] != MAGICNUMBER1 | buf[1] != MAGICNUMBER2 | buf[2] != MAGICNUMBER3 ){ + if((buf[0] != MAGICNUMBER1) | (buf[1] != MAGICNUMBER2) | (buf[2] != MAGICNUMBER3)){ //if one of the SECTORS has no magic numbers it is not formatted formatted = 0; } @@ -64,7 +64,7 @@ SPIAsEEPROM::SPIAsEEPROM() formatted = 1; for(uint16_t i=0; i< FLASHSIZEUSED/SECTORSIZE; i++ ){ winbondSPIFlash.read(sectorNumber*SECTORSIZE, buf, sizeof(buf) - 1); - if(buf[0] != MAGICNUMBER1 | buf[1] != MAGICNUMBER2 | buf[2] != MAGICNUMBER3 ){ + if((buf[0] != MAGICNUMBER1) | (buf[1] != MAGICNUMBER2) | (buf[2] != MAGICNUMBER3)){ formatted = 0; } } @@ -218,7 +218,7 @@ uint16_t SPIAsEEPROM::count(uint8_t buf[FLASH_PAGESIZE/BITS_PER_BYTE]){ uint16_t count=0; for(uint8_t j=0; j < 32; j++) for(uint8_t i=0; i<8; i++){ - if(buf[j] & 1 == 1){ //if current bit 1 + if((buf[j] & 1) == 1){ //if current bit 1 count++;//increase count } buf[j]=buf[j]>>1;//right shift diff --git a/speeduino/src/SPIAsEEPROM/winbondflash.cpp b/speeduino/src/SPIAsEEPROM/winbondflash.cpp index fd1c5bfa..ebc13a3d 100644 --- a/speeduino/src/SPIAsEEPROM/winbondflash.cpp +++ b/speeduino/src/SPIAsEEPROM/winbondflash.cpp @@ -140,7 +140,7 @@ bool winbondFlashClass::checkPartNo(partNumber _partno) if(_partno == autoDetect) { - for(int i=0;i Date: Wed, 25 Sep 2019 20:14:00 +0200 Subject: [PATCH 09/11] Added STM32F407VET6 to speeduino.ini --- reference/speeduino.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 61deceea..82bda694 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -213,7 +213,7 @@ page = 1 unused1-3c = bits, U08, 3, [2:7], "MAP", "TPS", "INVALID", "INVALID" wueRates = array, U08, 4, [10], "%", 1.0, 0.0, 0.0, 255, 0 crankingPct = scalar, U08, 14, "%", 1.0, 0.0, 0.0, 255, 0 - pinLayout = bits, U08, 15, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "01-05 MX5 PNP", "INVALID", "96-97 MX5 PNP", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NO2C", "UA4C", "INVALID", "INVALID", "INVALID", "DIY-EFI CORE4 v1.0", "INVALID", "INVALID", "INVALID", "INVALID", "dvjcodec Teensy RevA", "dvjcodec Teensy RevB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" + pinLayout = bits, U08, 15, [0:7], "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "01-05 MX5 PNP", "INVALID", "96-97 MX5 PNP", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NO2C", "UA4C", "INVALID", "INVALID", "INVALID", "DIY-EFI CORE4 v1.0", "INVALID", "INVALID", "INVALID", "INVALID", "dvjcodec Teensy RevA", "dvjcodec Teensy RevB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Black STM32F407VET6 V0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" tachoPin = bits, U08, 16, [0:5], "Board Default", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" tachoDiv = bits, U08, 16, [6:7], "Normal", "Half", "INVALID", "INVALID" tachoDuration = scalar, U08, 17, "ms", 1.0, 0.0, 1.0, 6.0, 0 From a44cacc9d4e5b73ec31756a2bd8e0ccaba380e47 Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Mon, 30 Sep 2019 21:13:09 +0200 Subject: [PATCH 10/11] fix STM32F407 comilation wuth new stm32duino 1.7.0 --- speeduino/board_stm32_official.h | 29 +++- speeduino/board_stm32_official.ino | 227 ++++++++++++++--------------- 2 files changed, 135 insertions(+), 121 deletions(-) diff --git a/speeduino/board_stm32_official.h b/speeduino/board_stm32_official.h index dd74654e..7c481d50 100644 --- a/speeduino/board_stm32_official.h +++ b/speeduino/board_stm32_official.h @@ -2,8 +2,9 @@ #define STM32F407VE_H #if defined(CORE_STM32_OFFICIAL) #include -#include -#include "stm32f4xx_ll_tim.h" +#include +#include +#include "stm32f1xx_ll_tim.h" /* *********************************************************************************************************** * General @@ -28,10 +29,10 @@ #define USE_SERIAL3 void initBoard(); uint16_t freeRam(); -extern void oneMSIntervalIRQ(stimer_t *Timer); -extern void EmptyIRQCallback(stimer_t *Timer, uint32_t channel); extern "C" char* sbrk(int incr); + + /* *********************************************************************************************************** * Schedules @@ -154,6 +155,26 @@ extern "C" char* sbrk(int incr); * Timers */ +HardwareTimer Timer1(TIM1); +HardwareTimer Timer2(TIM2); +HardwareTimer Timer3(TIM3); +HardwareTimer Timer4(TIM4); +HardwareTimer Timer5(TIM5); +HardwareTimer Timer8(TIM8); + +void oneMSInterval(HardwareTimer*); +void boostInterrupt(HardwareTimer*); +void fuelSchedule1Interrupt(HardwareTimer*); +void fuelSchedule2Interrupt(HardwareTimer*); +void fuelSchedule3Interrupt(HardwareTimer*); +void fuelSchedule4Interrupt(HardwareTimer*); +void idleInterrupt(HardwareTimer*); +void vvtInterrupt(HardwareTimer*); +void ignitionSchedule1Interrupt(HardwareTimer*); +void ignitionSchedule2Interrupt(HardwareTimer*); +void ignitionSchedule3Interrupt(HardwareTimer*); +void ignitionSchedule4Interrupt(HardwareTimer*); +void ignitionSchedule5Interrupt(HardwareTimer*); /* *********************************************************************************************************** diff --git a/speeduino/board_stm32_official.ino b/speeduino/board_stm32_official.ino index 95b41348..9f2b7df3 100644 --- a/speeduino/board_stm32_official.ino +++ b/speeduino/board_stm32_official.ino @@ -4,56 +4,21 @@ #include "auxiliaries.h" #include "idle.h" #include "scheduler.h" -#include +#include "HardwareTimer.h" + -#if defined(STM32F4) - #define NR_OFF_TIMERS 9 - //stimer_t HardwareTimers[NR_OFF_TIMERS + 1]; - stimer_t HardwareTimers_1; - stimer_t HardwareTimers_2; - stimer_t HardwareTimers_3; - stimer_t HardwareTimers_4; - stimer_t HardwareTimers_5; - stimer_t HardwareTimers_8; - //These should really be in the stm32GENERIC libs, but for somereason they only have timers 1-4 - // #include - // #include "src/HardwareTimers/HardwareTimer.h" - // HardwareTimer Timer5(TIM5, chip_tim5, sizeof(chip_tim5) / sizeof(chip_tim5[0])); - // HardwareTimer Timer8(TIM8, chip_tim8, sizeof(chip_tim8) / sizeof(chip_tim8[0])); -#else - #include "HardwareTimer.h" -#endif - extern void oneMSIntervalIRQ(stimer_t *Timer) - { - oneMSInterval(); - } - extern void EmptyIRQCallback(stimer_t *Timer, uint32_t channel) - { - - } void initBoard() { - /* - * Initialize timers - */ - - HardwareTimers_1.timer = TIM1; - HardwareTimers_2.timer = TIM2; - HardwareTimers_3.timer = TIM3; - HardwareTimers_4.timer = TIM4; - - HardwareTimers_5.timer = TIM5; - HardwareTimers_8.timer = TIM8; - - /* *********************************************************************************************************** * General */ - #define FLASH_LENGTH 8192 - + #ifndef FLASH_LENGTH + #define FLASH_LENGTH 8192 + #endif + delay(10); /* *********************************************************************************************************** * Idle @@ -64,14 +29,9 @@ } //This must happen at the end of the idle init - TimerPulseInit(&HardwareTimers_1, 0xFFFF, 0, EmptyIRQCallback); - //setTimerPrescalerRegister(&HardwareTimers_1, (uint32_t)(getTimerClkFreq(HardwareTimers_1.timer) / (500000)) - 1); - if(idle_pwm_max_count > 0) { attachIntHandleOC(&HardwareTimers_1, idleInterrupt, 4, 0);} //on first flash the configPage4.iacAlgorithm is invalid - //Timer1.setMode(4, TIMER_OUTPUT_COMPARE); + Timer1.setMode(4, TIMER_OUTPUT_COMPARE); //timer_set_mode(TIMER1, 4, TIMER_OUTPUT_COMPARE; - //on first flash the configPage4.iacAlgorithm is invalid: - //if(idle_pwm_max_count > 0) { Timer1.attachInterrupt(4, idleInterrupt);} - //Timer1.resume(); + if(idle_pwm_max_count > 0) { Timer1.attachInterrupt(4, idleInterrupt); } //on first flash the configPage4.iacAlgorithm is invalid /* @@ -79,10 +39,15 @@ * Timers */ #if defined(ARDUINO_BLACK_F407VE) || defined(STM32F4) || defined(_STM32F4_) - TimerHandleInit(&HardwareTimers_8, 1000, 168); - attachIntHandle(&HardwareTimers_8, oneMSIntervalIRQ); + Timer8.setOverflow(1000, MICROSEC_FORMAT); // Set up period + Timer8.setMode(1, TIMER_OUTPUT_COMPARE); + Timer8.attachInterrupt(1, oneMSInterval); + Timer8.resume(); //Start Timer #else - //Should do something here for other boards + Timer4.setOverflow(1000, MICROSEC_FORMAT); // Set up period + Timer4.setMode(1, TIMER_OUTPUT_COMPARE); + Timer4.attachInterrupt(1, oneMSInterval); + Timer4.resume(); //Start Timer #endif pinMode(LED_BUILTIN, OUTPUT); //Visual WDT @@ -95,72 +60,85 @@ vvt_pwm_max_count = 1000000L / (2 * configPage6.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle //Need to be initialised last due to instant interrupt - // Timer1.setMode(2, TIMER_OUTPUT_COMPARE); - // Timer1.setMode(3, TIMER_OUTPUT_COMPARE); - // if(boost_pwm_max_count > 0) { Timer1.attachInterrupt(2, boostInterrupt);} - // if(vvt_pwm_max_count > 0) { Timer1.attachInterrupt(3, vvtInterrupt);} - if(idle_pwm_max_count > 0) { attachIntHandleOC(&HardwareTimers_1, boostInterrupt, 2, 0);} - if(vvt_pwm_max_count > 0) { attachIntHandleOC(&HardwareTimers_1, vvtInterrupt, 3, 0);} - // Timer1.resume(); - - TimerPulseInit(&HardwareTimers_3, 0xFFFF, 0, EmptyIRQCallback); - attachIntHandleOC(&HardwareTimers_3, fuelSchedule1Interrupt, 1, 0); - attachIntHandleOC(&HardwareTimers_3, fuelSchedule2Interrupt, 2, 0); - attachIntHandleOC(&HardwareTimers_3, fuelSchedule3Interrupt, 3, 0); - attachIntHandleOC(&HardwareTimers_3, fuelSchedule4Interrupt, 4, 0); - + Timer1.setMode(2, TIMER_OUTPUT_COMPARE); + Timer1.setMode(3, TIMER_OUTPUT_COMPARE); + if(boost_pwm_max_count > 0) { Timer1.attachInterrupt(2, boostInterrupt);} + if(vvt_pwm_max_count > 0) { Timer1.attachInterrupt(3, vvtInterrupt);} - TimerPulseInit(&HardwareTimers_2, 0xFFFF, 0, EmptyIRQCallback); - attachIntHandleOC(&HardwareTimers_2, ignitionSchedule1Interrupt, 1, 0); - attachIntHandleOC(&HardwareTimers_2, ignitionSchedule2Interrupt, 2, 0); - attachIntHandleOC(&HardwareTimers_2, ignitionSchedule3Interrupt, 3, 0); - attachIntHandleOC(&HardwareTimers_2, ignitionSchedule4Interrupt, 4, 0); - - //Attach interupt functions - //Injection + /* + *********************************************************************************************************** + * Schedules + */ + Timer1.setOverflow(MAX_TIMER_PERIOD, MICROSEC_FORMAT); + Timer2.setOverflow(MAX_TIMER_PERIOD, MICROSEC_FORMAT); + Timer3.setOverflow(MAX_TIMER_PERIOD, MICROSEC_FORMAT); - TimerPulseInit(&HardwareTimers_5, 0xFFFF, 0, EmptyIRQCallback); - //setTimerPrescalerRegister(&HardwareTimers_5, (uint32_t)(getTimerClkFreq(HardwareTimers_5.timer) / (1000000)) - 1); - #if (INJ_CHANNELS >= 5) - attachIntHandleOC(&HardwareTimers_5, fuelSchedule5Interrupt, 1, 0); - //Timer5.attachInterrupt(1, fuelSchedule5Interrupt); - #endif - #if (INJ_CHANNELS >= 6) - attachIntHandleOC(&HardwareTimers_5, fuelSchedule6Interrupt, 2, 0); - //Timer5.attachInterrupt(2, fuelSchedule6Interrupt); - #endif - #if (INJ_CHANNELS >= 7) - attachIntHandleOC(&HardwareTimers_5, fuelSchedule7Interrupt, 3, 0); - //Timer5.attachInterrupt(3, fuelSchedule7Interrupt); - #endif - #if (INJ_CHANNELS >= 8) - attachIntHandleOC(&HardwareTimers_5, fuelSchedule8Interrupt, 4, 0); - //Timer5.attachInterrupt(4, fuelSchedule8Interrupt); - #endif - TimerPulseInit(&HardwareTimers_4, 0xFFFF, 0, EmptyIRQCallback); - //setTimerPrescalerRegister(&HardwareTimers_4, (uint32_t)(getTimerClkFreq(HardwareTimers_4.timer) / (1000000)) - 1); - #if (IGN_CHANNELS >= 5) - attachIntHandleOC(&HardwareTimers_4, ignitionSchedule5Interrupt, 1, 0); - //Timer4.attachInterrupt(1, ignitionSchedule5Interrupt); - #endif - #if (IGN_CHANNELS >= 6) - attachIntHandleOC(&HardwareTimers_4, ignitionSchedule6Interrupt, 2, 0); - //Timer4.attachInterrupt(2, ignitionSchedule6Interrupt); - #endif - #if (IGN_CHANNELS >= 7) - attachIntHandleOC(&HardwareTimers_4, ignitionSchedule7Interrupt, 3, 0); - //Timer4.attachInterrupt(3, ignitionSchedule7Interrupt); - #endif - #if (IGN_CHANNELS >= 8) - attachIntHandleOC(&HardwareTimers_4, ignitionSchedule8Interrupt, 4, 0); - //Timer4.attachInterrupt(4, ignitionSchedule8Interrupt); - #endif - - setTimerPrescalerRegister(&HardwareTimers_2, (uint32_t)(getTimerClkFreq(HardwareTimers_2.timer) / (250000)) - 1); - setTimerPrescalerRegister(&HardwareTimers_3, (uint32_t)(getTimerClkFreq(HardwareTimers_3.timer) / (250000)) - 1); - setTimerPrescalerRegister(&HardwareTimers_4, (uint32_t)(getTimerClkFreq(HardwareTimers_4.timer) / (250000)) - 1); - setTimerPrescalerRegister(&HardwareTimers_5, (uint32_t)(getTimerClkFreq(HardwareTimers_5.timer) / (250000)) - 1); + Timer2.setMode(1, TIMER_OUTPUT_COMPARE); + Timer2.setMode(2, TIMER_OUTPUT_COMPARE); + Timer2.setMode(3, TIMER_OUTPUT_COMPARE); + Timer2.setMode(4, TIMER_OUTPUT_COMPARE); + + Timer3.setMode(1, TIMER_OUTPUT_COMPARE); + Timer3.setMode(2, TIMER_OUTPUT_COMPARE); + Timer3.setMode(3, TIMER_OUTPUT_COMPARE); + Timer3.setMode(4, TIMER_OUTPUT_COMPARE); + Timer1.setMode(1, TIMER_OUTPUT_COMPARE); + + //Attach interupt functions + //Injection + Timer3.attachInterrupt(1, fuelSchedule1Interrupt); + Timer3.attachInterrupt(2, fuelSchedule2Interrupt); + Timer3.attachInterrupt(3, fuelSchedule3Interrupt); + Timer3.attachInterrupt(4, fuelSchedule4Interrupt); + #if (INJ_CHANNELS >= 5) + Timer5.setMode(1, TIMER_OUTPUT_COMPARE); + Timer5.attachInterrupt(1, fuelSchedule5Interrupt); + #endif + #if (INJ_CHANNELS >= 6) + Timer5.setMode(2, TIMER_OUTPUT_COMPARE); + Timer5.attachInterrupt(2, fuelSchedule6Interrupt); + #endif + #if (INJ_CHANNELS >= 7) + Timer5.setMode(3, TIMER_OUTPUT_COMPARE); + Timer5.attachInterrupt(3, fuelSchedule7Interrupt); + #endif + #if (INJ_CHANNELS >= 8) + Timer5.setMode(4, TIMER_OUTPUT_COMPARE); + Timer5.attachInterrupt(4, fuelSchedule8Interrupt); + #endif + + //Ignition + Timer2.attachInterrupt(1, ignitionSchedule1Interrupt); + Timer2.attachInterrupt(2, ignitionSchedule2Interrupt); + Timer2.attachInterrupt(3, ignitionSchedule3Interrupt); + Timer2.attachInterrupt(4, ignitionSchedule4Interrupt); + #if (IGN_CHANNELS >= 5) + Timer4.setMode(1, TIMER_OUTPUT_COMPARE); + Timer4.attachInterrupt(1, ignitionSchedule5Interrupt); + #endif + #if (IGN_CHANNELS >= 6) + Timer4.setMode(2, TIMER_OUTPUT_COMPARE); + Timer4.attachInterrupt(2, ignitionSchedule6Interrupt); + #endif + #if (IGN_CHANNELS >= 7) + Timer4.setMode(3, TIMER_OUTPUT_COMPARE); + Timer4.attachInterrupt(3, ignitionSchedule7Interrupt); + #endif + #if (IGN_CHANNELS >= 8) + Timer4.setMode(4, TIMER_OUTPUT_COMPARE); + Timer4.attachInterrupt(4, ignitionSchedule8Interrupt); + #endif + + Timer1.resume(); + Timer2.resume(); + Timer3.resume(); + #if (IGN_CHANNELS >= 5) + Timer4.resume(); + #endif + #if (INJ_CHANNELS >= 5) + Timer5.resume(); + #endif } uint16_t freeRam() @@ -169,7 +147,22 @@ return &top - reinterpret_cast(sbrk(0)); } - //pinmapping the STM32F407 for different boards, at this moment no board is desgined. - //All boards are set to the default just to be sure. - + /* + *********************************************************************************************************** + * Interrupt callback functions + */ + void oneMSInterval(HardwareTimer*){oneMSInterval();} + void boostInterrupt(HardwareTimer*){boostInterrupt();} + void fuelSchedule1Interrupt(HardwareTimer*){fuelSchedule1Interrupt();} + void fuelSchedule2Interrupt(HardwareTimer*){fuelSchedule2Interrupt();} + void fuelSchedule3Interrupt(HardwareTimer*){fuelSchedule3Interrupt();} + void fuelSchedule4Interrupt(HardwareTimer*){fuelSchedule4Interrupt();} + void idleInterrupt(HardwareTimer*){idleInterrupt();} + void vvtInterrupt(HardwareTimer*){vvtInterrupt();} + void ignitionSchedule1Interrupt(HardwareTimer*){ignitionSchedule1Interrupt();} + void ignitionSchedule2Interrupt(HardwareTimer*){ignitionSchedule2Interrupt();} + void ignitionSchedule3Interrupt(HardwareTimer*){ignitionSchedule3Interrupt();} + void ignitionSchedule4Interrupt(HardwareTimer*){ignitionSchedule4Interrupt();} + void ignitionSchedule5Interrupt(HardwareTimer*){ignitionSchedule5Interrupt();} + #endif From 3a42674d5768492893e01f2acee5125f1a900a65 Mon Sep 17 00:00:00 2001 From: hoogendijkta Date: Mon, 30 Sep 2019 21:29:26 +0200 Subject: [PATCH 11/11] Repair code with new STM32duino 1.7.0 core --- speeduino/board_stm32_official.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/speeduino/board_stm32_official.h b/speeduino/board_stm32_official.h index 7c481d50..a6b3def6 100644 --- a/speeduino/board_stm32_official.h +++ b/speeduino/board_stm32_official.h @@ -4,7 +4,7 @@ #include #include #include -#include "stm32f1xx_ll_tim.h" +#include "stm32f4xx_ll_tim.h" /* *********************************************************************************************************** * General