diff --git a/platformio.ini b/platformio.ini index 1147475b..393d4d10 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,6 +16,7 @@ build_unflags = -Os build_flags = -O3 -ffast-math -fshort-enums -funroll-loops -Wall -Wextra -std=c99 lib_deps = EEPROM, Time test_build_project_src = true +test_build_src = yes debug_tool = simavr test_ignore = test_table3d_native @@ -26,7 +27,7 @@ framework=arduino build_unflags = -Os build_flags = -O3 -ffast-math -Wall -Wextra -std=c99 lib_deps = EEPROM, Time -test_build_project_src = true +test_build_src = yes [env:teensy35] ;platform=teensy diff --git a/reference/speeduino.ini b/reference/speeduino.ini index b573650e..ba596763 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -454,7 +454,7 @@ page = 1 ;These are reserved for future use, in case of more CAN broadcasting features are added enable1Cluster = bits, U08, 126, [2:2], "Off", "On" enable2Cluster = bits, U08, 126, [3:3], "Off", "On" - unusedClusterBits = bits, U08, 126, [4:7], "INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID" + unusedClusterBits = bits, U08, 126, [4:7], "Off","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID" unused2-95 = scalar, U08, 127, "RPM", 100, 0.0, 0.0, 16320, 0 @@ -655,7 +655,7 @@ page = 6 useExtBaro = bits, U08, 13, [6:6], "No", "Yes" boostMode = bits, U08, 13, [7:7], "Simple", "Full" boostPin = bits, U08, 14, [0:5], "Board Default", "INVALID", "INVALID", "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" - unused_bit = bits, U08, 14, [6:6], "No", "Yes" + tachoMode = bits, U08, 14, [6:6], "Fixed Duration", "Match Dwell" useEMAP = bits, U08, 14, [7:7], "No", "Yes" brvBins = array, U08, 15, [6], "V", 0.1, 0, 6, 24, 1 ; Bins for the battery reference voltage injBatRates = array, U08, 21, [6], "%", 1, 0, 0, 255, 0 ;Values for injector pulsewidth vs voltage @@ -2249,6 +2249,7 @@ menuDialog = main battVCorMode = "The Battery Voltage Correction value from the table below can either be applied on the whole injection Pulse Width value, or only on the Open Time value." dwellTable = "Sets the dwell time in milliseconds based on RPM/load. This can be used to reduce stress/wear on ignition system where long dwell is not needed. And other areas can use longer dwell value if needed for stronger spark. Battery voltage correction is applied for these dwell values." useDwellMap = "In normal operation mode this is set to No and speeduino will use fixed running dwell value. But if different dwell values are required across engine RPM/load range, this can be set to Yes and separate Dwell table defines running dwell value." + tachoMode = "The output mode for the tacho pulse. Fixed timing will produce a pulse that is always of the same duration, which works better with mode modern digital tachos. Dwell based output creates a pulse that is matched to the coil/s dwell time. If enabled the tacho pulse duration and timing is same as coil dwell and the number of pulses is same as number of ignition events. This can work better on some styles of tacho but note that the pulse duration might become problem on higher cylinder number engines." canBMWCluster = "Enables CAN broadcasting for BMW E46, E39 and E38 instrument clusters with message ID's 0x316, 0x329 and 0x545" canVAGCluster = "Enables CAN broadcasting for VAG instrument clusters with message ID's 0x280 and 0x5A0" @@ -2413,11 +2414,12 @@ menuDialog = main panel = vss_gear_detection dialog = tacho, "Tacho" - field = "Output pin", tachoPin - field = "Output speed", tachoDiv - field = "Pulse duration", tachoDuration - ;field = "Tacho sweep on boot", useTachoSweep - ;field = "Tacho sweep Max RPM", tachoSweepMaxRPM, { useTachoSweep } + field = "Output pin", tachoPin + field = "Tacho pulse mode", tachoMode + field = "Output speed", tachoDiv, { tachoMode == 0 } + field = "Pulse duration", tachoDuration, { tachoMode == 0 } + ;field = "Tacho sweep on boot", useTachoSweep + ;field = "Tacho sweep Max RPM", tachoSweepMaxRPM, { useTachoSweep } dialog = accelEnrichments_aeSettings, "" field = "Enrichment mode", aeMode diff --git a/speeduino/corrections.ino b/speeduino/corrections.ino index 50c7f423..2eaaf924 100644 --- a/speeduino/corrections.ino +++ b/speeduino/corrections.ino @@ -365,7 +365,7 @@ uint16_t correctionAccel() else if(configPage2.aeMode == AE_MODE_TPS) { //Get the TPS rate change - TPS_change = (currentStatus.TPS - TPSlast); + TPS_change = (currentStatus.TPS - currentStatus.TPSlast); //TPS_rateOfChange = ldiv(1000000, (TPS_time - TPSlast_time)).quot * TPS_change; //This is the % per second that the TPS has moved TPS_rateOfChange = (TPS_READ_FREQUENCY * TPS_change) / 2; //This is the % per second that the TPS has moved, adjusted for the 0.5% resolution of the TPS if(TPS_rateOfChange >= 0) { currentStatus.tpsDOT = TPS_rateOfChange / 10; } //The TAE bins are divided by 10 in order to allow them to be stored in a byte @@ -431,7 +431,7 @@ uint16_t correctionAccel() else { int16_t taperRange = trueTaperMax - trueTaperMin; - int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100) / taperRange; //The percentage of the way through the RPM taper range + int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100UL) / taperRange; //The percentage of the way through the RPM taper range accelValue = percentage((100-taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount. } } @@ -490,7 +490,7 @@ uint16_t correctionAccel() else { int16_t taperRange = trueTaperMax - trueTaperMin; - int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100) / taperRange; //The percentage of the way through the RPM taper range + int16_t taperPercent = ((currentStatus.RPM - trueTaperMin) * 100UL) / taperRange; //The percentage of the way through the RPM taper range accelValue = percentage( (100 - taperPercent), accelValue); //Calculate the above percentage of the calculated accel amount. } } diff --git a/speeduino/decoders.ino b/speeduino/decoders.ino index 72d9a04e..7c39e15b 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -4618,6 +4618,7 @@ void triggerPri_Vmax() toothOneTime = curTime; currentStatus.hasSync = true; setFilter((curGap/1.75));//Angle to this tooth is 70, next is in 40, compensating. + currentStatus.startRevolutions++; //Counter } else if (toothCurrentCount==2) { @@ -4651,7 +4652,6 @@ void triggerPri_Vmax() } toothLastMinusOneToothTime = toothLastToothTime; toothLastToothTime = curTime; - currentStatus.startRevolutions++; //Counter if (triggerFilterTime > 50000){//The first pulse seen triggerFilterTime = 0; } diff --git a/speeduino/globals.h b/speeduino/globals.h index fc101311..de89856d 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -637,6 +637,7 @@ struct statuses { byte TPS; /**< The current TPS reading (0% - 100%). Is the tpsADC value after the calibration is applied */ byte tpsADC; /**< byte (valued: 0-255) representation of the TPS. Downsampled from the original 10-bit (0-1023) reading, but before any calibration is applied */ byte tpsDOT; /**< TPS delta over time. Measures the % per second that the TPS is changing. Value is divided by 10 to be stored in a byte */ + byte TPSlast; /**< The previous TPS reading */ byte mapDOT; /**< MAP delta over time. Measures the kpa per second that the MAP is changing. Value is divided by 10 to be stored in a byte */ volatile int rpmDOT; /**< RPM delta over time (RPM increase / s ?) */ byte VE; /**< The current VE value being used in the fuel calculation. Can be the same as VE1 or VE2, or a calculated value of both. */ @@ -1050,7 +1051,7 @@ struct config6 { byte useExtBaro : 1; byte boostMode : 1; /// Boost control mode: 0=Simple (BOOST_MODE_SIMPLE) or 1=full (BOOST_MODE_FULL) byte boostPin : 6; - byte unused_bit : 1; //Previously was VVTasOnOff + byte tachoMode : 1; /// Whether to use fixed tacho pulse duration or match to dwell duration byte useEMAP : 1; ///< Enable EMAP byte voltageCorrectionBins[6]; //X axis bins for voltage correction tables byte injVoltageCorrectionValues[6]; //Correction table for injector PW vs battery voltage diff --git a/speeduino/init.ino b/speeduino/init.ino index 4bfdedbc..1e769d94 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -1813,6 +1813,7 @@ void setPinMapping(byte boardID) pinTrigger3 = 20; //The Cam sensor 2 pin pinTPS = A2;//TPS input pin pinMAP = A3; //MAP sensor pin + pinEMAP = A15; //EMAP sensor pin pinIAT = A0; //IAT sensor pin pinCLT = A1; //CLT sensor pin pinO2 = A8; //O2 Sensor pin @@ -1834,6 +1835,11 @@ void setPinMapping(byte boardID) pinFlex = 2; // Flex sensor pinResetControl = 43; //Reset control output pinVSS = 3; //VSS input pin + pinWMIEmpty = 31; //(placeholder) + pinWMIIndicator = 33; //(placeholder) + pinWMIEnabled = 35; //(placeholder) + pinIdleUp = 37; //(placeholder) + pinCTPS = A6; //(placeholder) #elif defined(STM32F407xx) pinInjector1 = PB15; //Output pin injector 1 pinInjector2 = PB14; //Output pin injector 2 @@ -1855,6 +1861,7 @@ void setPinMapping(byte boardID) pinTrigger2 = PD4; //The Cam Sensor pin pinTPS = PA2;//TPS input pin pinMAP = PA3; //MAP sensor pin + pinEMAP = PC5; //EMAP sensor pin pinIAT = PA0; //IAT sensor pin pinCLT = PA1; //CLS sensor pin pinO2 = PB0; //O2 Sensor pin @@ -1876,6 +1883,11 @@ void setPinMapping(byte boardID) pinFlex = PD7; // Flex sensor pinResetControl = PB7; //Reset control output pinVSS = PB6; //VSS input pin + pinWMIEmpty = PD15; //(placeholder) + pinWMIIndicator = PD13; //(placeholder) + pinWMIEnabled = PE15; //(placeholder) + pinIdleUp = PE14; //(placeholder) + pinCTPS = PA6; //(placeholder) #endif break; @@ -2210,6 +2222,52 @@ void setPinMapping(byte boardID) #endif break; + + case 56: + #if defined(CORE_TEENSY) + //Pin mappings for the Bear Cub (Teensy 4.1) + pinInjector1 = 6; + pinInjector2 = 7; + pinInjector3 = 9; + pinInjector4 = 8; + pinInjector5 = 0; //Not used + pinCoil1 = 2; + pinCoil2 = 3; + pinCoil3 = 4; + pinCoil4 = 5; + + pinTrigger = 20; //The CAS pin + pinTrigger2 = 21; //The Cam Sensor pin + pinFlex = 37; // Flex sensor + pinMAP = A5; //MAP sensor pin + pinBaro = A4; //Baro sensor pin + pinBat = A15; //Battery reference voltage pin + pinTPS = A3; //TPS input pin + pinIAT = A0; //IAT sensor pin + pinCLT = A1; //CLS sensor pin + pinO2 = A2; //O2 Sensor pin + pinLaunch = 36; + + pinSpareTemp1 = A16; //spare Analog input 1 + pinSpareTemp2 = A17; //spare Analog input 2 + pinTachOut = 38; //Tacho output pin + pinIdle1 = 27; //Single wire idle control + pinIdle2 = 26; //2 wire idle control. Shared with Spare 1 output + pinFuelPump = 10; //Fuel pump output + pinVVT_1 = 28; //Default VVT output + pinStepperDir = 32; //Direction pin for DRV8825 driver + pinStepperStep = 31; //Step pin for DRV8825 driver + pinStepperEnable = 30; //Enable pin for DRV8825 driver + pinBoost = 24; //Boost control + pinSpareLOut1 = 29; //low current output spare1 + pinSpareLOut2 = 26; //low current output spare2 + pinSpareLOut3 = 28; //low current output spare3 + pinSpareLOut4 = 29; //low current output spare4 + pinFan = 25; //Pin for the fan output + pinResetControl = 46; //Reset control output PLACEHOLDER value for now + + #endif + break; case 60: diff --git a/speeduino/scheduledIO.h b/speeduino/scheduledIO.h index 410dce3c..5ccab4c7 100644 --- a/speeduino/scheduledIO.h +++ b/speeduino/scheduledIO.h @@ -125,6 +125,9 @@ void coil6Toggle(); void coil7Toggle(); void coil8Toggle(); +void tachoOutputOn(); +void tachoOutputOff(); + /* #ifndef USE_MC33810 #define openInjector1() *inj1_pin_port |= (inj1_pin_mask); BIT_SET(currentStatus.status1, BIT_STATUS1_INJ1) diff --git a/speeduino/scheduledIO.ino b/speeduino/scheduledIO.ino index 20aec342..0b8d5fd4 100644 --- a/speeduino/scheduledIO.ino +++ b/speeduino/scheduledIO.ino @@ -73,29 +73,29 @@ void closeInjector3and7() { closeInjector3(); closeInjector7(); } void openInjector4and8() { openInjector4(); openInjector8(); } void closeInjector4and8() { closeInjector4(); closeInjector8(); } -inline void beginCoil1Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil1Charging_DIRECT(); } else { coil1Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil1Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil1StopCharging_DIRECT(); } else { coil1StopCharging_MC33810(); } } +inline void beginCoil1Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil1Charging_DIRECT(); } else { coil1Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil1Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil1StopCharging_DIRECT(); } else { coil1StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil2Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil2Charging_DIRECT(); } else { coil2Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil2Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil2StopCharging_DIRECT(); } else { coil2StopCharging_MC33810(); } } +inline void beginCoil2Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil2Charging_DIRECT(); } else { coil2Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil2Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil2StopCharging_DIRECT(); } else { coil2StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil3Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil3Charging_DIRECT(); } else { coil3Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil3Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil3StopCharging_DIRECT(); } else { coil3StopCharging_MC33810(); } } +inline void beginCoil3Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil3Charging_DIRECT(); } else { coil3Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil3Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil3StopCharging_DIRECT(); } else { coil3StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil4Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil4Charging_DIRECT(); } else { coil4Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil4Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil4StopCharging_DIRECT(); } else { coil4StopCharging_MC33810(); } } +inline void beginCoil4Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil4Charging_DIRECT(); } else { coil4Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil4Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil4StopCharging_DIRECT(); } else { coil4StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil5Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil5Charging_DIRECT(); } else { coil5Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil5Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil5StopCharging_DIRECT(); } else { coil5StopCharging_MC33810(); } } +inline void beginCoil5Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil5Charging_DIRECT(); } else { coil5Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil5Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil5StopCharging_DIRECT(); } else { coil5StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil6Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil6Charging_DIRECT(); } else { coil6Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil6Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil6StopCharging_DIRECT(); } else { coil6StopCharging_MC33810(); } } +inline void beginCoil6Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil6Charging_DIRECT(); } else { coil6Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil6Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil6StopCharging_DIRECT(); } else { coil6StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil7Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil7Charging_DIRECT(); } else { coil7Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil7Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil7StopCharging_DIRECT(); } else { coil7StopCharging_MC33810(); } } +inline void beginCoil7Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil7Charging_DIRECT(); } else { coil7Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil7Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil7StopCharging_DIRECT(); } else { coil7StopCharging_MC33810(); } tachoOutputOff(); } -inline void beginCoil8Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil8Charging_DIRECT(); } else { coil8Charging_MC33810(); } tachoOutputFlag = READY; } -inline void endCoil8Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil8StopCharging_DIRECT(); } else { coil8StopCharging_MC33810(); } } +inline void beginCoil8Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil8Charging_DIRECT(); } else { coil8Charging_MC33810(); } tachoOutputOn(); } +inline void endCoil8Charge() { if(ignitionOutputControl != OUTPUT_CONTROL_MC33810) { coil8StopCharging_DIRECT(); } else { coil8StopCharging_MC33810(); } tachoOutputOff(); } //The below 3 calls are all part of the rotary ignition mode inline void beginTrailingCoilCharge() { beginCoil2Charge(); } @@ -126,4 +126,7 @@ void endCoil3and7Charge() { endCoil3Charge(); endCoil7Charge(); } void beginCoil4and8Charge() { beginCoil4Charge(); beginCoil8Charge(); } void endCoil4and8Charge() { endCoil4Charge(); endCoil8Charge(); } +void tachoOutputOn() { if(configPage6.tachoMode) { TACHO_PULSE_LOW(); } else { tachoOutputFlag = READY; } } +void tachoOutputOff() { if(configPage6.tachoMode) { TACHO_PULSE_HIGH(); } } + void nullCallback() { return; } diff --git a/speeduino/sensors.h b/speeduino/sensors.h index 38f5f35a..bfadf33c 100644 --- a/speeduino/sensors.h +++ b/speeduino/sensors.h @@ -52,9 +52,6 @@ unsigned long EMAPrunningValue; //As above but for EMAP unsigned int MAPcount; //Number of samples taken in the current MAP cycle uint32_t MAPcurRev; //Tracks which revolution we're sampling on bool auxIsEnabled; -byte TPSlast; /**< The previous TPS reading */ -unsigned long TPS_time; //The time the TPS sample was taken -unsigned long TPSlast_time; //The time the previous TPS sample was taken uint16_t MAPlast; /**< The previous MAP reading */ unsigned long MAP_time; //The time the MAP sample was taken unsigned long MAPlast_time; //The time the previous MAP sample was taken diff --git a/speeduino/sensors.ino b/speeduino/sensors.ino index 24021b58..72a612e0 100644 --- a/speeduino/sensors.ino +++ b/speeduino/sensors.ino @@ -397,8 +397,7 @@ static inline void readMAP() void readTPS(bool useFilter) { - TPSlast = currentStatus.TPS; - TPSlast_time = TPS_time; + currentStatus.TPSlast = currentStatus.TPS; #if defined(ANALOG_ISR) byte tempTPS = fastMap1023toX(AnChannel[pinTPS-A0], 255); //Get the current raw TPS ADC value and map it into a byte #else @@ -439,7 +438,6 @@ void readTPS(bool useFilter) else { currentStatus.CTPSActive = digitalRead(pinCTPS); } //Inverted mode (5v activates closed throttle position sensor) } else { currentStatus.CTPSActive = 0; } - TPS_time = micros(); } void readCLT(bool useFilter) diff --git a/speeduino/timers.ino b/speeduino/timers.ino index 0bba668b..9f1f36ac 100644 --- a/speeduino/timers.ino +++ b/speeduino/timers.ino @@ -32,6 +32,7 @@ void initialiseTimers() loop100ms = 0; loop250ms = 0; loopSec = 0; + tachoOutputFlag = DEACTIVE; } @@ -68,8 +69,8 @@ void oneMSInterval() //Most ARM chips can simply call a function if(ignitionSchedule7.Status == RUNNING) { if( (ignitionSchedule7.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { ign7EndFunction(); ignitionSchedule7.Status = OFF; } } if(ignitionSchedule8.Status == RUNNING) { if( (ignitionSchedule8.startTime < targetOverdwellTime) && (configPage4.useDwellLim) && (isCrankLocked != true) ) { ign8EndFunction(); ignitionSchedule8.Status = OFF; } } - //Tacho output check - //Tacho is flagged as being ready for a pulse by the ignition outputs. + //Tacho output check. This code will not do anything if tacho pulse duration is fixed to coil dwell. + //Tacho is flagged as being ready for a pulse by the ignition outputs. if(tachoOutputFlag == READY) { //Check for half speed tacho diff --git a/speeduino/updates.ino b/speeduino/updates.ino index 5f859b9b..075394b6 100644 --- a/speeduino/updates.ino +++ b/speeduino/updates.ino @@ -491,7 +491,7 @@ void doUpdates() configPage10.TrigEdgeThrd = 0; //Old use as On/Off selection is removed, so change VVT mode to On/Off based on that - if(configPage6.unused_bit == 1) { configPage6.vvtMode = VVT_MODE_ONOFF; } + if(configPage6.tachoMode == 1) { configPage6.vvtMode = VVT_MODE_ONOFF; } //Closed loop VVT improvements. Set safety limits to max/min working values and filter to minimum. configPage10.vvtCLMinAng = 0; @@ -579,6 +579,29 @@ void doUpdates() configPage4.vvtDelay = 0; configPage4.vvtMinClt = 0; + + //Set SD logging related settings to zero. + configPage13.onboard_log_csv_separator = 0; + configPage13.onboard_log_file_style = 0; + configPage13.onboard_log_file_rate = 0; + configPage13.onboard_log_filenaming = 0; + configPage13.onboard_log_storage = 0; + configPage13.onboard_log_trigger_boot = 0; + configPage13.onboard_log_trigger_RPM = 0; + configPage13.onboard_log_trigger_prot = 0; + configPage13.onboard_log_trigger_Vbat = 0; + configPage13.onboard_log_trigger_Epin = 0; + configPage13.onboard_log_tr1_duration = 0; + configPage13.onboard_log_tr2_thr_on = 0; + configPage13.onboard_log_tr2_thr_off = 0; + configPage13.onboard_log_tr3_thr_RPM = 0; + configPage13.onboard_log_tr3_thr_MAP = 0; + configPage13.onboard_log_tr3_thr_Oil = 0; + configPage13.onboard_log_tr3_thr_AFR = 0; + configPage13.onboard_log_tr4_thr_on = 0; + configPage13.onboard_log_tr4_thr_off = 0; + configPage13.onboard_log_tr5_thr_on = 0; + writeAllConfig(); storeEEPROMVersion(19); } @@ -592,6 +615,7 @@ void doUpdates() if( configPage2.nCylinders == 4 ) { configPage4.inj4cylPairing = INJ_PAIR_14_23; } //Force setting to use the default mode from previous FW versions. This is to prevent issues on any setups that have been wired accordingly configPage9.hardRevMode = 1; //Set hard rev limiter to Fixed mode + configPage6.tachoMode = 0; //CAN broadcast introduced configPage2.canBMWCluster = 0; diff --git a/test/test_decoders/test_decoders.cpp b/test/test_decoders/test_decoders.cpp index 109426c8..1fd37fd2 100644 --- a/test/test_decoders/test_decoders.cpp +++ b/test/test_decoders/test_decoders.cpp @@ -1,5 +1,6 @@ #include +#include #include #include "missing_tooth/missing_tooth.h" diff --git a/test/test_fuel/test_corrections.cpp b/test/test_fuel/test_corrections.cpp index ade67a24..7a84d27f 100644 --- a/test/test_fuel/test_corrections.cpp +++ b/test/test_fuel/test_corrections.cpp @@ -8,6 +8,7 @@ void testCorrections() { test_corrections_WUE(); test_corrections_dfco(); + test_corrections_TAE(); //TPS based accel enrichment corrections /* RUN_TEST(test_corrections_cranking); //Not written yet RUN_TEST(test_corrections_ASE); //Not written yet @@ -140,7 +141,7 @@ void setup_DFCO_on() correctionDFCO(); dfcoTaper = 20; } - +//********************************************************************************************************************** void test_corrections_dfco_on(void) { //Test under ideal conditions that DFCO goes active @@ -185,3 +186,144 @@ void test_corrections_dfco() RUN_TEST(test_corrections_dfco_off_TPS); RUN_TEST(test_corrections_dfco_off_delay); } +//********************************************************************************************************************** +//Setup a basic TAE enrichment curve, threshold etc that are common to all tests. Specifica values maybe updated in each individual test +void test_corrections_TAE_setup() +{ + configPage2.aeMode = AE_MODE_TPS; //Set AE to TPS + + configPage4.taeValues[0] = 70; + configPage4.taeValues[1] = 103; + configPage4.taeValues[2] = 124; + configPage4.taeValues[3] = 136; + + //Note: These values are divided by 10 + configPage4.taeBins[0] = 0; + configPage4.taeBins[1] = 8; + configPage4.taeBins[2] = 22; + configPage4.taeBins[3] = 97; + + configPage2.taeThresh = 0; + + //Divided by 100 + configPage2.aeTaperMin = 10; //1000 + configPage2.aeTaperMax = 50; //5000 + + //Set the coolant to be above the warmup AE taper + configPage2.aeColdTaperMax = 60; + configPage2.aeColdTaperMin = 0; + currentStatus.coolant = (int)(configPage2.aeColdTaperMax - CALIBRATION_TEMPERATURE_OFFSET) + 1; + + BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); //Make sure AE is turned off +} + +void test_corrections_TAE_no_rpm_taper() +{ + //Disable the taper + currentStatus.RPM = 2000; + configPage2.aeTaperMin = 50; //5000 + configPage2.aeTaperMax = 60; //6000 + + currentStatus.TPSlast = 0; + currentStatus.TPS = 50; //25% actual value + + uint16_t accelValue = correctionAccel(); //Run the AE calcs + + TEST_ASSERT_EQUAL(75, currentStatus.tpsDOT); //DOT is 750%/s (25 * 30), value divided by 10; + TEST_ASSERT_EQUAL((100+132), accelValue); + TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC)); //Confirm AE is flagged on +} + +void test_corrections_TAE_50pc_rpm_taper() +{ + //RPM is 50% of the way through the taper range + currentStatus.RPM = 3000; + configPage2.aeTaperMin = 10; //1000 + configPage2.aeTaperMax = 50; //5000 + + currentStatus.TPSlast = 0; + currentStatus.TPS = 50; //25% actual value + + uint16_t accelValue = correctionAccel(); //Run the AE calcs + + TEST_ASSERT_EQUAL(75, currentStatus.tpsDOT); //DOT is 750%/s (25 * 30), value divided by 10; + TEST_ASSERT_EQUAL((100+66), accelValue); + TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC)); //Confirm AE is flagged on +} + +void test_corrections_TAE_110pc_rpm_taper() +{ + //RPM is 110% of the way through the taper range, which should result in no additional AE + currentStatus.RPM = 5400; + configPage2.aeTaperMin = 10; //1000 + configPage2.aeTaperMax = 50; //5000 + + currentStatus.TPSlast = 0; + currentStatus.TPS = 50; //25% actual value + + uint16_t accelValue = correctionAccel(); //Run the AE calcs + + TEST_ASSERT_EQUAL(75, currentStatus.tpsDOT); //DOT is 750%/s (25 * 30), value divided by 10; + TEST_ASSERT_EQUAL(100, accelValue); //Should be no AE as we're above the RPM taper end point + TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC)); //Confirm AE is flagged on +} + +void test_corrections_TAE_under_threshold() +{ + //RPM is 50% of the way through the taper range, but TPS value will be below threshold + currentStatus.RPM = 3000; + configPage2.aeTaperMin = 10; //1000 + configPage2.aeTaperMax = 50; //5000 + + currentStatus.TPSlast = 0; + currentStatus.TPS = 6; //3% actual value. TPSDot should be 90%/s + configPage2.taeThresh = 100; //Above the reading of 90%/s + + uint16_t accelValue = correctionAccel(); //Run the AE calcs + + TEST_ASSERT_EQUAL(9, currentStatus.tpsDOT); //DOT is 90%/s (3% * 30), value divided by 10; + TEST_ASSERT_EQUAL(100, accelValue); //Should be no AE as we're above the RPM taper end point + TEST_ASSERT_FALSE(BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC)); //Confirm AE is flagged off +} + +void test_corrections_TAE_50pc_warmup_taper() +{ + //Disable the RPM taper + currentStatus.RPM = 2000; + configPage2.aeTaperMin = 50; //5000 + configPage2.aeTaperMax = 60; //6000 + + currentStatus.TPSlast = 0; + currentStatus.TPS = 50; //25% actual value + + //Set a cold % of 50% increase + configPage2.aeColdPct = 200; + configPage2.aeColdTaperMax = 60 + CALIBRATION_TEMPERATURE_OFFSET; + configPage2.aeColdTaperMin = 0 + CALIBRATION_TEMPERATURE_OFFSET; + //Set the coolant to be 50% of the way through the warmup range + currentStatus.coolant = 30; + + uint16_t accelValue = correctionAccel(); //Run the AE calcs + + TEST_ASSERT_EQUAL(75, currentStatus.tpsDOT); //DOT is 750%/s (25 * 30), value divided by 10; + TEST_ASSERT_EQUAL((100+165), accelValue); //Total AE should be 132 + (50% * 50%) = 132 * 1.25 = 165 + TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC)); //Confirm AE is flagged on +} + +void test_corrections_TAE() +{ + test_corrections_TAE_setup(); + + + RUN_TEST(test_corrections_TAE_no_rpm_taper); + BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); //Flag must be cleared between tests + RUN_TEST(test_corrections_TAE_50pc_rpm_taper); + BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); //Flag must be cleared between tests + RUN_TEST(test_corrections_TAE_110pc_rpm_taper); + BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); //Flag must be cleared between tests + RUN_TEST(test_corrections_TAE_under_threshold); + BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC); //Flag must be cleared between tests + RUN_TEST(test_corrections_TAE_50pc_warmup_taper); + + +} \ No newline at end of file diff --git a/test/test_fuel/test_corrections.h b/test/test_fuel/test_corrections.h index 0f148915..d9ef1bb1 100644 --- a/test/test_fuel/test_corrections.h +++ b/test/test_fuel/test_corrections.h @@ -9,4 +9,5 @@ void test_corrections_bat(void); void test_corrections_iatdensity(void); void test_corrections_baro(void); void test_corrections_launch(void); -void test_corrections_dfco(void); \ No newline at end of file +void test_corrections_dfco(void); +void test_corrections_TAE(void); \ No newline at end of file