From 3feefef1a70f30d225176b79085a6fc6f37e4dd6 Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Wed, 5 Oct 2016 13:44:09 -0300 Subject: [PATCH 01/21] removed unused variables removed unused variables in fastMap1023toX function --- math.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/math.h b/math.h index e671cd9..73ff072 100644 --- a/math.h +++ b/math.h @@ -10,11 +10,35 @@ int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max) //This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range //This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings) -int fastMap1023toX(unsigned long x, int in_min, int in_max, int out_min, int out_max) +//int fastMap1023toX(unsigned long x, int in_min, int in_max, int out_min, int out_max) +//removed unused variables, in_min and out_min is aways 0, in_max is aways 1023 +int fastMap1023toX(unsigned long x, int out_max) { return (x * out_max) >> 10; } +/* +//Unsigned int assembly multiply, result in 20 clocks +//Need speed test +unsigned long hwdu16(unsigned int x, unsigned int y){ + unsigned long result; + asm("mul _y, _x"); //arg1l * arg2l - > + asm("movw _result+2, r0"); + asm("movf _y+1,_x+1");//arg1h * arg2h - > + asm("movw _result, r0"); + asm("mul _y, _x+1"); //arg1l * arg2h - > + asm("add _result+2,r0");//add cross + asm("adc _result+1,r1");//products + asm("clr r0"); + asm("adc _result,r0"); + asm("mul _y+1, _x"); //arg1h * arg2l - > + asm("add _result+2,r0");//add cross + asm("adc _result+1,r1");//products + asm("clr r0"); + asm("adc _result,r0"); + return(result); +}*/ + /* The following are all fast versions of specific divisions Ref: http://www.hackersdelight.org/divcMore.pdf From 9d2c3f41069718322dea4460ccb089734f3dc397 Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Wed, 5 Oct 2016 13:50:04 -0300 Subject: [PATCH 02/21] removed unused variables --- speeduino.ino | 3 --- 1 file changed, 3 deletions(-) diff --git a/speeduino.ino b/speeduino.ino index e6a6f57..776a9e4 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -1002,7 +1002,6 @@ void loop() if( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { unsigned long pwLimit = percentage(configPage1.dutyLim, revolutionTime); //The pulsewidth limit is determined to be the duty cycle limit (Eg 85%) by the total time it takes to perform 1 revolution - if ( if (currentStatus.PW > pwLimit) { currentStatus.PW = pwLimit; } } @@ -1471,5 +1470,3 @@ void beginCoil2and4Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pin void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoil4, coilLOW); } void nullCallback() { return; } - - From eb2ce0591fe1463b3a3df786472dc8ec20513917 Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Wed, 5 Oct 2016 13:51:14 -0300 Subject: [PATCH 03/21] Fix wrong Battery voltage pin name --- globals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/globals.h b/globals.h index 7082896..ccf3051 100644 --- a/globals.h +++ b/globals.h @@ -421,7 +421,7 @@ byte pinIAT; //IAT sensor pin byte pinCLT; //CLS sensor pin byte pinO2; //O2 Sensor pin byte pinO2_2; //second O2 pin -byte pinBat; //O2 Sensor pin +byte pinBat; //Battery voltage pin byte pinDisplayReset; // OLED reset pin byte pinTachOut; //Tacho output byte pinFuelPump; //Fuel pump on/off From 1f6169ecefbc9b6d3fd40548b0195e51ee0c737d Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Wed, 5 Oct 2016 13:53:11 -0300 Subject: [PATCH 04/21] removed unused variables --- sensors.ino | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sensors.ino b/sensors.ino index 3f784d5..c320e9c 100644 --- a/sensors.ino +++ b/sensors.ino @@ -16,7 +16,7 @@ void instanteneousMAPReading() if(tempReading >= VALID_MAP_MAX || tempReading <= VALID_MAP_MIN) { mapErrorCount += 1; } else { currentStatus.mapADC = tempReading; mapErrorCount = 0; } - currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, 0, 1023, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value + currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax); //Get the current MAP value } void readMAP() @@ -51,7 +51,7 @@ void readMAP() { //Reaching here means that the last cylce has completed and the MAP value should be calculated currentStatus.mapADC = ldiv(MAPrunningValue, MAPcount).quot; - currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, 0, 1023, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value + currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax); //Get the current MAP value MAPcurRev = startRevolutions; //Reset the current rev count MAPrunningValue = 0; MAPcount = 0; @@ -77,7 +77,7 @@ void readMAP() { //Reaching here means that the last cylce has completed and the MAP value should be calculated currentStatus.mapADC = MAPrunningValue; - currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, 0, 1023, configPage1.mapMin, configPage1.mapMax); //Get the current MAP value + currentStatus.MAP = fastMap1023toX(currentStatus.mapADC, configPage1.mapMax); //Get the current MAP value MAPcurRev = startRevolutions; //Reset the current rev count MAPrunningValue = 1023; //Reset the latest value so the next reading will always be lower } @@ -90,7 +90,7 @@ void readTPS() currentStatus.TPSlast = currentStatus.TPS; currentStatus.TPSlast_time = currentStatus.TPS_time; analogRead(pinTPS); - byte tempTPS = fastMap1023toX(analogRead(pinTPS), 0, 1023, 0, 255); //Get the current raw TPS ADC value and map it into a byte + byte tempTPS = fastMap1023toX(analogRead(pinTPS), 255); //Get the current raw TPS ADC value and map it into a byte currentStatus.tpsADC = ADC_FILTER(tempTPS, ADCFILTER_TPS, currentStatus.tpsADC); //Check that the ADC values fall within the min and max ranges (Should always be the case, but noise can cause these to fluctuate outside the defined range). byte tempADC = currentStatus.tpsADC; //The tempADC value is used in order to allow TunerStudio to recover and redo the TPS calibration if this somehow gets corrupted @@ -103,7 +103,7 @@ void readTPS() void readCLT() { tempReading = analogRead(pinCLT); - tempReading = fastMap1023toX(analogRead(pinCLT), 0, 1023, 0, 511); //Get the current raw CLT value + tempReading = fastMap1023toX(analogRead(pinCLT), 511); //Get the current raw CLT value currentStatus.cltADC = ADC_FILTER(tempReading, ADCFILTER_CLT, currentStatus.cltADC); currentStatus.coolant = cltCalibrationTable[currentStatus.cltADC] - CALIBRATION_TEMPERATURE_OFFSET; //Temperature calibration values are stored as positive bytes. We subtract 40 from them to allow for negative temperatures } @@ -111,7 +111,7 @@ void readCLT() void readIAT() { tempReading = analogRead(pinIAT); - tempReading = fastMap1023toX(analogRead(pinIAT), 0, 1023, 0, 511); //Get the current raw IAT value + tempReading = fastMap1023toX(analogRead(pinIAT), 511); //Get the current raw IAT value currentStatus.iatADC = ADC_FILTER(tempReading, ADCFILTER_IAT, currentStatus.iatADC); currentStatus.IAT = iatCalibrationTable[currentStatus.iatADC] - CALIBRATION_TEMPERATURE_OFFSET; } @@ -119,7 +119,7 @@ void readIAT() void readO2() { tempReading = analogRead(pinO2); - tempReading = fastMap1023toX(analogRead(pinO2), 0, 1023, 0, 511); //Get the current O2 value. + tempReading = fastMap1023toX(analogRead(pinO2), 511); //Get the current O2 value. currentStatus.O2ADC = ADC_FILTER(tempReading, ADCFILTER_O2, currentStatus.O2ADC); currentStatus.O2 = o2CalibrationTable[currentStatus.O2ADC]; } @@ -133,7 +133,7 @@ void readO2() void readBat() { tempReading = analogRead(pinBat); - tempReading = fastMap1023toX(analogRead(pinBat), 0, 1023, 0, 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245) + tempReading = fastMap1023toX(analogRead(pinBat), 245); //Get the current raw Battery value. Permissible values are from 0v to 24.5v (245) currentStatus.battery10 = ADC_FILTER(tempReading, ADCFILTER_BAT, currentStatus.battery10); } From eb0f2b0cb9fd863e064a91c55e035a26eb8f8846 Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Thu, 13 Oct 2016 14:51:51 -0300 Subject: [PATCH 05/21] removed assembly code --- math.h | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/math.h b/math.h index 73ff072..983b754 100644 --- a/math.h +++ b/math.h @@ -17,28 +17,6 @@ int fastMap1023toX(unsigned long x, int out_max) return (x * out_max) >> 10; } -/* -//Unsigned int assembly multiply, result in 20 clocks -//Need speed test -unsigned long hwdu16(unsigned int x, unsigned int y){ - unsigned long result; - asm("mul _y, _x"); //arg1l * arg2l - > - asm("movw _result+2, r0"); - asm("movf _y+1,_x+1");//arg1h * arg2h - > - asm("movw _result, r0"); - asm("mul _y, _x+1"); //arg1l * arg2h - > - asm("add _result+2,r0");//add cross - asm("adc _result+1,r1");//products - asm("clr r0"); - asm("adc _result,r0"); - asm("mul _y+1, _x"); //arg1h * arg2l - > - asm("add _result+2,r0");//add cross - asm("adc _result+1,r1");//products - asm("clr r0"); - asm("adc _result,r0"); - return(result); -}*/ - /* The following are all fast versions of specific divisions Ref: http://www.hackersdelight.org/divcMore.pdf From 6d8714e035a4209e24e17198d94612c9f4f705f6 Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Tue, 18 Oct 2016 15:58:25 -0200 Subject: [PATCH 06/21] Adition of float spark math Add some spark math, fix some code too --- globals.h | 1 + speeduino.ino | 24 +++++++++++++----------- table.ino | 46 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/globals.h b/globals.h index ccf3051..5348dee 100644 --- a/globals.h +++ b/globals.h @@ -150,6 +150,7 @@ struct statuses { volatile int loopsPerSecond; boolean launchingSoft; //True when in launch control soft limit mode boolean launchingHard; //True when in launch control hard limit mode + float adv; int freeRAM; //Helpful bitwise operations: diff --git a/speeduino.ino b/speeduino.ino index 776a9e4..2439039 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -201,18 +201,18 @@ void setup() //Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup if(configPage2.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; } else { coilHIGH = HIGH, coilLOW = LOW; } - digitalWrite(pinCoil1, coilLOW); - digitalWrite(pinCoil2, coilLOW); - digitalWrite(pinCoil3, coilLOW); - digitalWrite(pinCoil4, coilLOW); - digitalWrite(pinCoil5, coilLOW); + endCoil1Charge(); //digitalWrite(pinCoil1, coilLOW); + endCoil2Charge(); //digitalWrite(pinCoil2, coilLOW); + endCoil3Charge(); //digitalWrite(pinCoil3, coilLOW); + endCoil4Charge(); //digitalWrite(pinCoil4, coilLOW); + endCoil5Charge(); //digitalWrite(pinCoil5, coilLOW); //Similar for injectors, make sure they're turned off - digitalWrite(pinInjector1, LOW); - digitalWrite(pinInjector2, LOW); - digitalWrite(pinInjector3, LOW); - digitalWrite(pinInjector4, LOW); - digitalWrite(pinInjector5, LOW); + closeInjector1(); //digitalWrite(pinInjector1, HIGH); + closeInjector2(); //digitalWrite(pinInjector2, HIGH); + closeInjector3(); //digitalWrite(pinInjector3, HIGH); + closeInjector4(); //digitalWrite(pinInjector4, HIGH); + closeInjector5(); //digitalWrite(pinInjector5, HIGH); //Set the tacho output default state digitalWrite(pinTachOut, HIGH); @@ -924,6 +924,7 @@ void loop() currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value currentStatus.PW = PW_SD(req_fuel_uS, currentStatus.VE, currentStatus.MAP, currentStatus.corrections, inj_opentime_uS); currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance + currentStatus.adv = get3DTableValue2(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance } else { @@ -931,6 +932,7 @@ void loop() currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.TPS, currentStatus.RPM); //Perform lookup into fuel map for RPM vs TPS value currentStatus.PW = PW_AN(req_fuel_uS, currentStatus.VE, currentStatus.TPS, currentStatus.corrections, inj_opentime_uS); //Calculate pulsewidth using the Alpha-N algorithm (in uS) currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM); //As above, but for ignition advance + currentStatus.adv = get3DTableValue2(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance } //Check for fixed ignition angles @@ -1450,7 +1452,7 @@ void loop() inline void endCoil4Charge() { digitalWrite(pinCoil4, coilLOW); } inline void openInjector5() { digitalWrite(pinInjector5, HIGH); } - inline void closeInjector5() { digitalWrite(pinInjector5, LOW); } + inline void closeInjector5() { digitalWrite(pinInjector5, LOW); } inline void beginCoil5Charge() { digitalWrite(pinCoil5, coilHIGH); digitalWrite(pinTachOut, LOW); } inline void endCoil5Charge() { digitalWrite(pinCoil5, coilLOW); } diff --git a/table.ino b/table.ino index 6882c28..51de2bd 100644 --- a/table.ino +++ b/table.ino @@ -213,7 +213,51 @@ int table2D_getValue(struct table2D *fromTable, int X) } +//This function pulls a value from a 3D table given a target for X and Y coordinates. +//It fix a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf +float get3DTableValue2(struct table3D *fromTable, int Y, int X) +{ + float m, n, o ,p, q, r; + byte xMin, xMax; + byte yMin, yMax; + for (xMin = fromTable->xSize-1; xMin>=0; xMin--) if(X>fromTable->axisX[xMin]) break; + for (yMin = fromTable->ySize-1; yMin>=0; yMin--) if(Y>fromTable->axisY[yMin]) break; + if (xMin>fromTable->xSize-1) xMin = fromTable->xSize-1; //Overflow protection + if (yMin>fromTable->ySize-1) yMin = fromTable->ySize-1; //Overflow protection + + xMax = xMin + 1; + yMax = yMin + 1; + if (xMax>fromTable->xSize-1) xMax = fromTable->xSize-1; //Overflow protection + if (yMax>fromTable->ySize-1) yMax = fromTable->ySize-1; //Overflow protection + + p = float(X-fromTable->axisX[xMin]) / float(fromTable->axisX[xMax] - fromTable->axisX[xMin]); + q = float(Y-fromTable->axisY[yMin]) / float(fromTable->axisY[yMax] - fromTable->axisY[yMin]); + + /* On http://www.megamanual.com/v22manual/ve_tuner.pdf the interpolation image is fliped + Eg: | ve_turner.pdf | | should be | cause y and x axis is in that order + VE(1,1) VE(1,2) VE(2,1) VE(2,2) ^ + y| + | + VE(2,1) VE(2,2) VE(1,1) VE(1,2) +------------> x + + At this point we have the 4 corners of the map where the interpolated value will fall in + Eg: A=(yMax,xMin) B=(yMax,xMax) + + C=(yMin,xMin) D=(yMin,xMax) + */ + int A = fromTable->values[yMax][xMin]; + int B = fromTable->values[yMax][xMax]; + int C = fromTable->values[yMin][xMin]; + int D = fromTable->values[yMin][xMax]; + + m = (1.0-p) * (1.0-q); + n = p * (1-q); + o = (1-p) * q; + r = p * q; + + return ( (A * m) + (B * n) + (C * o) + (D * r) ); +} //This function pulls a value from a 3D table given a target for X and Y coordinates. //It performs a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf @@ -358,7 +402,7 @@ int get3DTableValue(struct table3D *fromTable, int Y, int X) int B = fromTable->values[yMin][xMax]; int C = fromTable->values[yMax][xMin]; int D = fromTable->values[yMax][xMax]; - + //Create some normalised position values //These are essentially percentages (between 0 and 1) of where the desired value falls between the nearest bins on each axis From 18319259a093cd8da2a32c008622d6b4c8a619cc Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Tue, 18 Oct 2016 16:30:26 -0200 Subject: [PATCH 07/21] digitalWriteFast.h inplementation --- auxiliaries.ino | 8 +- digitalWriteFast.h | 357 +++++++++++++++++++++++++++++++++++++++++++++ idle.ino | 32 ++-- speeduino.ino | 111 +++++++------- timers.ino | 10 +- utils.ino | 67 ++++----- 6 files changed, 472 insertions(+), 113 deletions(-) create mode 100644 digitalWriteFast.h diff --git a/auxiliaries.ino b/auxiliaries.ino index 4da2526..e97f7ea 100644 --- a/auxiliaries.ino +++ b/auxiliaries.ino @@ -12,13 +12,13 @@ void initialiseFan() { if(configPage4.fanInv == 1) {fanHIGH = LOW, fanLOW = HIGH; } else {fanHIGH = HIGH, fanLOW = LOW;} -digitalWrite(pinFan, fanLOW); //Initiallise program with the fan in the off state +digitalWriteFast(pinFan, fanLOW); //Initiallise program with the fan in the off state } void fanControl() { - if (currentStatus.coolant >= (configPage4.fanSP - CALIBRATION_TEMPERATURE_OFFSET)) { digitalWrite(pinFan,fanHIGH); } - else if (currentStatus.coolant <= (configPage4.fanSP - configPage4.fanHyster)) { digitalWrite(pinFan, fanLOW); } + if (currentStatus.coolant >= (configPage4.fanSP - CALIBRATION_TEMPERATURE_OFFSET)) { digitalWriteFast(pinFan,fanHIGH); } + else if (currentStatus.coolant <= (configPage4.fanSP - configPage4.fanHyster)) { digitalWriteFast(pinFan, fanLOW); } } void initialiseAuxPWM() @@ -47,7 +47,7 @@ void boostControl() { if(configPage3.boostEnabled) { - if(currentStatus.MAP < 100) { TIMSK1 &= ~(1 << OCIE1A); digitalWrite(pinBoost, LOW); return; } //Set duty to 0 and turn off timer compare + if(currentStatus.MAP < 100) { TIMSK1 &= ~(1 << OCIE1A); digitalWriteFast(pinBoost, LOW); return; } //Set duty to 0 and turn off timer compare boost_cl_target_boost = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM) * 2; //Boost target table is in kpa and divided by 2 boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); boostPID.Compute(); diff --git a/digitalWriteFast.h b/digitalWriteFast.h new file mode 100644 index 0000000..2f65f74 --- /dev/null +++ b/digitalWriteFast.h @@ -0,0 +1,357 @@ +/* + Optimized digital functions for AVR microcontrollers + by Watterott electronic (www.watterott.com) + based on http://code.google.com/p/digitalwritefast + */ + +#ifndef __digitalWriteFast_h_ +#define __digitalWriteFast_h_ 1 + +// general macros/defines +#ifndef BIT_READ +# define BIT_READ(value, bit) ((value) & (1UL << (bit))) +#endif +#ifndef BIT_SET +# define BIT_SET(value, bit) ((value) |= (1UL << (bit))) +#endif +#ifndef BIT_CLEAR +# define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit))) +#endif +#ifndef BIT_WRITE +# define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit)) +#endif + +#ifndef SWAP +#define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0) +#endif + +#ifndef DEC +# define DEC (10) +#endif +#ifndef HEX +# define HEX (16) +#endif +#ifndef OCT +# define OCT (8) +#endif +#ifndef BIN +# define BIN (2) +#endif + + +// workarounds for ARM microcontrollers +#if (!defined(__AVR__) || defined(ARDUINO_ARCH_SAM)) +#ifndef PROGMEM +# define PROGMEM +#endif +#ifndef PGM_P +# define PGM_P const char * +#endif +#ifndef PSTR +# define PSTR(str) (str) +#endif + +#ifndef memcpy_P +# define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#endif +#ifndef strcpy_P +# define strcpy_P(dst, src) strcpy((dst), (src)) +#endif +#ifndef strcat_P +# define strcat_P(dst, src) strcat((dst), (src)) +#endif +#ifndef strcmp_P +# define strcmp_P(a, b) strcmp((a), (b)) +#endif +#ifndef strcasecmp_P +# define strcasecmp_P(a, b) strcasecmp((a), (b)) +#endif +#ifndef strncmp_P +# define strncmp_P(a, b, n) strncmp((a), (b), (n)) +#endif +#ifndef strncasecmp_P +# define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n)) +#endif +#ifndef strstr_P +# define strstr_P(a, b) strstr((a), (b)) +#endif +#ifndef strlen_P +# define strlen_P(a) strlen((a)) +#endif +#ifndef sprintf_P +# define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) +#endif + +#ifndef pgm_read_byte +# define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#endif +#ifndef pgm_read_word +# define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#endif +#ifndef pgm_read_dword +# define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#endif + +#endif + + +// digital functions +//#ifndef digitalPinToPortReg +#define SPI_SW_SS_PIN (10) //SS on Uno (for software SPI) +#define SPI_SW_MOSI_PIN (11) //MOSI on Uno (for software SPI) +#define SPI_SW_MISO_PIN (12) //MISO on Uno (for software SPI) +#define SPI_SW_SCK_PIN (13) //SCK on Uno (for software SPI) + + +// --- Arduino Due --- +#if (defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__)) + +#define UART_RX_PIN (0) +#define UART_TX_PIN (1) + +#define I2C_SDA_PIN (20) +#define I2C_SCL_PIN (21) + +#define SPI_HW_SS_PIN (78) //SS0:77, SS1:87, SS2:86, SS3:78 +#define SPI_HW_MOSI_PIN (75) //75 +#define SPI_HW_MISO_PIN (74) //74 +#define SPI_HW_SCK_PIN (76) //76 + + +// --- Arduino Zero --- +#elif (defined(ARDUINO_SAM_ZERO) || defined(__SAMD21G18A__)) + +#define UART_RX_PIN (0) +#define UART_TX_PIN (1) + +#define I2C_SDA_PIN (16) +#define I2C_SCL_PIN (17) + +#define SPI_HW_SS_PIN (14) //14 +#define SPI_HW_MOSI_PIN (21) //21 +#define SPI_HW_MISO_PIN (18) //18 +#define SPI_HW_SCK_PIN (20) //20 + + +// --- Arduino Mega --- +#elif (defined(ARDUINO_AVR_MEGA) || \ + defined(ARDUINO_AVR_MEGA1280) || \ + defined(ARDUINO_AVR_MEGA2560) || \ + defined(__AVR_ATmega1280__) || \ + defined(__AVR_ATmega1281__) || \ + defined(__AVR_ATmega2560__) || \ + defined(__AVR_ATmega2561__)) + +#define UART_RX_PIN (0) //PE0 +#define UART_TX_PIN (1) //PE1 + +#define I2C_SDA_PIN (20) +#define I2C_SCL_PIN (21) + +#define SPI_HW_SS_PIN (53) //PB0 +#define SPI_HW_MOSI_PIN (51) //PB2 +#define SPI_HW_MISO_PIN (50) //PB3 +#define SPI_HW_SCK_PIN (52) //PB1 + +#define __digitalPinToPortReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PORTA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ +(((P) >= 30 && (P) <= 37) ? &PORTC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \ +(((P) >= 54 && (P) <= 61) ? &PORTF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ +(((P) == 14 || (P) == 15) ? &PORTJ : \ +(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) + +#define __digitalPinToDDRReg(P) \ +(((P) >= 22 && (P) <= 29) ? &DDRA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ +(((P) >= 30 && (P) <= 37) ? &DDRC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \ +(((P) >= 54 && (P) <= 61) ? &DDRF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ +(((P) == 14 || (P) == 15) ? &DDRJ : \ +(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) + +#define __digitalPinToPINReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PINA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ +(((P) >= 30 && (P) <= 37) ? &PINC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \ +(((P) >= 54 && (P) <= 61) ? &PINF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \ +(((P) == 14 || (P) == 15) ? &PINJ : \ +(((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) + +#define __digitalPinToBit(P) \ +(((P) >= 7 && (P) <= 9) ? (P) - 3 : \ +(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ +(((P) >= 22 && (P) <= 29) ? (P) - 22 : \ +(((P) >= 30 && (P) <= 37) ? 37 - (P) : \ +(((P) >= 39 && (P) <= 41) ? 41 - (P) : \ +(((P) >= 42 && (P) <= 49) ? 49 - (P) : \ +(((P) >= 50 && (P) <= 53) ? 53 - (P) : \ +(((P) >= 54 && (P) <= 61) ? (P) - 54 : \ +(((P) >= 62 && (P) <= 69) ? (P) - 62 : \ +(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ +(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ +(((P) == 19) ? 2 : \ +(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ +(((P) == 2) ? 4 : \ +(((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) + + +// --- Arduino 644 --- +#elif (defined(__AVR_ATmega644__) || \ + defined(__AVR_ATmega644P__)) + +#define UART_RX_PIN (8) //PD0 +#define UART_TX_PIN (9) //PD1 + +#define I2C_SDA_PIN (17) //PC1 +#define I2C_SCL_PIN (16) //PC0 + +#define SPI_HW_SS_PIN (4) //PB4 +#define SPI_HW_MOSI_PIN (5) //PB5 +#define SPI_HW_MISO_PIN (6) //PB6 +#define SPI_HW_SCK_PIN (7) //PB7 + +#define __digitalPinToPortReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA))) +#define __digitalPinToDDRReg(P) \ +(((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 8 && (P) <= 15) ? &DDRC : &DDRA))) +#define __digitalPinToPINReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 8 && (P) <= 15) ? &PINC : &PINA))) +#define __digitalPinToBit(P) \ +(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24))) + + +// --- Arduino Leonardo --- +#elif (defined(ARDUINO_AVR_LEONARDO) || \ + defined(__AVR_ATmega16U4__) || \ + defined(__AVR_ATmega32U4__)) + +#define UART_RX_PIN (0) //PD2 +#define UART_TX_PIN (1) //PD3 + +#define I2C_SDA_PIN (2) //PD1 +#define I2C_SCL_PIN (3) //PD0 + +#define SPI_HW_SS_PIN (17) //PB0 +#define SPI_HW_MOSI_PIN (16) //PB2 +#define SPI_HW_MISO_PIN (14) //PB3 +#define SPI_HW_SCK_PIN (15) //PB1 + +#define __digitalPinToPortReg(P) \ +((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF : (((P) == 7) ? &PORTE : &PORTB))) +#define __digitalPinToDDRReg(P) \ +((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF : (((P) == 7) ? &DDRE : &DDRB))) +#define __digitalPinToPINReg(P) \ +((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF : (((P) == 7) ? &PINE : &PINB))) +#define __digitalPinToBit(P) \ +(((P) >= 8 && (P) <= 11) ? (P) - 4 : (((P) >= 18 && (P) <= 21) ? 25 - (P) : (((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : (((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : (((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 ))))))))))))))))))) + + +// --- Arduino Uno --- +#elif (defined(ARDUINO_AVR_UNO) || \ + defined(ARDUINO_AVR_DUEMILANOVE) || \ + defined(__AVR_ATmega328__) || \ + defined(__AVR_ATmega328P__) || \ + defined(__AVR_ATmega328PB__)) + +#define UART_RX_PIN (0) //PD0 +#define UART_TX_PIN (1) //PD1 + +#define I2C_SDA_PIN (18) //A4 +#define I2C_SCL_PIN (19) //A5 + +#define SPI_HW_SS_PIN (10) //PB0 +#define SPI_HW_MOSI_PIN (11) //PB2 +#define SPI_HW_MISO_PIN (12) //PB3 +#define SPI_HW_SCK_PIN (13) //PB1 + +#if defined(__AVR_ATmega328PB__) +#define __digitalPinToPortReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE))) +#define __digitalPinToDDRReg(P) \ +(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE))) +#define __digitalPinToPINReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE))) +#define __digitalPinToBit(P) \ +(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22)))) +#else +#define __digitalPinToPortReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC)) +#define __digitalPinToDDRReg(P) \ +(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC)) +#define __digitalPinToPINReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC)) +#define __digitalPinToBit(P) \ +(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) +#endif + + +// --- Other --- +#else + +#define I2C_SDA_PIN SDA +#define I2C_SCL_PIN SCL + +#define SPI_HW_SS_PIN SS +#define SPI_HW_MOSI_PIN MOSI +#define SPI_HW_MISO_PIN MISO +#define SPI_HW_SCK_PIN SCK + + +#endif +//#endif //#ifndef digitalPinToPortReg + + +#ifndef digitalWriteFast +#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) +#define digitalWriteFast(P, V) \ +if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ + BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \ +} else { \ + digitalWrite((P), (V)); \ +} +#else +#define digitalWriteFast digitalWrite +#endif +#endif + + +#ifndef pinModeFast +#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) +#define pinModeFast(P, V) \ +if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ + BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \ +} else { \ + pinMode((P), (V)); \ +} +#else +#define pinModeFast pinMode +#endif +#endif + + +#ifndef digitalReadFast +#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) +#define digitalReadFast(P) ( (int) __digitalReadFast((P)) ) +#define __digitalReadFast(P ) \ + (__builtin_constant_p(P) ) ? ( \ + ( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \ + digitalRead((P)) +#else +#define digitalReadFast digitalRead +#endif +#endif + +#endif //__digitalWriteFast_h_ + diff --git a/idle.ino b/idle.ino index 4d75065..3297070 100644 --- a/idle.ino +++ b/idle.ino @@ -32,7 +32,7 @@ void initialiseIdle() //Case 1 is on/off idle control if (currentStatus.coolant < configPage4.iacFastTemp) { - digitalWrite(pinIdle1, HIGH); + digitalWriteFast(pinIdle1, HIGH); } break; @@ -122,10 +122,10 @@ void idleControl() case 1: //Case 1 is on/off idle control if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp) //All temps are offset by 40 degrees { - digitalWrite(pinIdle1, HIGH); + digitalWriteFast(pinIdle1, HIGH); idleOn = true; } - else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; } + else if (idleOn) { digitalWriteFast(pinIdle1, LOW); idleOn = false; } break; case 2: //Case 2 is PWM open loop @@ -141,7 +141,7 @@ void idleControl() { //Standard running currentStatus.idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees - if( currentStatus.idleDuty == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); break; } + if( currentStatus.idleDuty == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWriteFast(pinIdle1, LOW); break; } TIMSK4 |= (1 << OCIE4C); //Turn on the C compare unit (ie turn on the interrupt) idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count); idleOn = true; @@ -154,7 +154,7 @@ void idleControl() //idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD); idlePID.Compute(); - if( idle_pwm_target_value == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); } + if( idle_pwm_target_value == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWriteFast(pinIdle1, LOW); } else{ TIMSK4 |= (1 << OCIE4C); } //Turn on the C compare unit (ie turn on the interrupt) //idle_pwm_target_value = 104; break; @@ -168,7 +168,7 @@ void idleControl() if(idleStepper.stepperStatus == STEPPING) { //Means we're currently in a step, but it needs to be turned off - digitalWrite(pinStepperStep, LOW); //Turn off the step + digitalWriteFast(pinStepperStep, LOW); //Turn off the step idleStepper.stepStartTime = micros(); idleStepper.stepperStatus = COOLING; //'Cooling' is the time the stepper needs to sit in LOW state before the next step can be made return; @@ -192,10 +192,10 @@ void idleControl() //Currently cranking. Use the cranking table idleStepper.targetIdleStep = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check - else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards - else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards + else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards + else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards - digitalWrite(pinStepperStep, HIGH); + digitalWriteFast(pinStepperStep, HIGH); idleStepper.stepStartTime = micros(); idleStepper.stepperStatus = STEPPING; idleOn = true; @@ -205,10 +205,10 @@ void idleControl() //Standard running idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check - else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards - else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards + else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards + else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards - digitalWrite(pinStepperStep, HIGH); + digitalWriteFast(pinStepperStep, HIGH); idleStepper.stepStartTime = micros(); idleStepper.stepperStatus = STEPPING; idleOn = true; @@ -224,15 +224,15 @@ A simple function to home the stepper motor (If in use) void homeStepper() { //Need to 'home' the stepper on startup - digitalWrite(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards + digitalWriteFast(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards for(int x=0; x < (configPage4.iacStepHome * 3); x++) //Step counts are divided by 3 in TS. Multiply back out here { - digitalWrite(pinStepperStep, HIGH); + digitalWriteFast(pinStepperStep, HIGH); delayMicroseconds(iacStepTime); - digitalWrite(pinStepperStep, LOW); + digitalWriteFast(pinStepperStep, LOW); delayMicroseconds(iacStepTime); } - digitalWrite(pinStepperDir, STEPPER_FORWARD); + digitalWriteFast(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep = 0; idleStepper.targetIdleStep = 0; idleStepper.stepperStatus = SOFF; diff --git a/speeduino.ino b/speeduino.ino index 2439039..575d8a7 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //************************************************************************************************** #include "globals.h" +#include "digitalWriteFast.h" #include "utils.h" #include "table.h" #include "scheduler.h" @@ -201,21 +202,21 @@ void setup() //Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup if(configPage2.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; } else { coilHIGH = HIGH, coilLOW = LOW; } - endCoil1Charge(); //digitalWrite(pinCoil1, coilLOW); - endCoil2Charge(); //digitalWrite(pinCoil2, coilLOW); - endCoil3Charge(); //digitalWrite(pinCoil3, coilLOW); - endCoil4Charge(); //digitalWrite(pinCoil4, coilLOW); - endCoil5Charge(); //digitalWrite(pinCoil5, coilLOW); + endCoil1Charge(); //digitalWriteFast(pinCoil1, coilLOW); + endCoil2Charge(); //digitalWriteFast(pinCoil2, coilLOW); + endCoil3Charge(); //digitalWriteFast(pinCoil3, coilLOW); + endCoil4Charge(); //digitalWriteFast(pinCoil4, coilLOW); + endCoil5Charge(); //digitalWriteFast(pinCoil5, coilLOW); //Similar for injectors, make sure they're turned off - closeInjector1(); //digitalWrite(pinInjector1, HIGH); - closeInjector2(); //digitalWrite(pinInjector2, HIGH); - closeInjector3(); //digitalWrite(pinInjector3, HIGH); - closeInjector4(); //digitalWrite(pinInjector4, HIGH); - closeInjector5(); //digitalWrite(pinInjector5, HIGH); + closeInjector1(); //digitalWriteFast(pinInjector1, HIGH); + closeInjector2(); //digitalWriteFast(pinInjector2, HIGH); + closeInjector3(); //digitalWriteFast(pinInjector3, HIGH); + closeInjector4(); //digitalWriteFast(pinInjector4, HIGH); + closeInjector5(); //digitalWriteFast(pinInjector5, HIGH); //Set the tacho output default state - digitalWrite(pinTachOut, HIGH); + digitalWriteFast(pinTachOut, HIGH); //Lookup the current MAP reading for barometric pressure readMAP(); @@ -284,10 +285,10 @@ void setup() triggerInterrupt2 = 2; break; } - pinMode(pinTrigger, INPUT); - pinMode(pinTrigger2, INPUT); - pinMode(pinTrigger3, INPUT); - //digitalWrite(pinTrigger, HIGH); + pinModeFast(pinTrigger, INPUT); + pinModeFast(pinTrigger2, INPUT); + pinModeFast(pinTrigger3, INPUT); + //digitalWriteFast(pinTrigger, HIGH); //Set the trigger function based on the decoder in the config @@ -754,7 +755,7 @@ void setup() } //Begin priming the fuel pump. This is turned off in the low resolution, 1s interrupt in timers.ino - digitalWrite(pinFuelPump, HIGH); + digitalWriteFast(pinFuelPump, HIGH); fuelPumpOn = true; //Perform the priming pulses. Set these to run at an arbitrary time in the future (100us). The prime pulse value is in ms*10, so need to multiple by 100 to get to uS setFuelSchedule1(openInjector1and4, 100, (unsigned long)(configPage1.primePulse * 100), closeInjector1and4); @@ -797,7 +798,7 @@ void loop() { int lastRPM = currentStatus.RPM; //Need to record this for rpmDOT calculation currentStatus.RPM = currentStatus.longRPM = getRPM(); //Long RPM is included here - if(fuelPumpOn == false) { digitalWrite(pinFuelPump, HIGH); fuelPumpOn = true; } //Check if the fuel pump is on and turn it on if it isn't. + if(fuelPumpOn == false) { digitalWriteFast(pinFuelPump, HIGH); fuelPumpOn = true; } //Check if the fuel pump is on and turn it on if it isn't. currentStatus.rpmDOT = ldiv(1000000, (currentLoopTime - previousLoopTime)).quot * (currentStatus.RPM - lastRPM); //This is the RPM per second that the engine has accelerated/decelleratedin the last loop } else @@ -815,9 +816,9 @@ void loop() currentStatus.rpmDOT = 0; ignitionOn = false; fuelOn = false; - if (fpPrimed) { digitalWrite(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete + if (fpPrimed) { digitalWriteFast(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete fuelPumpOn = false; - TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); //Turns off the idle control PWM. This REALLY needs to be cleaned up into a general PWM controller class + TIMSK4 &= ~(1 << OCIE4C); digitalWriteFast(pinIdle1, LOW); //Turns off the idle control PWM. This REALLY needs to be cleaned up into a general PWM controller class } //Uncomment the following for testing @@ -837,8 +838,8 @@ void loop() //Check for launching (clutch) can be done around here too bool launchTrigger; - if(configPage3.launchHiLo) { launchTrigger = digitalRead(pinLaunch); } - else { launchTrigger = !digitalRead(pinLaunch); } + if(configPage3.launchHiLo) { launchTrigger = digitalReadFast(pinLaunch); } + else { launchTrigger = !digitalReadFast(pinLaunch); } if (configPage3.launchEnabled && launchTrigger && (currentStatus.RPM > ((unsigned int)(configPage3.lnchSoftLim) * 100)) ) { currentStatus.launchingSoft = true; BIT_SET(currentStatus.spark, BIT_SPARK_SLAUNCH); } //SoftCut rev limit for 2-step launch control. else { currentStatus.launchingSoft = false; BIT_CLEAR(currentStatus.spark, BIT_SPARK_SLAUNCH); } if (configPage3.launchEnabled && launchTrigger && (currentStatus.RPM > ((unsigned int)(configPage3.lnchHardLim) * 100)) ) { currentStatus.launchingHard = true; BIT_SET(currentStatus.spark, BIT_SPARK_HLAUNCH); } //HardCut rev limit for 2-step launch control. @@ -900,7 +901,7 @@ void loop() if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); //clears the engine cranking bit - if(configPage2.ignBypassEnabled) { digitalWrite(pinIgnBypass, HIGH); } + if(configPage2.ignBypassEnabled) { digitalWriteFast(pinIgnBypass, HIGH); } } } else @@ -908,7 +909,7 @@ void loop() BIT_SET(currentStatus.engine, BIT_ENGINE_CRANK); BIT_CLEAR(currentStatus.engine, BIT_ENGINE_RUN); currentStatus.runSecs = 0; //We're cranking (hopefully), so reset the engine run time to prompt ASE. - if(configPage2.ignBypassEnabled) { digitalWrite(pinIgnBypass, LOW); } + if(configPage2.ignBypassEnabled) { digitalWriteFast(pinIgnBypass, LOW); } } //END SETTING STATUSES @@ -1412,63 +1413,63 @@ void loop() void openInjector1() { *inj1_pin_port |= (inj1_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1); } void closeInjector1() { *inj1_pin_port &= ~(inj1_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1); } - void beginCoil1Charge() { *ign1_pin_port |= (ign1_pin_mask); BIT_SET(currentStatus.spark, 0); digitalWrite(pinTachOut, LOW); } + void beginCoil1Charge() { *ign1_pin_port |= (ign1_pin_mask); BIT_SET(currentStatus.spark, 0); digitalWriteFast(pinTachOut, LOW); } void endCoil1Charge() { *ign1_pin_port &= ~(ign1_pin_mask); BIT_CLEAR(currentStatus.spark, 0); } void openInjector2() { *inj2_pin_port |= (inj2_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2); } void closeInjector2() { *inj2_pin_port &= ~(inj2_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ2); } - void beginCoil2Charge() { *ign2_pin_port |= (ign2_pin_mask); BIT_SET(currentStatus.spark, 1); digitalWrite(pinTachOut, LOW); } + void beginCoil2Charge() { *ign2_pin_port |= (ign2_pin_mask); BIT_SET(currentStatus.spark, 1); digitalWriteFast(pinTachOut, LOW); } void endCoil2Charge() { *ign2_pin_port &= ~(ign2_pin_mask); BIT_CLEAR(currentStatus.spark, 1);} void openInjector3() { *inj3_pin_port |= (inj3_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ3); } void closeInjector3() { *inj3_pin_port &= ~(inj3_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ3); } - void beginCoil3Charge() { *ign3_pin_port |= (ign3_pin_mask); BIT_SET(currentStatus.spark, 2); digitalWrite(pinTachOut, LOW); } + void beginCoil3Charge() { *ign3_pin_port |= (ign3_pin_mask); BIT_SET(currentStatus.spark, 2); digitalWriteFast(pinTachOut, LOW); } void endCoil3Charge() { *ign3_pin_port &= ~(ign3_pin_mask); BIT_CLEAR(currentStatus.spark, 2);} void openInjector4() { *inj4_pin_port |= (inj4_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ4); } void closeInjector4() { *inj4_pin_port &= ~(inj4_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ4); } - void beginCoil4Charge() { *ign4_pin_port |= (ign4_pin_mask); BIT_SET(currentStatus.spark, 3); digitalWrite(pinTachOut, LOW); } + void beginCoil4Charge() { *ign4_pin_port |= (ign4_pin_mask); BIT_SET(currentStatus.spark, 3); digitalWriteFast(pinTachOut, LOW); } void endCoil4Charge() { *ign4_pin_port &= ~(ign4_pin_mask); BIT_CLEAR(currentStatus.spark, 3);} #else */ - inline void openInjector1() { digitalWrite(pinInjector1, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1); } - inline void closeInjector1() { digitalWrite(pinInjector1, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1); } - inline void beginCoil1Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinTachOut, LOW); } - inline void endCoil1Charge() { digitalWrite(pinCoil1, coilLOW); } + inline void openInjector1() { digitalWriteFast(pinInjector1, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1); } + inline void closeInjector1() { digitalWriteFast(pinInjector1, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1); } + inline void beginCoil1Charge() { digitalWriteFast(pinCoil1, coilHIGH); digitalWriteFast(pinTachOut, LOW); } + inline void endCoil1Charge() { digitalWriteFast(pinCoil1, coilLOW); } - inline void openInjector2() { digitalWrite(pinInjector2, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2); } //Sets the relevant pin HIGH and changes the current status bit for injector 2 (2nd bit of currentStatus.squirt) - inline void closeInjector2() { digitalWrite(pinInjector2, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ2); } - inline void beginCoil2Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pinTachOut, LOW); } - inline void endCoil2Charge() { digitalWrite(pinCoil2, coilLOW); } + inline void openInjector2() { digitalWriteFast(pinInjector2, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2); } //Sets the relevant pin HIGH and changes the current status bit for injector 2 (2nd bit of currentStatus.squirt) + inline void closeInjector2() { digitalWriteFast(pinInjector2, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ2); } + inline void beginCoil2Charge() { digitalWriteFast(pinCoil2, coilHIGH); digitalWriteFast(pinTachOut, LOW); } + inline void endCoil2Charge() { digitalWriteFast(pinCoil2, coilLOW); } - inline void openInjector3() { digitalWrite(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ3); } //Sets the relevant pin HIGH and changes the current status bit for injector 3 (3rd bit of currentStatus.squirt) - inline void closeInjector3() { digitalWrite(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ3); } - inline void beginCoil3Charge() { digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); } - inline void endCoil3Charge() { digitalWrite(pinCoil3, coilLOW); } + inline void openInjector3() { digitalWriteFast(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ3); } //Sets the relevant pin HIGH and changes the current status bit for injector 3 (3rd bit of currentStatus.squirt) + inline void closeInjector3() { digitalWriteFast(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ3); } + inline void beginCoil3Charge() { digitalWriteFast(pinCoil3, coilHIGH); digitalWriteFast(pinTachOut, LOW); } + inline void endCoil3Charge() { digitalWriteFast(pinCoil3, coilLOW); } - inline void openInjector4() { digitalWrite(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ4); } //Sets the relevant pin HIGH and changes the current status bit for injector 4 (4th bit of currentStatus.squirt) - inline void closeInjector4() { digitalWrite(pinInjector4, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ4); } - inline void beginCoil4Charge() { digitalWrite(pinCoil4, coilHIGH); digitalWrite(pinTachOut, LOW); } - inline void endCoil4Charge() { digitalWrite(pinCoil4, coilLOW); } + inline void openInjector4() { digitalWriteFast(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ4); } //Sets the relevant pin HIGH and changes the current status bit for injector 4 (4th bit of currentStatus.squirt) + inline void closeInjector4() { digitalWriteFast(pinInjector4, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ4); } + inline void beginCoil4Charge() { digitalWriteFast(pinCoil4, coilHIGH); digitalWriteFast(pinTachOut, LOW); } + inline void endCoil4Charge() { digitalWriteFast(pinCoil4, coilLOW); } - inline void openInjector5() { digitalWrite(pinInjector5, HIGH); } - inline void closeInjector5() { digitalWrite(pinInjector5, LOW); } - inline void beginCoil5Charge() { digitalWrite(pinCoil5, coilHIGH); digitalWrite(pinTachOut, LOW); } - inline void endCoil5Charge() { digitalWrite(pinCoil5, coilLOW); } + inline void openInjector5() { digitalWriteFast(pinInjector5, HIGH); } + inline void closeInjector5() { digitalWriteFast(pinInjector5, LOW); } + inline void beginCoil5Charge() { digitalWriteFast(pinCoil5, coilHIGH); digitalWriteFast(pinTachOut, LOW); } + inline void endCoil5Charge() { digitalWriteFast(pinCoil5, coilLOW); } //#endif //Combination functions for semi-sequential injection -void openInjector1and4() { digitalWrite(pinInjector1, HIGH); digitalWrite(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, 0); } -void closeInjector1and4() { digitalWrite(pinInjector1, LOW); digitalWrite(pinInjector4, LOW);BIT_CLEAR(currentStatus.squirt, 0); } -void openInjector2and3() { digitalWrite(pinInjector2, HIGH); digitalWrite(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, 1); } -void closeInjector2and3() { digitalWrite(pinInjector2, LOW); digitalWrite(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, 1); } +void openInjector1and4() { digitalWriteFast(pinInjector1, HIGH); digitalWriteFast(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, 0); } +void closeInjector1and4() { digitalWriteFast(pinInjector1, LOW); digitalWriteFast(pinInjector4, LOW);BIT_CLEAR(currentStatus.squirt, 0); } +void openInjector2and3() { digitalWriteFast(pinInjector2, HIGH); digitalWriteFast(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, 1); } +void closeInjector2and3() { digitalWriteFast(pinInjector2, LOW); digitalWriteFast(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, 1); } //As above but for ignition (Wasted COP mode) -void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); } -void endCoil1and3Charge() { digitalWrite(pinCoil1, coilLOW); digitalWrite(pinCoil3, coilLOW); } -void beginCoil2and4Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pinCoil4, coilHIGH); digitalWrite(pinTachOut, LOW); } -void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoil4, coilLOW); } +void beginCoil1and3Charge() { digitalWriteFast(pinCoil1, coilHIGH); digitalWriteFast(pinCoil3, coilHIGH); digitalWriteFast(pinTachOut, LOW); } +void endCoil1and3Charge() { digitalWriteFast(pinCoil1, coilLOW); digitalWriteFast(pinCoil3, coilLOW); } +void beginCoil2and4Charge() { digitalWriteFast(pinCoil2, coilHIGH); digitalWriteFast(pinCoil4, coilHIGH); digitalWriteFast(pinTachOut, LOW); } +void endCoil2and4Charge() { digitalWriteFast(pinCoil2, coilLOW); digitalWriteFast(pinCoil4, coilLOW); } void nullCallback() { return; } diff --git a/timers.ino b/timers.ino index e03475e..ccdf1aa 100644 --- a/timers.ino +++ b/timers.ino @@ -47,10 +47,10 @@ void timer2Overflowinterrupt() //Most ARM chips can simply call a function targetOverdwellTime = micros() - (1000 * configPage2.dwellLimit); //Set a target time in the past that all coil charging must have begun after. If the coil charge began before this time, it's been running too long targetTachoPulseTime = micros() - (1500); //Check first whether each spark output is currently on. Only check it's dwell time if it is - if(ignitionSchedule1.Status == RUNNING) { if(ignitionSchedule1.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil1Charge(); } if(ignitionSchedule1.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } - if(ignitionSchedule2.Status == RUNNING) { if(ignitionSchedule2.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil2Charge(); } if(ignitionSchedule2.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } - if(ignitionSchedule3.Status == RUNNING) { if(ignitionSchedule3.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil3Charge(); } if(ignitionSchedule3.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } - if(ignitionSchedule4.Status == RUNNING) { if(ignitionSchedule4.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil4Charge(); } if(ignitionSchedule4.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } + if(ignitionSchedule1.Status == RUNNING) { if(ignitionSchedule1.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil1Charge(); } if(ignitionSchedule1.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } + if(ignitionSchedule2.Status == RUNNING) { if(ignitionSchedule2.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil2Charge(); } if(ignitionSchedule2.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } + if(ignitionSchedule3.Status == RUNNING) { if(ignitionSchedule3.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil3Charge(); } if(ignitionSchedule3.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } + if(ignitionSchedule4.Status == RUNNING) { if(ignitionSchedule4.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil4Charge(); } if(ignitionSchedule4.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } //Loop executed every 250ms loop (1ms x 250 = 250ms) //Anything inside this if statement will run every 250ms. @@ -92,7 +92,7 @@ void timer2Overflowinterrupt() //Most ARM chips can simply call a function if(currentStatus.secl >= configPage1.fpPrime) { fpPrimed = true; //Mark the priming as being completed - if(currentStatus.RPM == 0) { digitalWrite(pinFuelPump, LOW); fuelPumpOn = false; } //If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running + if(currentStatus.RPM == 0) { digitalWriteFast(pinFuelPump, LOW); fuelPumpOn = false; } //If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running } } //************************************************************************************************************************************************** diff --git a/utils.ino b/utils.ino index b0c07fc..ff8f6cf 100644 --- a/utils.ino +++ b/utils.ino @@ -8,6 +8,7 @@ A full copy of the license may be found in the projects root directory /* Returns how much free dynamic memory exists (between heap and stack) */ +#include "digitalWriteFast.h" #include "utils.h" int freeRam () @@ -311,22 +312,22 @@ void setPinMapping(byte boardID) if(configPage1.tachoPin != 0) { pinTachOut = configPage1.tachoPin; } //Finally, set the relevant pin modes for outputs - pinMode(pinCoil1, OUTPUT); - pinMode(pinCoil2, OUTPUT); - pinMode(pinCoil3, OUTPUT); - pinMode(pinCoil4, OUTPUT); - pinMode(pinCoil5, OUTPUT); - pinMode(pinInjector1, OUTPUT); - pinMode(pinInjector2, OUTPUT); - pinMode(pinInjector3, OUTPUT); - pinMode(pinInjector4, OUTPUT); - pinMode(pinInjector5, OUTPUT); - pinMode(pinTachOut, OUTPUT); - pinMode(pinIdle1, OUTPUT); - pinMode(pinIdle2, OUTPUT); - pinMode(pinFuelPump, OUTPUT); - pinMode(pinIgnBypass, OUTPUT); - pinMode(pinFan, OUTPUT); + pinModeFast(pinCoil1, OUTPUT); + pinModeFast(pinCoil2, OUTPUT); + pinModeFast(pinCoil3, OUTPUT); + pinModeFast(pinCoil4, OUTPUT); + pinModeFast(pinCoil5, OUTPUT); + pinModeFast(pinInjector1, OUTPUT); + pinModeFast(pinInjector2, OUTPUT); + pinModeFast(pinInjector3, OUTPUT); + pinModeFast(pinInjector4, OUTPUT); + pinModeFast(pinInjector5, OUTPUT); + pinModeFast(pinTachOut, OUTPUT); + pinModeFast(pinIdle1, OUTPUT); + pinModeFast(pinIdle2, OUTPUT); + pinModeFast(pinFuelPump, OUTPUT); + pinModeFast(pinIgnBypass, OUTPUT); + pinModeFast(pinFan, OUTPUT); inj1_pin_port = portOutputRegister(digitalPinToPort(pinInjector1)); inj1_pin_mask = digitalPinToBitMask(pinInjector1); @@ -351,25 +352,25 @@ void setPinMapping(byte boardID) ign5_pin_mask = digitalPinToBitMask(pinCoil5); //And for inputs - pinMode(pinMAP, INPUT); - pinMode(pinO2, INPUT); - pinMode(pinO2_2, INPUT); - pinMode(pinTPS, INPUT); - pinMode(pinIAT, INPUT); - pinMode(pinCLT, INPUT); - pinMode(pinBat, INPUT); - pinMode(pinTrigger, INPUT); - pinMode(pinTrigger2, INPUT); - pinMode(pinTrigger3, INPUT); - pinMode(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup -// pinMode(pinLaunch, INPUT_PULLUP); //This should work for both NO and NC grounding switches - if (configPage3.lnchPullRes) { pinMode(pinLaunch, INPUT_PULLUP); } - else { pinMode(pinLaunch, INPUT); } //If Launch Pull Resistor is not set make input float. + pinModeFast(pinMAP, INPUT); + pinModeFast(pinO2, INPUT); + pinModeFast(pinO2_2, INPUT); + pinModeFast(pinTPS, INPUT); + pinModeFast(pinIAT, INPUT); + pinModeFast(pinCLT, INPUT); + pinModeFast(pinBat, INPUT); + pinModeFast(pinTrigger, INPUT); + pinModeFast(pinTrigger2, INPUT); + pinModeFast(pinTrigger3, INPUT); + pinModeFast(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup +// pinModeFast(pinLaunch, INPUT_PULLUP); //This should work for both NO and NC grounding switches + if (configPage3.lnchPullRes) { pinModeFast(pinLaunch, INPUT_PULLUP); } + else { pinModeFast(pinLaunch, INPUT); } //If Launch Pull Resistor is not set make input float. //Set default values - digitalWrite(pinMAP, HIGH); - //digitalWrite(pinO2, LOW); - digitalWrite(pinTPS, LOW); + digitalWriteFast(pinMAP, HIGH); + //digitalWriteFast(pinO2, LOW); + digitalWriteFast(pinTPS, LOW); } /* From f77488899667088f5dd30b5090b29bb12510abbe Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Fri, 21 Oct 2016 12:14:01 -0200 Subject: [PATCH 08/21] Revert "digitalWriteFast.h inplementation" This reverts commit 18319259a093cd8da2a32c008622d6b4c8a619cc. --- auxiliaries.ino | 8 +- digitalWriteFast.h | 357 --------------------------------------------- idle.ino | 32 ++-- speeduino.ino | 111 +++++++------- timers.ino | 10 +- utils.ino | 67 +++++---- 6 files changed, 113 insertions(+), 472 deletions(-) delete mode 100644 digitalWriteFast.h diff --git a/auxiliaries.ino b/auxiliaries.ino index e97f7ea..4da2526 100644 --- a/auxiliaries.ino +++ b/auxiliaries.ino @@ -12,13 +12,13 @@ void initialiseFan() { if(configPage4.fanInv == 1) {fanHIGH = LOW, fanLOW = HIGH; } else {fanHIGH = HIGH, fanLOW = LOW;} -digitalWriteFast(pinFan, fanLOW); //Initiallise program with the fan in the off state +digitalWrite(pinFan, fanLOW); //Initiallise program with the fan in the off state } void fanControl() { - if (currentStatus.coolant >= (configPage4.fanSP - CALIBRATION_TEMPERATURE_OFFSET)) { digitalWriteFast(pinFan,fanHIGH); } - else if (currentStatus.coolant <= (configPage4.fanSP - configPage4.fanHyster)) { digitalWriteFast(pinFan, fanLOW); } + if (currentStatus.coolant >= (configPage4.fanSP - CALIBRATION_TEMPERATURE_OFFSET)) { digitalWrite(pinFan,fanHIGH); } + else if (currentStatus.coolant <= (configPage4.fanSP - configPage4.fanHyster)) { digitalWrite(pinFan, fanLOW); } } void initialiseAuxPWM() @@ -47,7 +47,7 @@ void boostControl() { if(configPage3.boostEnabled) { - if(currentStatus.MAP < 100) { TIMSK1 &= ~(1 << OCIE1A); digitalWriteFast(pinBoost, LOW); return; } //Set duty to 0 and turn off timer compare + if(currentStatus.MAP < 100) { TIMSK1 &= ~(1 << OCIE1A); digitalWrite(pinBoost, LOW); return; } //Set duty to 0 and turn off timer compare boost_cl_target_boost = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM) * 2; //Boost target table is in kpa and divided by 2 boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); boostPID.Compute(); diff --git a/digitalWriteFast.h b/digitalWriteFast.h deleted file mode 100644 index 2f65f74..0000000 --- a/digitalWriteFast.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - Optimized digital functions for AVR microcontrollers - by Watterott electronic (www.watterott.com) - based on http://code.google.com/p/digitalwritefast - */ - -#ifndef __digitalWriteFast_h_ -#define __digitalWriteFast_h_ 1 - -// general macros/defines -#ifndef BIT_READ -# define BIT_READ(value, bit) ((value) & (1UL << (bit))) -#endif -#ifndef BIT_SET -# define BIT_SET(value, bit) ((value) |= (1UL << (bit))) -#endif -#ifndef BIT_CLEAR -# define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit))) -#endif -#ifndef BIT_WRITE -# define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit)) -#endif - -#ifndef SWAP -#define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0) -#endif - -#ifndef DEC -# define DEC (10) -#endif -#ifndef HEX -# define HEX (16) -#endif -#ifndef OCT -# define OCT (8) -#endif -#ifndef BIN -# define BIN (2) -#endif - - -// workarounds for ARM microcontrollers -#if (!defined(__AVR__) || defined(ARDUINO_ARCH_SAM)) -#ifndef PROGMEM -# define PROGMEM -#endif -#ifndef PGM_P -# define PGM_P const char * -#endif -#ifndef PSTR -# define PSTR(str) (str) -#endif - -#ifndef memcpy_P -# define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) -#endif -#ifndef strcpy_P -# define strcpy_P(dst, src) strcpy((dst), (src)) -#endif -#ifndef strcat_P -# define strcat_P(dst, src) strcat((dst), (src)) -#endif -#ifndef strcmp_P -# define strcmp_P(a, b) strcmp((a), (b)) -#endif -#ifndef strcasecmp_P -# define strcasecmp_P(a, b) strcasecmp((a), (b)) -#endif -#ifndef strncmp_P -# define strncmp_P(a, b, n) strncmp((a), (b), (n)) -#endif -#ifndef strncasecmp_P -# define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n)) -#endif -#ifndef strstr_P -# define strstr_P(a, b) strstr((a), (b)) -#endif -#ifndef strlen_P -# define strlen_P(a) strlen((a)) -#endif -#ifndef sprintf_P -# define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) -#endif - -#ifndef pgm_read_byte -# define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#endif -#ifndef pgm_read_word -# define pgm_read_word(addr) (*(const unsigned short *)(addr)) -#endif -#ifndef pgm_read_dword -# define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#endif - -#endif - - -// digital functions -//#ifndef digitalPinToPortReg -#define SPI_SW_SS_PIN (10) //SS on Uno (for software SPI) -#define SPI_SW_MOSI_PIN (11) //MOSI on Uno (for software SPI) -#define SPI_SW_MISO_PIN (12) //MISO on Uno (for software SPI) -#define SPI_SW_SCK_PIN (13) //SCK on Uno (for software SPI) - - -// --- Arduino Due --- -#if (defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__)) - -#define UART_RX_PIN (0) -#define UART_TX_PIN (1) - -#define I2C_SDA_PIN (20) -#define I2C_SCL_PIN (21) - -#define SPI_HW_SS_PIN (78) //SS0:77, SS1:87, SS2:86, SS3:78 -#define SPI_HW_MOSI_PIN (75) //75 -#define SPI_HW_MISO_PIN (74) //74 -#define SPI_HW_SCK_PIN (76) //76 - - -// --- Arduino Zero --- -#elif (defined(ARDUINO_SAM_ZERO) || defined(__SAMD21G18A__)) - -#define UART_RX_PIN (0) -#define UART_TX_PIN (1) - -#define I2C_SDA_PIN (16) -#define I2C_SCL_PIN (17) - -#define SPI_HW_SS_PIN (14) //14 -#define SPI_HW_MOSI_PIN (21) //21 -#define SPI_HW_MISO_PIN (18) //18 -#define SPI_HW_SCK_PIN (20) //20 - - -// --- Arduino Mega --- -#elif (defined(ARDUINO_AVR_MEGA) || \ - defined(ARDUINO_AVR_MEGA1280) || \ - defined(ARDUINO_AVR_MEGA2560) || \ - defined(__AVR_ATmega1280__) || \ - defined(__AVR_ATmega1281__) || \ - defined(__AVR_ATmega2560__) || \ - defined(__AVR_ATmega2561__)) - -#define UART_RX_PIN (0) //PE0 -#define UART_TX_PIN (1) //PE1 - -#define I2C_SDA_PIN (20) -#define I2C_SCL_PIN (21) - -#define SPI_HW_SS_PIN (53) //PB0 -#define SPI_HW_MOSI_PIN (51) //PB2 -#define SPI_HW_MISO_PIN (50) //PB3 -#define SPI_HW_SCK_PIN (52) //PB1 - -#define __digitalPinToPortReg(P) \ -(((P) >= 22 && (P) <= 29) ? &PORTA : \ -((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ -(((P) >= 30 && (P) <= 37) ? &PORTC : \ -((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ -((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \ -(((P) >= 54 && (P) <= 61) ? &PORTF : \ -((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ -((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ -(((P) == 14 || (P) == 15) ? &PORTJ : \ -(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) - -#define __digitalPinToDDRReg(P) \ -(((P) >= 22 && (P) <= 29) ? &DDRA : \ -((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ -(((P) >= 30 && (P) <= 37) ? &DDRC : \ -((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ -((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \ -(((P) >= 54 && (P) <= 61) ? &DDRF : \ -((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ -((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ -(((P) == 14 || (P) == 15) ? &DDRJ : \ -(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) - -#define __digitalPinToPINReg(P) \ -(((P) >= 22 && (P) <= 29) ? &PINA : \ -((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ -(((P) >= 30 && (P) <= 37) ? &PINC : \ -((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \ -((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \ -(((P) >= 54 && (P) <= 61) ? &PINF : \ -((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \ -((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \ -(((P) == 14 || (P) == 15) ? &PINJ : \ -(((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) - -#define __digitalPinToBit(P) \ -(((P) >= 7 && (P) <= 9) ? (P) - 3 : \ -(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ -(((P) >= 22 && (P) <= 29) ? (P) - 22 : \ -(((P) >= 30 && (P) <= 37) ? 37 - (P) : \ -(((P) >= 39 && (P) <= 41) ? 41 - (P) : \ -(((P) >= 42 && (P) <= 49) ? 49 - (P) : \ -(((P) >= 50 && (P) <= 53) ? 53 - (P) : \ -(((P) >= 54 && (P) <= 61) ? (P) - 54 : \ -(((P) >= 62 && (P) <= 69) ? (P) - 62 : \ -(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ -(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ -(((P) == 19) ? 2 : \ -(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ -(((P) == 2) ? 4 : \ -(((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) - - -// --- Arduino 644 --- -#elif (defined(__AVR_ATmega644__) || \ - defined(__AVR_ATmega644P__)) - -#define UART_RX_PIN (8) //PD0 -#define UART_TX_PIN (9) //PD1 - -#define I2C_SDA_PIN (17) //PC1 -#define I2C_SCL_PIN (16) //PC0 - -#define SPI_HW_SS_PIN (4) //PB4 -#define SPI_HW_MOSI_PIN (5) //PB5 -#define SPI_HW_MISO_PIN (6) //PB6 -#define SPI_HW_SCK_PIN (7) //PB7 - -#define __digitalPinToPortReg(P) \ -(((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA))) -#define __digitalPinToDDRReg(P) \ -(((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 8 && (P) <= 15) ? &DDRC : &DDRA))) -#define __digitalPinToPINReg(P) \ -(((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 8 && (P) <= 15) ? &PINC : &PINA))) -#define __digitalPinToBit(P) \ -(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24))) - - -// --- Arduino Leonardo --- -#elif (defined(ARDUINO_AVR_LEONARDO) || \ - defined(__AVR_ATmega16U4__) || \ - defined(__AVR_ATmega32U4__)) - -#define UART_RX_PIN (0) //PD2 -#define UART_TX_PIN (1) //PD3 - -#define I2C_SDA_PIN (2) //PD1 -#define I2C_SCL_PIN (3) //PD0 - -#define SPI_HW_SS_PIN (17) //PB0 -#define SPI_HW_MOSI_PIN (16) //PB2 -#define SPI_HW_MISO_PIN (14) //PB3 -#define SPI_HW_SCK_PIN (15) //PB1 - -#define __digitalPinToPortReg(P) \ -((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF : (((P) == 7) ? &PORTE : &PORTB))) -#define __digitalPinToDDRReg(P) \ -((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF : (((P) == 7) ? &DDRE : &DDRB))) -#define __digitalPinToPINReg(P) \ -((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF : (((P) == 7) ? &PINE : &PINB))) -#define __digitalPinToBit(P) \ -(((P) >= 8 && (P) <= 11) ? (P) - 4 : (((P) >= 18 && (P) <= 21) ? 25 - (P) : (((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : (((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : (((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 ))))))))))))))))))) - - -// --- Arduino Uno --- -#elif (defined(ARDUINO_AVR_UNO) || \ - defined(ARDUINO_AVR_DUEMILANOVE) || \ - defined(__AVR_ATmega328__) || \ - defined(__AVR_ATmega328P__) || \ - defined(__AVR_ATmega328PB__)) - -#define UART_RX_PIN (0) //PD0 -#define UART_TX_PIN (1) //PD1 - -#define I2C_SDA_PIN (18) //A4 -#define I2C_SCL_PIN (19) //A5 - -#define SPI_HW_SS_PIN (10) //PB0 -#define SPI_HW_MOSI_PIN (11) //PB2 -#define SPI_HW_MISO_PIN (12) //PB3 -#define SPI_HW_SCK_PIN (13) //PB1 - -#if defined(__AVR_ATmega328PB__) -#define __digitalPinToPortReg(P) \ -(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE))) -#define __digitalPinToDDRReg(P) \ -(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE))) -#define __digitalPinToPINReg(P) \ -(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE))) -#define __digitalPinToBit(P) \ -(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22)))) -#else -#define __digitalPinToPortReg(P) \ -(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC)) -#define __digitalPinToDDRReg(P) \ -(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC)) -#define __digitalPinToPINReg(P) \ -(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC)) -#define __digitalPinToBit(P) \ -(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) -#endif - - -// --- Other --- -#else - -#define I2C_SDA_PIN SDA -#define I2C_SCL_PIN SCL - -#define SPI_HW_SS_PIN SS -#define SPI_HW_MOSI_PIN MOSI -#define SPI_HW_MISO_PIN MISO -#define SPI_HW_SCK_PIN SCK - - -#endif -//#endif //#ifndef digitalPinToPortReg - - -#ifndef digitalWriteFast -#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) -#define digitalWriteFast(P, V) \ -if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ - BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \ -} else { \ - digitalWrite((P), (V)); \ -} -#else -#define digitalWriteFast digitalWrite -#endif -#endif - - -#ifndef pinModeFast -#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) -#define pinModeFast(P, V) \ -if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ - BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \ -} else { \ - pinMode((P), (V)); \ -} -#else -#define pinModeFast pinMode -#endif -#endif - - -#ifndef digitalReadFast -#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) -#define digitalReadFast(P) ( (int) __digitalReadFast((P)) ) -#define __digitalReadFast(P ) \ - (__builtin_constant_p(P) ) ? ( \ - ( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \ - digitalRead((P)) -#else -#define digitalReadFast digitalRead -#endif -#endif - -#endif //__digitalWriteFast_h_ - diff --git a/idle.ino b/idle.ino index 3297070..4d75065 100644 --- a/idle.ino +++ b/idle.ino @@ -32,7 +32,7 @@ void initialiseIdle() //Case 1 is on/off idle control if (currentStatus.coolant < configPage4.iacFastTemp) { - digitalWriteFast(pinIdle1, HIGH); + digitalWrite(pinIdle1, HIGH); } break; @@ -122,10 +122,10 @@ void idleControl() case 1: //Case 1 is on/off idle control if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp) //All temps are offset by 40 degrees { - digitalWriteFast(pinIdle1, HIGH); + digitalWrite(pinIdle1, HIGH); idleOn = true; } - else if (idleOn) { digitalWriteFast(pinIdle1, LOW); idleOn = false; } + else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; } break; case 2: //Case 2 is PWM open loop @@ -141,7 +141,7 @@ void idleControl() { //Standard running currentStatus.idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees - if( currentStatus.idleDuty == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWriteFast(pinIdle1, LOW); break; } + if( currentStatus.idleDuty == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); break; } TIMSK4 |= (1 << OCIE4C); //Turn on the C compare unit (ie turn on the interrupt) idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count); idleOn = true; @@ -154,7 +154,7 @@ void idleControl() //idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD); idlePID.Compute(); - if( idle_pwm_target_value == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWriteFast(pinIdle1, LOW); } + if( idle_pwm_target_value == 0 ) { TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); } else{ TIMSK4 |= (1 << OCIE4C); } //Turn on the C compare unit (ie turn on the interrupt) //idle_pwm_target_value = 104; break; @@ -168,7 +168,7 @@ void idleControl() if(idleStepper.stepperStatus == STEPPING) { //Means we're currently in a step, but it needs to be turned off - digitalWriteFast(pinStepperStep, LOW); //Turn off the step + digitalWrite(pinStepperStep, LOW); //Turn off the step idleStepper.stepStartTime = micros(); idleStepper.stepperStatus = COOLING; //'Cooling' is the time the stepper needs to sit in LOW state before the next step can be made return; @@ -192,10 +192,10 @@ void idleControl() //Currently cranking. Use the cranking table idleStepper.targetIdleStep = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check - else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards - else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards + else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards + else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards - digitalWriteFast(pinStepperStep, HIGH); + digitalWrite(pinStepperStep, HIGH); idleStepper.stepStartTime = micros(); idleStepper.stepperStatus = STEPPING; idleOn = true; @@ -205,10 +205,10 @@ void idleControl() //Standard running idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check - else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards - else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWriteFast(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards + else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards + else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards - digitalWriteFast(pinStepperStep, HIGH); + digitalWrite(pinStepperStep, HIGH); idleStepper.stepStartTime = micros(); idleStepper.stepperStatus = STEPPING; idleOn = true; @@ -224,15 +224,15 @@ A simple function to home the stepper motor (If in use) void homeStepper() { //Need to 'home' the stepper on startup - digitalWriteFast(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards + digitalWrite(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards for(int x=0; x < (configPage4.iacStepHome * 3); x++) //Step counts are divided by 3 in TS. Multiply back out here { - digitalWriteFast(pinStepperStep, HIGH); + digitalWrite(pinStepperStep, HIGH); delayMicroseconds(iacStepTime); - digitalWriteFast(pinStepperStep, LOW); + digitalWrite(pinStepperStep, LOW); delayMicroseconds(iacStepTime); } - digitalWriteFast(pinStepperDir, STEPPER_FORWARD); + digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep = 0; idleStepper.targetIdleStep = 0; idleStepper.stepperStatus = SOFF; diff --git a/speeduino.ino b/speeduino.ino index 575d8a7..2439039 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //************************************************************************************************** #include "globals.h" -#include "digitalWriteFast.h" #include "utils.h" #include "table.h" #include "scheduler.h" @@ -202,21 +201,21 @@ void setup() //Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup if(configPage2.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; } else { coilHIGH = HIGH, coilLOW = LOW; } - endCoil1Charge(); //digitalWriteFast(pinCoil1, coilLOW); - endCoil2Charge(); //digitalWriteFast(pinCoil2, coilLOW); - endCoil3Charge(); //digitalWriteFast(pinCoil3, coilLOW); - endCoil4Charge(); //digitalWriteFast(pinCoil4, coilLOW); - endCoil5Charge(); //digitalWriteFast(pinCoil5, coilLOW); + endCoil1Charge(); //digitalWrite(pinCoil1, coilLOW); + endCoil2Charge(); //digitalWrite(pinCoil2, coilLOW); + endCoil3Charge(); //digitalWrite(pinCoil3, coilLOW); + endCoil4Charge(); //digitalWrite(pinCoil4, coilLOW); + endCoil5Charge(); //digitalWrite(pinCoil5, coilLOW); //Similar for injectors, make sure they're turned off - closeInjector1(); //digitalWriteFast(pinInjector1, HIGH); - closeInjector2(); //digitalWriteFast(pinInjector2, HIGH); - closeInjector3(); //digitalWriteFast(pinInjector3, HIGH); - closeInjector4(); //digitalWriteFast(pinInjector4, HIGH); - closeInjector5(); //digitalWriteFast(pinInjector5, HIGH); + closeInjector1(); //digitalWrite(pinInjector1, HIGH); + closeInjector2(); //digitalWrite(pinInjector2, HIGH); + closeInjector3(); //digitalWrite(pinInjector3, HIGH); + closeInjector4(); //digitalWrite(pinInjector4, HIGH); + closeInjector5(); //digitalWrite(pinInjector5, HIGH); //Set the tacho output default state - digitalWriteFast(pinTachOut, HIGH); + digitalWrite(pinTachOut, HIGH); //Lookup the current MAP reading for barometric pressure readMAP(); @@ -285,10 +284,10 @@ void setup() triggerInterrupt2 = 2; break; } - pinModeFast(pinTrigger, INPUT); - pinModeFast(pinTrigger2, INPUT); - pinModeFast(pinTrigger3, INPUT); - //digitalWriteFast(pinTrigger, HIGH); + pinMode(pinTrigger, INPUT); + pinMode(pinTrigger2, INPUT); + pinMode(pinTrigger3, INPUT); + //digitalWrite(pinTrigger, HIGH); //Set the trigger function based on the decoder in the config @@ -755,7 +754,7 @@ void setup() } //Begin priming the fuel pump. This is turned off in the low resolution, 1s interrupt in timers.ino - digitalWriteFast(pinFuelPump, HIGH); + digitalWrite(pinFuelPump, HIGH); fuelPumpOn = true; //Perform the priming pulses. Set these to run at an arbitrary time in the future (100us). The prime pulse value is in ms*10, so need to multiple by 100 to get to uS setFuelSchedule1(openInjector1and4, 100, (unsigned long)(configPage1.primePulse * 100), closeInjector1and4); @@ -798,7 +797,7 @@ void loop() { int lastRPM = currentStatus.RPM; //Need to record this for rpmDOT calculation currentStatus.RPM = currentStatus.longRPM = getRPM(); //Long RPM is included here - if(fuelPumpOn == false) { digitalWriteFast(pinFuelPump, HIGH); fuelPumpOn = true; } //Check if the fuel pump is on and turn it on if it isn't. + if(fuelPumpOn == false) { digitalWrite(pinFuelPump, HIGH); fuelPumpOn = true; } //Check if the fuel pump is on and turn it on if it isn't. currentStatus.rpmDOT = ldiv(1000000, (currentLoopTime - previousLoopTime)).quot * (currentStatus.RPM - lastRPM); //This is the RPM per second that the engine has accelerated/decelleratedin the last loop } else @@ -816,9 +815,9 @@ void loop() currentStatus.rpmDOT = 0; ignitionOn = false; fuelOn = false; - if (fpPrimed) { digitalWriteFast(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete + if (fpPrimed) { digitalWrite(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete fuelPumpOn = false; - TIMSK4 &= ~(1 << OCIE4C); digitalWriteFast(pinIdle1, LOW); //Turns off the idle control PWM. This REALLY needs to be cleaned up into a general PWM controller class + TIMSK4 &= ~(1 << OCIE4C); digitalWrite(pinIdle1, LOW); //Turns off the idle control PWM. This REALLY needs to be cleaned up into a general PWM controller class } //Uncomment the following for testing @@ -838,8 +837,8 @@ void loop() //Check for launching (clutch) can be done around here too bool launchTrigger; - if(configPage3.launchHiLo) { launchTrigger = digitalReadFast(pinLaunch); } - else { launchTrigger = !digitalReadFast(pinLaunch); } + if(configPage3.launchHiLo) { launchTrigger = digitalRead(pinLaunch); } + else { launchTrigger = !digitalRead(pinLaunch); } if (configPage3.launchEnabled && launchTrigger && (currentStatus.RPM > ((unsigned int)(configPage3.lnchSoftLim) * 100)) ) { currentStatus.launchingSoft = true; BIT_SET(currentStatus.spark, BIT_SPARK_SLAUNCH); } //SoftCut rev limit for 2-step launch control. else { currentStatus.launchingSoft = false; BIT_CLEAR(currentStatus.spark, BIT_SPARK_SLAUNCH); } if (configPage3.launchEnabled && launchTrigger && (currentStatus.RPM > ((unsigned int)(configPage3.lnchHardLim) * 100)) ) { currentStatus.launchingHard = true; BIT_SET(currentStatus.spark, BIT_SPARK_HLAUNCH); } //HardCut rev limit for 2-step launch control. @@ -901,7 +900,7 @@ void loop() if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); //clears the engine cranking bit - if(configPage2.ignBypassEnabled) { digitalWriteFast(pinIgnBypass, HIGH); } + if(configPage2.ignBypassEnabled) { digitalWrite(pinIgnBypass, HIGH); } } } else @@ -909,7 +908,7 @@ void loop() BIT_SET(currentStatus.engine, BIT_ENGINE_CRANK); BIT_CLEAR(currentStatus.engine, BIT_ENGINE_RUN); currentStatus.runSecs = 0; //We're cranking (hopefully), so reset the engine run time to prompt ASE. - if(configPage2.ignBypassEnabled) { digitalWriteFast(pinIgnBypass, LOW); } + if(configPage2.ignBypassEnabled) { digitalWrite(pinIgnBypass, LOW); } } //END SETTING STATUSES @@ -1413,63 +1412,63 @@ void loop() void openInjector1() { *inj1_pin_port |= (inj1_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1); } void closeInjector1() { *inj1_pin_port &= ~(inj1_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1); } - void beginCoil1Charge() { *ign1_pin_port |= (ign1_pin_mask); BIT_SET(currentStatus.spark, 0); digitalWriteFast(pinTachOut, LOW); } + void beginCoil1Charge() { *ign1_pin_port |= (ign1_pin_mask); BIT_SET(currentStatus.spark, 0); digitalWrite(pinTachOut, LOW); } void endCoil1Charge() { *ign1_pin_port &= ~(ign1_pin_mask); BIT_CLEAR(currentStatus.spark, 0); } void openInjector2() { *inj2_pin_port |= (inj2_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2); } void closeInjector2() { *inj2_pin_port &= ~(inj2_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ2); } - void beginCoil2Charge() { *ign2_pin_port |= (ign2_pin_mask); BIT_SET(currentStatus.spark, 1); digitalWriteFast(pinTachOut, LOW); } + void beginCoil2Charge() { *ign2_pin_port |= (ign2_pin_mask); BIT_SET(currentStatus.spark, 1); digitalWrite(pinTachOut, LOW); } void endCoil2Charge() { *ign2_pin_port &= ~(ign2_pin_mask); BIT_CLEAR(currentStatus.spark, 1);} void openInjector3() { *inj3_pin_port |= (inj3_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ3); } void closeInjector3() { *inj3_pin_port &= ~(inj3_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ3); } - void beginCoil3Charge() { *ign3_pin_port |= (ign3_pin_mask); BIT_SET(currentStatus.spark, 2); digitalWriteFast(pinTachOut, LOW); } + void beginCoil3Charge() { *ign3_pin_port |= (ign3_pin_mask); BIT_SET(currentStatus.spark, 2); digitalWrite(pinTachOut, LOW); } void endCoil3Charge() { *ign3_pin_port &= ~(ign3_pin_mask); BIT_CLEAR(currentStatus.spark, 2);} void openInjector4() { *inj4_pin_port |= (inj4_pin_mask); ; BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ4); } void closeInjector4() { *inj4_pin_port &= ~(inj4_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ4); } - void beginCoil4Charge() { *ign4_pin_port |= (ign4_pin_mask); BIT_SET(currentStatus.spark, 3); digitalWriteFast(pinTachOut, LOW); } + void beginCoil4Charge() { *ign4_pin_port |= (ign4_pin_mask); BIT_SET(currentStatus.spark, 3); digitalWrite(pinTachOut, LOW); } void endCoil4Charge() { *ign4_pin_port &= ~(ign4_pin_mask); BIT_CLEAR(currentStatus.spark, 3);} #else */ - inline void openInjector1() { digitalWriteFast(pinInjector1, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1); } - inline void closeInjector1() { digitalWriteFast(pinInjector1, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1); } - inline void beginCoil1Charge() { digitalWriteFast(pinCoil1, coilHIGH); digitalWriteFast(pinTachOut, LOW); } - inline void endCoil1Charge() { digitalWriteFast(pinCoil1, coilLOW); } + inline void openInjector1() { digitalWrite(pinInjector1, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1); } + inline void closeInjector1() { digitalWrite(pinInjector1, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1); } + inline void beginCoil1Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinTachOut, LOW); } + inline void endCoil1Charge() { digitalWrite(pinCoil1, coilLOW); } - inline void openInjector2() { digitalWriteFast(pinInjector2, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2); } //Sets the relevant pin HIGH and changes the current status bit for injector 2 (2nd bit of currentStatus.squirt) - inline void closeInjector2() { digitalWriteFast(pinInjector2, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ2); } - inline void beginCoil2Charge() { digitalWriteFast(pinCoil2, coilHIGH); digitalWriteFast(pinTachOut, LOW); } - inline void endCoil2Charge() { digitalWriteFast(pinCoil2, coilLOW); } + inline void openInjector2() { digitalWrite(pinInjector2, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2); } //Sets the relevant pin HIGH and changes the current status bit for injector 2 (2nd bit of currentStatus.squirt) + inline void closeInjector2() { digitalWrite(pinInjector2, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ2); } + inline void beginCoil2Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pinTachOut, LOW); } + inline void endCoil2Charge() { digitalWrite(pinCoil2, coilLOW); } - inline void openInjector3() { digitalWriteFast(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ3); } //Sets the relevant pin HIGH and changes the current status bit for injector 3 (3rd bit of currentStatus.squirt) - inline void closeInjector3() { digitalWriteFast(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ3); } - inline void beginCoil3Charge() { digitalWriteFast(pinCoil3, coilHIGH); digitalWriteFast(pinTachOut, LOW); } - inline void endCoil3Charge() { digitalWriteFast(pinCoil3, coilLOW); } + inline void openInjector3() { digitalWrite(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ3); } //Sets the relevant pin HIGH and changes the current status bit for injector 3 (3rd bit of currentStatus.squirt) + inline void closeInjector3() { digitalWrite(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ3); } + inline void beginCoil3Charge() { digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); } + inline void endCoil3Charge() { digitalWrite(pinCoil3, coilLOW); } - inline void openInjector4() { digitalWriteFast(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ4); } //Sets the relevant pin HIGH and changes the current status bit for injector 4 (4th bit of currentStatus.squirt) - inline void closeInjector4() { digitalWriteFast(pinInjector4, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ4); } - inline void beginCoil4Charge() { digitalWriteFast(pinCoil4, coilHIGH); digitalWriteFast(pinTachOut, LOW); } - inline void endCoil4Charge() { digitalWriteFast(pinCoil4, coilLOW); } + inline void openInjector4() { digitalWrite(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ4); } //Sets the relevant pin HIGH and changes the current status bit for injector 4 (4th bit of currentStatus.squirt) + inline void closeInjector4() { digitalWrite(pinInjector4, LOW); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ4); } + inline void beginCoil4Charge() { digitalWrite(pinCoil4, coilHIGH); digitalWrite(pinTachOut, LOW); } + inline void endCoil4Charge() { digitalWrite(pinCoil4, coilLOW); } - inline void openInjector5() { digitalWriteFast(pinInjector5, HIGH); } - inline void closeInjector5() { digitalWriteFast(pinInjector5, LOW); } - inline void beginCoil5Charge() { digitalWriteFast(pinCoil5, coilHIGH); digitalWriteFast(pinTachOut, LOW); } - inline void endCoil5Charge() { digitalWriteFast(pinCoil5, coilLOW); } + inline void openInjector5() { digitalWrite(pinInjector5, HIGH); } + inline void closeInjector5() { digitalWrite(pinInjector5, LOW); } + inline void beginCoil5Charge() { digitalWrite(pinCoil5, coilHIGH); digitalWrite(pinTachOut, LOW); } + inline void endCoil5Charge() { digitalWrite(pinCoil5, coilLOW); } //#endif //Combination functions for semi-sequential injection -void openInjector1and4() { digitalWriteFast(pinInjector1, HIGH); digitalWriteFast(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, 0); } -void closeInjector1and4() { digitalWriteFast(pinInjector1, LOW); digitalWriteFast(pinInjector4, LOW);BIT_CLEAR(currentStatus.squirt, 0); } -void openInjector2and3() { digitalWriteFast(pinInjector2, HIGH); digitalWriteFast(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, 1); } -void closeInjector2and3() { digitalWriteFast(pinInjector2, LOW); digitalWriteFast(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, 1); } +void openInjector1and4() { digitalWrite(pinInjector1, HIGH); digitalWrite(pinInjector4, HIGH); BIT_SET(currentStatus.squirt, 0); } +void closeInjector1and4() { digitalWrite(pinInjector1, LOW); digitalWrite(pinInjector4, LOW);BIT_CLEAR(currentStatus.squirt, 0); } +void openInjector2and3() { digitalWrite(pinInjector2, HIGH); digitalWrite(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, 1); } +void closeInjector2and3() { digitalWrite(pinInjector2, LOW); digitalWrite(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, 1); } //As above but for ignition (Wasted COP mode) -void beginCoil1and3Charge() { digitalWriteFast(pinCoil1, coilHIGH); digitalWriteFast(pinCoil3, coilHIGH); digitalWriteFast(pinTachOut, LOW); } -void endCoil1and3Charge() { digitalWriteFast(pinCoil1, coilLOW); digitalWriteFast(pinCoil3, coilLOW); } -void beginCoil2and4Charge() { digitalWriteFast(pinCoil2, coilHIGH); digitalWriteFast(pinCoil4, coilHIGH); digitalWriteFast(pinTachOut, LOW); } -void endCoil2and4Charge() { digitalWriteFast(pinCoil2, coilLOW); digitalWriteFast(pinCoil4, coilLOW); } +void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); } +void endCoil1and3Charge() { digitalWrite(pinCoil1, coilLOW); digitalWrite(pinCoil3, coilLOW); } +void beginCoil2and4Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pinCoil4, coilHIGH); digitalWrite(pinTachOut, LOW); } +void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoil4, coilLOW); } void nullCallback() { return; } diff --git a/timers.ino b/timers.ino index ccdf1aa..e03475e 100644 --- a/timers.ino +++ b/timers.ino @@ -47,10 +47,10 @@ void timer2Overflowinterrupt() //Most ARM chips can simply call a function targetOverdwellTime = micros() - (1000 * configPage2.dwellLimit); //Set a target time in the past that all coil charging must have begun after. If the coil charge began before this time, it's been running too long targetTachoPulseTime = micros() - (1500); //Check first whether each spark output is currently on. Only check it's dwell time if it is - if(ignitionSchedule1.Status == RUNNING) { if(ignitionSchedule1.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil1Charge(); } if(ignitionSchedule1.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } - if(ignitionSchedule2.Status == RUNNING) { if(ignitionSchedule2.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil2Charge(); } if(ignitionSchedule2.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } - if(ignitionSchedule3.Status == RUNNING) { if(ignitionSchedule3.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil3Charge(); } if(ignitionSchedule3.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } - if(ignitionSchedule4.Status == RUNNING) { if(ignitionSchedule4.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil4Charge(); } if(ignitionSchedule4.startTime < targetTachoPulseTime) { digitalWriteFast(pinTachOut, HIGH); } } + if(ignitionSchedule1.Status == RUNNING) { if(ignitionSchedule1.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil1Charge(); } if(ignitionSchedule1.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } + if(ignitionSchedule2.Status == RUNNING) { if(ignitionSchedule2.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil2Charge(); } if(ignitionSchedule2.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } + if(ignitionSchedule3.Status == RUNNING) { if(ignitionSchedule3.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil3Charge(); } if(ignitionSchedule3.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } + if(ignitionSchedule4.Status == RUNNING) { if(ignitionSchedule4.startTime < targetOverdwellTime && configPage2.useDwellLim) { endCoil4Charge(); } if(ignitionSchedule4.startTime < targetTachoPulseTime) { digitalWrite(pinTachOut, HIGH); } } //Loop executed every 250ms loop (1ms x 250 = 250ms) //Anything inside this if statement will run every 250ms. @@ -92,7 +92,7 @@ void timer2Overflowinterrupt() //Most ARM chips can simply call a function if(currentStatus.secl >= configPage1.fpPrime) { fpPrimed = true; //Mark the priming as being completed - if(currentStatus.RPM == 0) { digitalWriteFast(pinFuelPump, LOW); fuelPumpOn = false; } //If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running + if(currentStatus.RPM == 0) { digitalWrite(pinFuelPump, LOW); fuelPumpOn = false; } //If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running } } //************************************************************************************************************************************************** diff --git a/utils.ino b/utils.ino index ff8f6cf..b0c07fc 100644 --- a/utils.ino +++ b/utils.ino @@ -8,7 +8,6 @@ A full copy of the license may be found in the projects root directory /* Returns how much free dynamic memory exists (between heap and stack) */ -#include "digitalWriteFast.h" #include "utils.h" int freeRam () @@ -312,22 +311,22 @@ void setPinMapping(byte boardID) if(configPage1.tachoPin != 0) { pinTachOut = configPage1.tachoPin; } //Finally, set the relevant pin modes for outputs - pinModeFast(pinCoil1, OUTPUT); - pinModeFast(pinCoil2, OUTPUT); - pinModeFast(pinCoil3, OUTPUT); - pinModeFast(pinCoil4, OUTPUT); - pinModeFast(pinCoil5, OUTPUT); - pinModeFast(pinInjector1, OUTPUT); - pinModeFast(pinInjector2, OUTPUT); - pinModeFast(pinInjector3, OUTPUT); - pinModeFast(pinInjector4, OUTPUT); - pinModeFast(pinInjector5, OUTPUT); - pinModeFast(pinTachOut, OUTPUT); - pinModeFast(pinIdle1, OUTPUT); - pinModeFast(pinIdle2, OUTPUT); - pinModeFast(pinFuelPump, OUTPUT); - pinModeFast(pinIgnBypass, OUTPUT); - pinModeFast(pinFan, OUTPUT); + pinMode(pinCoil1, OUTPUT); + pinMode(pinCoil2, OUTPUT); + pinMode(pinCoil3, OUTPUT); + pinMode(pinCoil4, OUTPUT); + pinMode(pinCoil5, OUTPUT); + pinMode(pinInjector1, OUTPUT); + pinMode(pinInjector2, OUTPUT); + pinMode(pinInjector3, OUTPUT); + pinMode(pinInjector4, OUTPUT); + pinMode(pinInjector5, OUTPUT); + pinMode(pinTachOut, OUTPUT); + pinMode(pinIdle1, OUTPUT); + pinMode(pinIdle2, OUTPUT); + pinMode(pinFuelPump, OUTPUT); + pinMode(pinIgnBypass, OUTPUT); + pinMode(pinFan, OUTPUT); inj1_pin_port = portOutputRegister(digitalPinToPort(pinInjector1)); inj1_pin_mask = digitalPinToBitMask(pinInjector1); @@ -352,25 +351,25 @@ void setPinMapping(byte boardID) ign5_pin_mask = digitalPinToBitMask(pinCoil5); //And for inputs - pinModeFast(pinMAP, INPUT); - pinModeFast(pinO2, INPUT); - pinModeFast(pinO2_2, INPUT); - pinModeFast(pinTPS, INPUT); - pinModeFast(pinIAT, INPUT); - pinModeFast(pinCLT, INPUT); - pinModeFast(pinBat, INPUT); - pinModeFast(pinTrigger, INPUT); - pinModeFast(pinTrigger2, INPUT); - pinModeFast(pinTrigger3, INPUT); - pinModeFast(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup -// pinModeFast(pinLaunch, INPUT_PULLUP); //This should work for both NO and NC grounding switches - if (configPage3.lnchPullRes) { pinModeFast(pinLaunch, INPUT_PULLUP); } - else { pinModeFast(pinLaunch, INPUT); } //If Launch Pull Resistor is not set make input float. + pinMode(pinMAP, INPUT); + pinMode(pinO2, INPUT); + pinMode(pinO2_2, INPUT); + pinMode(pinTPS, INPUT); + pinMode(pinIAT, INPUT); + pinMode(pinCLT, INPUT); + pinMode(pinBat, INPUT); + pinMode(pinTrigger, INPUT); + pinMode(pinTrigger2, INPUT); + pinMode(pinTrigger3, INPUT); + pinMode(pinFlex, INPUT_PULLUP); //Standard GM / Continental flex sensor requires pullup +// pinMode(pinLaunch, INPUT_PULLUP); //This should work for both NO and NC grounding switches + if (configPage3.lnchPullRes) { pinMode(pinLaunch, INPUT_PULLUP); } + else { pinMode(pinLaunch, INPUT); } //If Launch Pull Resistor is not set make input float. //Set default values - digitalWriteFast(pinMAP, HIGH); - //digitalWriteFast(pinO2, LOW); - digitalWriteFast(pinTPS, LOW); + digitalWrite(pinMAP, HIGH); + //digitalWrite(pinO2, LOW); + digitalWrite(pinTPS, LOW); } /* From dabbf872c2db490e13dfd73e0f59f4bf83179b0d Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Sat, 22 Oct 2016 09:17:56 -0200 Subject: [PATCH 09/21] limit baro corretion Check if engine isn't running. Others minor code changes. --- auxiliaries.ino | 5 +- digitalWriteFast.h | 217 +++++++++++++++++++++++++++++++++++++++++++++ globals.h | 3 +- idle.ino | 5 +- math.h | 2 +- sensors.ino | 2 +- speeduino.ino | 38 +++++--- table.ino | 82 ++--------------- 8 files changed, 256 insertions(+), 98 deletions(-) create mode 100644 digitalWriteFast.h diff --git a/auxiliaries.ino b/auxiliaries.ino index 17e4673..14c3d70 100644 --- a/auxiliaries.ino +++ b/auxiliaries.ino @@ -35,8 +35,9 @@ void initialiseAuxPWM() vvt_pin_port = portOutputRegister(digitalPinToPort(pinVVT_1)); vvt_pin_mask = digitalPinToBitMask(pinVVT_1); - boost_pwm_max_count = 1000000L / (16 * configPage3.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz - vvt_pwm_max_count = 1000000L / (16 * configPage3.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle + //(16 * configPage3.boostFreq * 2) = (configPage3.boostFreq * 16 * 2) = (configPage3.boostFreq * 32) = (configPage3.boostFreq << 5) + boost_pwm_max_count = 1000000L / (configPage3.boostFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz + vvt_pwm_max_count = 1000000L / (configPage3.vvtFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle //TIMSK1 |= (1 << OCIE1A); //Turn on the A compare unit (ie turn on the interrupt) //Shouldn't be needed with closed loop as its turned on below TIMSK1 |= (1 << OCIE1B); //Turn on the B compare unit (ie turn on the interrupt) diff --git a/digitalWriteFast.h b/digitalWriteFast.h new file mode 100644 index 0000000..b2676a7 --- /dev/null +++ b/digitalWriteFast.h @@ -0,0 +1,217 @@ +/* + Optimized digital functions for AVR microcontrollers + by Watterott electronic (www.watterott.com) + based on http://code.google.com/p/digitalwritefast + */ + +#ifndef __digitalWriteFast_h_ +#define __digitalWriteFast_h_ 1 + +#define ERROR_SEQUENCE 0b10101010 //digitalReadFast will return this value if pin number is not constant +// general macros/defines +#ifndef BIT_READ +# define BIT_READ(value, bit) ((value) & (1UL << (bit))) +#endif +#ifndef BIT_SET +# define BIT_SET(value, bit) ((value) |= (1UL << (bit))) +#endif +#ifndef BIT_CLEAR +# define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit))) +#endif +#ifndef BIT_WRITE +# define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit)) +#endif + +#ifndef SWAP +#define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0) +#endif + +// workarounds for ARM microcontrollers +#if (!defined(__AVR__) || defined(ARDUINO_ARCH_SAM)) +#ifndef PROGMEM +# define PROGMEM +#endif +#ifndef PGM_P +# define PGM_P const char * +#endif +#ifndef PSTR +# define PSTR(str) (str) +#endif + +#ifndef memcpy_P +# define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#endif +#ifndef strcpy_P +# define strcpy_P(dst, src) strcpy((dst), (src)) +#endif +#ifndef strcat_P +# define strcat_P(dst, src) strcat((dst), (src)) +#endif +#ifndef strcmp_P +# define strcmp_P(a, b) strcmp((a), (b)) +#endif +#ifndef strcasecmp_P +# define strcasecmp_P(a, b) strcasecmp((a), (b)) +#endif +#ifndef strncmp_P +# define strncmp_P(a, b, n) strncmp((a), (b), (n)) +#endif +#ifndef strncasecmp_P +# define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n)) +#endif +#ifndef strstr_P +# define strstr_P(a, b) strstr((a), (b)) +#endif +#ifndef strlen_P +# define strlen_P(a) strlen((a)) +#endif +#ifndef sprintf_P +# define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) +#endif + +#ifndef pgm_read_byte +# define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#endif +#ifndef pgm_read_word +# define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#endif +#ifndef pgm_read_dword +# define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#endif + +#endif + + +// digital functions +// --- Arduino Mega --- +#if (defined(ARDUINO_AVR_MEGA) || \ + defined(ARDUINO_AVR_MEGA1280) || \ + defined(ARDUINO_AVR_MEGA2560) || \ + defined(__AVR_ATmega1280__) || \ + defined(__AVR_ATmega1281__) || \ + defined(__AVR_ATmega2560__) || \ + defined(__AVR_ATmega2561__)) + +#define UART_RX_PIN (0) //PE0 +#define UART_TX_PIN (1) //PE1 + +#define I2C_SDA_PIN (20) +#define I2C_SCL_PIN (21) + +#define SPI_HW_SS_PIN (53) //PB0 +#define SPI_HW_MOSI_PIN (51) //PB2 +#define SPI_HW_MISO_PIN (50) //PB3 +#define SPI_HW_SCK_PIN (52) //PB1 + +#define __digitalPinToPortReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PORTA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ +(((P) >= 30 && (P) <= 37) ? &PORTC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \ +(((P) >= 54 && (P) <= 61) ? &PORTF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ +(((P) == 14 || (P) == 15) ? &PORTJ : \ +(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) + +#define __digitalPinToDDRReg(P) \ +(((P) >= 22 && (P) <= 29) ? &DDRA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ +(((P) >= 30 && (P) <= 37) ? &DDRC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \ +(((P) >= 54 && (P) <= 61) ? &DDRF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ +(((P) == 14 || (P) == 15) ? &DDRJ : \ +(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) + +#define __digitalPinToPINReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PINA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ +(((P) >= 30 && (P) <= 37) ? &PINC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \ +((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \ +(((P) >= 54 && (P) <= 61) ? &PINF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \ +(((P) == 14 || (P) == 15) ? &PINJ : \ +(((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) + +#define __digitalPinToBit(P) \ +(((P) >= 7 && (P) <= 9) ? (P) - 3 : \ +(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ +(((P) >= 22 && (P) <= 29) ? (P) - 22 : \ +(((P) >= 30 && (P) <= 37) ? 37 - (P) : \ +(((P) >= 39 && (P) <= 41) ? 41 - (P) : \ +(((P) >= 42 && (P) <= 49) ? 49 - (P) : \ +(((P) >= 50 && (P) <= 53) ? 53 - (P) : \ +(((P) >= 54 && (P) <= 61) ? (P) - 54 : \ +(((P) >= 62 && (P) <= 69) ? (P) - 62 : \ +(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ +(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ +(((P) == 19) ? 2 : \ +(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ +(((P) == 2) ? 4 : \ +(((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) + +// --- Other --- +#else + +#define SPI_HW_SS_PIN SS +#define SPI_HW_MOSI_PIN MOSI +#define SPI_HW_MISO_PIN MISO +#define SPI_HW_SCK_PIN SCK + +#endif +//#endif //#ifndef digitalPinToPortReg + + +//ref: http://forum.arduino.cc/index.php?topic=140409.msg1054868#msg1054868 +//void OutputsErrorIfCalled( void ) __attribute__ (( error( "Line: "__line__ "Variable used for digitalWriteFast") )); +void NonConstantUsed( void ) __attribute__ (( error("") )); + + +#ifndef digitalWriteFast +#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) +#define digitalWriteFast(P, V) \ +if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ + BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \ +} else { \ + NonConstantUsed(); \ +} +#else +#define digitalWriteFast digitalWrite +#endif +#endif + + +#ifndef pinModeFast +#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) +#define pinModeFast(P, V) \ +if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ + BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \ +} else { \ + NonConstantUsed(); \ +} +#else +#define pinModeFast pinMode +#endif +#endif + + +#ifndef digitalReadFast +#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) +#define digitalReadFast(P) ( (byte) __digitalReadFast((P)) ) +#define __digitalReadFast(P ) \ + (__builtin_constant_p(P) ) ? ( \ + ( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \ + ERROR_SEQUENCE +#else +#define digitalReadFast digitalRead +#endif +#endif + +#endif //__digitalWriteFast_h_ + diff --git a/globals.h b/globals.h index 5acd138..ccf3051 100644 --- a/globals.h +++ b/globals.h @@ -147,10 +147,9 @@ struct statuses { unsigned int PW; //In uS volatile byte runSecs; //Counter of seconds since cranking commenced (overflows at 255 obviously) volatile byte secl; //Continous - volatile unsigned int loopsPerSecond; + volatile int loopsPerSecond; boolean launchingSoft; //True when in launch control soft limit mode boolean launchingHard; //True when in launch control hard limit mode - float adv; int freeRAM; //Helpful bitwise operations: diff --git a/idle.ino b/idle.ino index 3b8e431..79eedb9 100644 --- a/idle.ino +++ b/idle.ino @@ -52,7 +52,8 @@ void initialiseIdle() idle_pin_mask = digitalPinToBitMask(pinIdle1); idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2)); idle2_pin_mask = digitalPinToBitMask(pinIdle2); - idle_pwm_max_count = 1000000L / (16 * configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz + //(16 * configPage3.idleFreq * 2) = (configPage3.idleFreq * 16 * 2) = (configPage3.idleFreq * 32) = (configPage3.idleFreq << 5) + idle_pwm_max_count = 1000000L / (configPage3.idleFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz enableIdle(); break; @@ -72,7 +73,7 @@ void initialiseIdle() idle_pin_mask = digitalPinToBitMask(pinIdle1); idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2)); idle2_pin_mask = digitalPinToBitMask(pinIdle2); - idle_pwm_max_count = 1000000L / (16 * configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz + idle_pwm_max_count = 1000000L / (configPage3.idleFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz idlePID.SetOutputLimits(0, idle_pwm_max_count); idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD); idlePID.SetMode(AUTOMATIC); //Turn PID on diff --git a/math.h b/math.h index 983b754..128ddb9 100644 --- a/math.h +++ b/math.h @@ -11,7 +11,7 @@ int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max) //This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range //This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings) //int fastMap1023toX(unsigned long x, int in_min, int in_max, int out_min, int out_max) -//removed unused variables, in_min and out_min is aways 0, in_max is aways 1023 +//removed ununsed variables, in_min and out_min is aways 0, in_max is aways 1023 int fastMap1023toX(unsigned long x, int out_max) { return (x * out_max) >> 10; diff --git a/sensors.ino b/sensors.ino index 4b0a2fe..c320e9c 100644 --- a/sensors.ino +++ b/sensors.ino @@ -4,7 +4,7 @@ Copyright (C) Josh Stewart A full copy of the license may be found in the projects root directory */ -unsigned int tempReading; +int tempReading; void instanteneousMAPReading() { diff --git a/speeduino.ino b/speeduino.ino index 93ac030..4e17552 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -96,6 +96,7 @@ unsigned long previousLoopTime; //The time the previous loop started (uS) unsigned long MAPrunningValue; //Used for tracking either the total of all MAP readings in this cycle (Event average) or the lowest value detected in this cycle (event minimum) unsigned int MAPcount; //Number of samples taken in the current MAP cycle byte MAPcurRev = 0; //Tracks which revolution we're sampling on +int LastBaro; //Used for ignore correction if powered on a ruuning engine int CRANK_ANGLE_MAX = 720; int CRANK_ANGLE_MAX_IGN = 360, CRANK_ANGLE_MAX_INJ = 360; // The number of crank degrees that the system track over. 360 for wasted / timed batch and 720 for sequential @@ -201,25 +202,33 @@ void setup() //Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup if(configPage2.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; } else { coilHIGH = HIGH, coilLOW = LOW; } - endCoil1Charge(); //digitalWrite(pinCoil1, coilLOW); - endCoil2Charge(); //digitalWrite(pinCoil2, coilLOW); - endCoil3Charge(); //digitalWrite(pinCoil3, coilLOW); - endCoil4Charge(); //digitalWrite(pinCoil4, coilLOW); - endCoil5Charge(); //digitalWrite(pinCoil5, coilLOW); + endCoil1Charge(); + endCoil2Charge(); + endCoil3Charge(); + endCoil4Charge(); + endCoil5Charge(); //Similar for injectors, make sure they're turned off - closeInjector1(); //digitalWrite(pinInjector1, HIGH); - closeInjector2(); //digitalWrite(pinInjector2, HIGH); - closeInjector3(); //digitalWrite(pinInjector3, HIGH); - closeInjector4(); //digitalWrite(pinInjector4, HIGH); - closeInjector5(); //digitalWrite(pinInjector5, HIGH); + closeInjector1(); + closeInjector2(); + closeInjector3(); + closeInjector4(); + closeInjector5(); //Set the tacho output default state digitalWrite(pinTachOut, HIGH); //Lookup the current MAP reading for barometric pressure readMAP(); - currentStatus.baro = currentStatus.MAP; + /* + * The highest sea-level pressure on Earth occurs in Siberia, where the Siberian High often attains a sea-level pressure above 105 kPa; + * with record highs close to 108.5 kPa. + * The lowest measurable sea-level pressure is found at the centers of tropical cyclones and tornadoes, with a record low of 87 kPa; + */ + if ((currentStatus.MAP >= 87) && (currentStatus.MAP <= 108)) //Check if engine isn't running + LastBaro = currentStatus.baro = currentStatus.MAP; + else + currentStatus.baro = LastBaro; //last baro correction //Perform all initialisations initialiseSchedulers(); @@ -925,7 +934,6 @@ void loop() currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value currentStatus.PW = PW_SD(req_fuel_uS, currentStatus.VE, currentStatus.MAP, currentStatus.corrections, inj_opentime_uS); currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance - currentStatus.adv = get3DTableValue2(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance } else { @@ -933,7 +941,6 @@ void loop() currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.TPS, currentStatus.RPM); //Perform lookup into fuel map for RPM vs TPS value currentStatus.PW = PW_AN(req_fuel_uS, currentStatus.VE, currentStatus.TPS, currentStatus.corrections, inj_opentime_uS); //Calculate pulsewidth using the Alpha-N algorithm (in uS) currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM); //As above, but for ignition advance - currentStatus.adv = get3DTableValue2(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance } //Check for fixed ignition angles @@ -1453,7 +1460,7 @@ void loop() inline void endCoil4Charge() { digitalWrite(pinCoil4, coilLOW); } inline void openInjector5() { digitalWrite(pinInjector5, HIGH); } - inline void closeInjector5() { digitalWrite(pinInjector5, LOW); } + inline void closeInjector5() { digitalWrite(pinInjector5, LOW); } inline void beginCoil5Charge() { digitalWrite(pinCoil5, coilHIGH); digitalWrite(pinTachOut, LOW); } inline void endCoil5Charge() { digitalWrite(pinCoil5, coilLOW); } @@ -1473,3 +1480,6 @@ void beginCoil2and4Charge() { digitalWrite(pinCoil2, coilHIGH); digitalWrite(pin void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoil4, coilLOW); } void nullCallback() { return; } + + + diff --git a/table.ino b/table.ino index 51de2bd..0a56176 100644 --- a/table.ino +++ b/table.ino @@ -9,7 +9,6 @@ Because the size of the table is dynamic, this functino is required to reallocat Note that this may clear some of the existing values of the table */ #include "table.h" -#include "globals.h" void table2D_setSize(struct table2D* targetTable, byte newSize) { @@ -213,52 +212,6 @@ int table2D_getValue(struct table2D *fromTable, int X) } -//This function pulls a value from a 3D table given a target for X and Y coordinates. -//It fix a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf -float get3DTableValue2(struct table3D *fromTable, int Y, int X) -{ - float m, n, o ,p, q, r; - byte xMin, xMax; - byte yMin, yMax; - - for (xMin = fromTable->xSize-1; xMin>=0; xMin--) if(X>fromTable->axisX[xMin]) break; - for (yMin = fromTable->ySize-1; yMin>=0; yMin--) if(Y>fromTable->axisY[yMin]) break; - if (xMin>fromTable->xSize-1) xMin = fromTable->xSize-1; //Overflow protection - if (yMin>fromTable->ySize-1) yMin = fromTable->ySize-1; //Overflow protection - - xMax = xMin + 1; - yMax = yMin + 1; - if (xMax>fromTable->xSize-1) xMax = fromTable->xSize-1; //Overflow protection - if (yMax>fromTable->ySize-1) yMax = fromTable->ySize-1; //Overflow protection - - p = float(X-fromTable->axisX[xMin]) / float(fromTable->axisX[xMax] - fromTable->axisX[xMin]); - q = float(Y-fromTable->axisY[yMin]) / float(fromTable->axisY[yMax] - fromTable->axisY[yMin]); - - /* On http://www.megamanual.com/v22manual/ve_tuner.pdf the interpolation image is fliped - Eg: | ve_turner.pdf | | should be | cause y and x axis is in that order - VE(1,1) VE(1,2) VE(2,1) VE(2,2) ^ - y| - | - VE(2,1) VE(2,2) VE(1,1) VE(1,2) +------------> x - - At this point we have the 4 corners of the map where the interpolated value will fall in - Eg: A=(yMax,xMin) B=(yMax,xMax) - - C=(yMin,xMin) D=(yMin,xMax) - */ - int A = fromTable->values[yMax][xMin]; - int B = fromTable->values[yMax][xMax]; - int C = fromTable->values[yMin][xMin]; - int D = fromTable->values[yMin][xMax]; - - m = (1.0-p) * (1.0-q); - n = p * (1-q); - o = (1-p) * q; - r = p * q; - - return ( (A * m) + (B * n) + (C * o) + (D * r) ); -} - //This function pulls a value from a 3D table given a target for X and Y coordinates. //It performs a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf int get3DTableValue(struct table3D *fromTable, int Y, int X) @@ -406,46 +359,23 @@ int get3DTableValue(struct table3D *fromTable, int Y, int X) //Create some normalised position values //These are essentially percentages (between 0 and 1) of where the desired value falls between the nearest bins on each axis - // Float version - /* - float p, q; - if (xMaxValue == xMinValue) - { p = (float)(X-xMinValue); } - else { p = ((float)(X - xMinValue)) / (float)(xMaxValue - xMinValue); } - if (yMaxValue == yMinValue) - { q = (float)(Y - yMinValue); } - else { q = 1- (((float)(Y - yMaxValue)) / (float)(yMinValue - yMaxValue)); } - - float m = (1.0-p) * (1.0-q); - float n = p * (1-q); - float o = (1-p) * q; - float r = p * q; - - - return ( (A * m) + (B * n) + (C * o) + (D * r) ); - */ - - // Non-Float version: //Initial check incase the values were hit straight on long p; if (xMaxValue == xMinValue) - { p = ((long)(X - xMinValue) << 8); } //This only occurs if the requested X value was equal to one of the X axis bins - else - { + p = ((long)(X - xMinValue) << 8); //This only occurs if the requested X value was equal to one of the X axis bins + else p = ((long)(X - xMinValue) << 8) / (xMaxValue - xMinValue); //This is the standard case - } long q; if (yMaxValue == yMinValue) - { q = ((long)(Y - yMinValue) << 8); } + q = ((long)(Y - yMinValue) << 8); else - { - q = 256 - (((long)(Y - yMaxValue) << 8) / (yMinValue - yMaxValue)); - } + q = 256 - (((long)(Y - yMaxValue) << 8) / (yMinValue - yMaxValue)); + int m = ((256-p) * (256-q)) >> 8; int n = (p * (256-q)) >> 8; int o = ((256-p) * q) >> 8; int r = (p * q) >> 8; return ( (A * m) + (B * n) + (C * o) + (D * r) ) >> 8; - } +} From 7c91a0bbb91a057e3e056f19df91eee9dae4949c Mon Sep 17 00:00:00 2001 From: VitorBoss Date: Tue, 25 Oct 2016 10:22:09 -0200 Subject: [PATCH 10/21] do while loop According to tests this speeds up about 1.2% loops --- speeduino.ino | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/speeduino.ino b/speeduino.ino index 4e17552..b5ef973 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -772,6 +772,8 @@ void setup() } void loop() +{ +do { mainLoopCount++; //Check for any requets from serial. Serial operations are checked under 2 scenarios: @@ -1403,7 +1405,8 @@ void loop() } - } + }while(1); //Some tests result this in a 1.2% faster at 8500RPM +} //************************************************************************************************ //Interrupts From 2641cddfa93a020d5dc23dcdd77557af080eaf88 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Tue, 25 Oct 2016 23:35:39 +1100 Subject: [PATCH 11/21] Revert "do while loop" This reverts commit 7c91a0bbb91a057e3e056f19df91eee9dae4949c. --- speeduino.ino | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/speeduino.ino b/speeduino.ino index b5ef973..4e17552 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -772,8 +772,6 @@ void setup() } void loop() -{ -do { mainLoopCount++; //Check for any requets from serial. Serial operations are checked under 2 scenarios: @@ -1405,8 +1403,7 @@ do } - }while(1); //Some tests result this in a 1.2% faster at 8500RPM -} + } //************************************************************************************************ //Interrupts From 1a5635d7954ad130796b68e86c5277efecb7e774 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 00:24:40 +1100 Subject: [PATCH 12/21] Store previous baro value in EEPROM. Having this in a variable is insufficient --- speeduino.ino | 9 +++++---- storage.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/speeduino.ino b/speeduino.ino index eb91e56..256f7c7 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -100,7 +100,6 @@ unsigned long previousLoopTime; //The time the previous loop started (uS) unsigned long MAPrunningValue; //Used for tracking either the total of all MAP readings in this cycle (Event average) or the lowest value detected in this cycle (event minimum) unsigned int MAPcount; //Number of samples taken in the current MAP cycle byte MAPcurRev = 0; //Tracks which revolution we're sampling on -int LastBaro; //Used for ignore correction if powered on a ruuning engine int CRANK_ANGLE_MAX = 720; int CRANK_ANGLE_MAX_IGN = 360, CRANK_ANGLE_MAX_INJ = 360; // The number of crank degrees that the system track over. 360 for wasted / timed batch and 720 for sequential @@ -234,9 +233,11 @@ void setup() * The lowest measurable sea-level pressure is found at the centers of tropical cyclones and tornadoes, with a record low of 87 kPa; */ if ((currentStatus.MAP >= 87) && (currentStatus.MAP <= 108)) //Check if engine isn't running - LastBaro = currentStatus.baro = currentStatus.MAP; - else - currentStatus.baro = LastBaro; //last baro correction + { + currentStatus.baro = currentStatus.MAP; + EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro); + } + else { currentStatus.baro = EEPROM.read(EEPROM_LAST_BARO); //last baro correction } //Perform all initialisations initialiseSchedulers(); diff --git a/storage.h b/storage.h index 3f562ed..d929aff 100644 --- a/storage.h +++ b/storage.h @@ -96,6 +96,7 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes) #define EEPROM_CONFIG9_YBINS4 1385 //Calibration data is stored at the end of the EEPROM (This is in case any further calibration tables are needed as they are large blocks) +#define EEPROM_LAST_BARO 2558 #define EEPROM_CALIBRATION_O2 2559 #define EEPROM_CALIBRATION_IAT 3071 #define EEPROM_CALIBRATION_CLT 3583 From 2af90436c1612c0157796e4a6c1f1851b66c54f6 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 00:33:19 +1100 Subject: [PATCH 13/21] Fix type corrections that were overwritten --- globals.h | 2 +- sensors.h | 2 ++ sensors.ino | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/globals.h b/globals.h index ccf3051..a7f2006 100644 --- a/globals.h +++ b/globals.h @@ -147,7 +147,7 @@ struct statuses { unsigned int PW; //In uS volatile byte runSecs; //Counter of seconds since cranking commenced (overflows at 255 obviously) volatile byte secl; //Continous - volatile int loopsPerSecond; + volatile unsigned int loopsPerSecond; boolean launchingSoft; //True when in launch control soft limit mode boolean launchingHard; //True when in launch control hard limit mode int freeRAM; diff --git a/sensors.h b/sensors.h index 5d87415..a5ae7cf 100644 --- a/sensors.h +++ b/sensors.h @@ -21,4 +21,6 @@ volatile byte flexCounter = 0; void instanteneousMAPReading(); void readMAP(); +unsigned int tempReading; + #endif // SENSORS_H diff --git a/sensors.ino b/sensors.ino index c320e9c..3b1eb66 100644 --- a/sensors.ino +++ b/sensors.ino @@ -4,8 +4,6 @@ Copyright (C) Josh Stewart A full copy of the license may be found in the projects root directory */ -int tempReading; - void instanteneousMAPReading() { //Instantaneous MAP readings From 3bdeec43f50f2f2be6740c792bcfcaa48fdb35d1 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 00:37:26 +1100 Subject: [PATCH 14/21] I'm reverting these changes as there is no benefit to them. The lines are written this way for clarity as both the 16 and the 2 have specific meanings (See comment) --- auxiliaries.ino | 5 ++--- idle.ino | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/auxiliaries.ino b/auxiliaries.ino index 14c3d70..17e4673 100644 --- a/auxiliaries.ino +++ b/auxiliaries.ino @@ -35,9 +35,8 @@ void initialiseAuxPWM() vvt_pin_port = portOutputRegister(digitalPinToPort(pinVVT_1)); vvt_pin_mask = digitalPinToBitMask(pinVVT_1); - //(16 * configPage3.boostFreq * 2) = (configPage3.boostFreq * 16 * 2) = (configPage3.boostFreq * 32) = (configPage3.boostFreq << 5) - boost_pwm_max_count = 1000000L / (configPage3.boostFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz - vvt_pwm_max_count = 1000000L / (configPage3.vvtFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle + boost_pwm_max_count = 1000000L / (16 * configPage3.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz + vvt_pwm_max_count = 1000000L / (16 * configPage3.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle //TIMSK1 |= (1 << OCIE1A); //Turn on the A compare unit (ie turn on the interrupt) //Shouldn't be needed with closed loop as its turned on below TIMSK1 |= (1 << OCIE1B); //Turn on the B compare unit (ie turn on the interrupt) diff --git a/idle.ino b/idle.ino index 79eedb9..cefb7b6 100644 --- a/idle.ino +++ b/idle.ino @@ -52,8 +52,7 @@ void initialiseIdle() idle_pin_mask = digitalPinToBitMask(pinIdle1); idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2)); idle2_pin_mask = digitalPinToBitMask(pinIdle2); - //(16 * configPage3.idleFreq * 2) = (configPage3.idleFreq * 16 * 2) = (configPage3.idleFreq * 32) = (configPage3.idleFreq << 5) - idle_pwm_max_count = 1000000L / (configPage3.idleFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz + idle_pwm_max_count = 1000000L / (16 * configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz enableIdle(); break; From 6e50a6fc57a8be6645363ed44ee1031c33ddfc46 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 00:42:20 +1100 Subject: [PATCH 15/21] Updates per style guide --- idle.ino | 2 +- table.ino | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/idle.ino b/idle.ino index cefb7b6..3b8e431 100644 --- a/idle.ino +++ b/idle.ino @@ -72,7 +72,7 @@ void initialiseIdle() idle_pin_mask = digitalPinToBitMask(pinIdle1); idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2)); idle2_pin_mask = digitalPinToBitMask(pinIdle2); - idle_pwm_max_count = 1000000L / (configPage3.idleFreq << 5); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz + idle_pwm_max_count = 1000000L / (16 * configPage3.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz idlePID.SetOutputLimits(0, idle_pwm_max_count); idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD); idlePID.SetMode(AUTOMATIC); //Turn PID on diff --git a/table.ino b/table.ino index 0a56176..f277032 100644 --- a/table.ino +++ b/table.ino @@ -362,16 +362,12 @@ int get3DTableValue(struct table3D *fromTable, int Y, int X) //Initial check incase the values were hit straight on long p; - if (xMaxValue == xMinValue) - p = ((long)(X - xMinValue) << 8); //This only occurs if the requested X value was equal to one of the X axis bins - else - p = ((long)(X - xMinValue) << 8) / (xMaxValue - xMinValue); //This is the standard case + if (xMaxValue == xMinValue) { p = ((long)(X - xMinValue) << 8); } //This only occurs if the requested X value was equal to one of the X axis bins + else { p = ((long)(X - xMinValue) << 8) / (xMaxValue - xMinValue); } //This is the standard case long q; - if (yMaxValue == yMinValue) - q = ((long)(Y - yMinValue) << 8); - else - q = 256 - (((long)(Y - yMaxValue) << 8) / (yMinValue - yMaxValue)); + if (yMaxValue == yMinValue) { q = ((long)(Y - yMinValue) << 8); } + else { q = 256 - (((long)(Y - yMaxValue) << 8) / (yMinValue - yMaxValue)); } int m = ((256-p) * (256-q)) >> 8; int n = (p * (256-q)) >> 8; From 991f7c17718495f44d529d40b995fff1bfaed275 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 01:04:37 +1100 Subject: [PATCH 16/21] Number of scope check fixes --- auxiliaries.h | 1 + corrections.h | 2 ++ sensors.h | 1 + sensors.ino | 2 +- speeduino.ino | 20 ++++++++++---------- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/auxiliaries.h b/auxiliaries.h index 42cdf2a..6168e6c 100644 --- a/auxiliaries.h +++ b/auxiliaries.h @@ -4,6 +4,7 @@ void initialiseAuxPWM(); void boostControl(); void vvtControl(); +void initialiseFan(); volatile byte *boost_pin_port; volatile byte boost_pin_mask; diff --git a/corrections.h b/corrections.h index 5344257..134a731 100644 --- a/corrections.h +++ b/corrections.h @@ -5,6 +5,8 @@ All functions in the gamma file return #ifndef CORRECTIONS_H #define CORRECTIONS_H +void initialiseCorrections(); + byte correctionsTotal(); byte correctionWUE(); //Warmup enrichment byte correctionASE(); //After Start Enrichment diff --git a/sensors.h b/sensors.h index a5ae7cf..00b7d4f 100644 --- a/sensors.h +++ b/sensors.h @@ -20,6 +20,7 @@ volatile byte flexCounter = 0; void instanteneousMAPReading(); void readMAP(); +void flexPulse(); unsigned int tempReading; diff --git a/sensors.ino b/sensors.ino index 3b1eb66..5578ac2 100644 --- a/sensors.ino +++ b/sensors.ino @@ -139,7 +139,7 @@ void readBat() * The interrupt function for reading the flex sensor frequency * This value is incremented with every pulse and reset back to 0 once per second */ - void flexPulse() +void flexPulse() { ++flexCounter; } diff --git a/speeduino.ino b/speeduino.ino index 256f7c7..7e67feb 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -209,18 +209,18 @@ void setup() //Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup if(configPage2.IgInv == 1) { coilHIGH = LOW, coilLOW = HIGH; } else { coilHIGH = HIGH, coilLOW = LOW; } - endCoil1Charge(); - endCoil2Charge(); - endCoil3Charge(); - endCoil4Charge(); - endCoil5Charge(); + digitalWrite(pinCoil1, coilLOW); + digitalWrite(pinCoil2, coilLOW); + digitalWrite(pinCoil3, coilLOW); + digitalWrite(pinCoil4, coilLOW); + digitalWrite(pinCoil5, coilLOW); //Similar for injectors, make sure they're turned off - closeInjector1(); - closeInjector2(); - closeInjector3(); - closeInjector4(); - closeInjector5(); + digitalWrite(pinInjector1, HIGH); + digitalWrite(pinInjector2, HIGH); + digitalWrite(pinInjector3, HIGH); + digitalWrite(pinInjector4, HIGH); + digitalWrite(pinInjector5, HIGH); //Set the tacho output default state digitalWrite(pinTachOut, HIGH); From 1d699d18bc25126498d1c10bbbb9a4a971cf6517 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 01:07:47 +1100 Subject: [PATCH 17/21] Fix injector start state being the wrong way in previous commit --- speeduino.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/speeduino.ino b/speeduino.ino index 7e67feb..be0a02a 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -216,11 +216,11 @@ void setup() digitalWrite(pinCoil5, coilLOW); //Similar for injectors, make sure they're turned off - digitalWrite(pinInjector1, HIGH); - digitalWrite(pinInjector2, HIGH); - digitalWrite(pinInjector3, HIGH); - digitalWrite(pinInjector4, HIGH); - digitalWrite(pinInjector5, HIGH); + digitalWrite(pinInjector1, LOW); + digitalWrite(pinInjector2, LOW); + digitalWrite(pinInjector3, LOW); + digitalWrite(pinInjector4, LOW); + digitalWrite(pinInjector5, LOW); //Set the tacho output default state digitalWrite(pinTachOut, HIGH); From 2b902edc75961541d1b6d187cdf992a27986cfef Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 10:21:46 +1100 Subject: [PATCH 18/21] Function prototypes for decoders --- decoders.h | 21 ++++++++++++++++++++- decoders.ino | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/decoders.h b/decoders.h index de07111..797077a 100644 --- a/decoders.h +++ b/decoders.h @@ -1,5 +1,24 @@ +#ifndef DECODERS_H +#define DECODERS_H + #include +static inline void addToothLogEntry(unsigned long toothTime); +static inline int stdGetRPM(); +static inline void setFilter(unsigned long curGap); +static inline int crankingGetRPM(byte totalTeeth); +void triggerSetup_missingTooth(); +void triggerPri_missingTooth(); +void triggerSec_missingTooth(); +int getRPM_missingTooth(); +int getCrankAngle_missingTooth(int timePerDegree); +void triggerSetup_DualWheel(); +void triggerPri_DualWheel(); +void triggerSec_DualWheel(); +int getRPM_DualWheel(); +int getCrankAngle_DualWheel(int timePerDegree); + + volatile unsigned long curTime; volatile unsigned long curGap; volatile unsigned long curTime2; @@ -37,4 +56,4 @@ int toothAngles[24]; //An array for storing fixed tooth angles. Currently sized #define LONG 0; #define SHORT 1; - +#endif diff --git a/decoders.ino b/decoders.ino index 734db7e..4d05485 100644 --- a/decoders.ino +++ b/decoders.ino @@ -71,7 +71,7 @@ This gives much more volatile reading, but is quite useful during cranking, part It can only be used on patterns where the teeth are evently spaced It takes an argument of the full (COMPLETE) number of teeth per revolution. For a missing tooth wheel, this is the number if the tooth had NOT been missing (Eg 36-1 = 36) */ -inline int crankingGetRPM(byte totalTeeth) +static inline int crankingGetRPM(byte totalTeeth) { noInterrupts(); revolutionTime = (toothLastToothTime - toothLastMinusOneToothTime) * totalTeeth; From 8d9ff50eaef17dd3b634be15132cb7ac94476fb0 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 10:30:12 +1100 Subject: [PATCH 19/21] Define the bar max and min values --- sensors.h | 3 +++ speeduino.ino | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sensors.h b/sensors.h index 00b7d4f..731c852 100644 --- a/sensors.h +++ b/sensors.h @@ -9,6 +9,9 @@ #define ADCFILTER_O2 128 #define ADCFILTER_BAT 128 +#define BARO_MIN 87 +#define BARO_MAX 108 + volatile byte flexCounter = 0; /* diff --git a/speeduino.ino b/speeduino.ino index be0a02a..4f62fad 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -232,12 +232,12 @@ void setup() * with record highs close to 108.5 kPa. * The lowest measurable sea-level pressure is found at the centers of tropical cyclones and tornadoes, with a record low of 87 kPa; */ - if ((currentStatus.MAP >= 87) && (currentStatus.MAP <= 108)) //Check if engine isn't running + if ((currentStatus.MAP >= BARO_MIN) && (currentStatus.MAP <= BARO_MAX)) //Check if engine isn't running { currentStatus.baro = currentStatus.MAP; EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro); } - else { currentStatus.baro = EEPROM.read(EEPROM_LAST_BARO); //last baro correction } + else { currentStatus.baro = EEPROM.read(EEPROM_LAST_BARO); } //last baro correction //Perform all initialisations initialiseSchedulers(); From 7345b73167912f8905b55cc58bf19290ca540cfc Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 10:38:39 +1100 Subject: [PATCH 20/21] Add digitalWriteFast to src directory (It's effectively a lib) --- speeduino.ino | 1 + digitalWriteFast.h => src/DigitalWriteFast/digitalWriteFast.h | 0 2 files changed, 1 insertion(+) rename digitalWriteFast.h => src/DigitalWriteFast/digitalWriteFast.h (100%) diff --git a/speeduino.ino b/speeduino.ino index 4f62fad..9bccc6c 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "fastAnalog.h" #include "sensors.h" #include "src/PID_v1/PID_v1.h" +//#include "src/DigitalWriteFast/digitalWriteFast.h" #include "errors.h" #ifdef __SAM3X8E__ diff --git a/digitalWriteFast.h b/src/DigitalWriteFast/digitalWriteFast.h similarity index 100% rename from digitalWriteFast.h rename to src/DigitalWriteFast/digitalWriteFast.h From 216aec6590e2cc46ce1e2e9249fe92a167d6ae04 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 26 Oct 2016 10:41:23 +1100 Subject: [PATCH 21/21] Setup math.h properly --- math.h | 96 ++------------------------------------------------------ math.ino | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 94 deletions(-) create mode 100644 math.ino diff --git a/math.h b/math.h index 128ddb9..bf94c51 100644 --- a/math.h +++ b/math.h @@ -1,98 +1,6 @@ #ifndef MATH_H #define MATH_H -//Replace the standard arduino map() function to use the div function instead -int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max) -{ - return ldiv( ((x - in_min) * (out_max - out_min)) , (in_max - in_min) ).quot + out_min; - //return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} +int fastMap1023toX(unsigned long x, int out_max); -//This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range -//This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings) -//int fastMap1023toX(unsigned long x, int in_min, int in_max, int out_min, int out_max) -//removed ununsed variables, in_min and out_min is aways 0, in_max is aways 1023 -int fastMap1023toX(unsigned long x, int out_max) -{ - return (x * out_max) >> 10; -} - -/* -The following are all fast versions of specific divisions -Ref: http://www.hackersdelight.org/divcMore.pdf -*/ - -//Unsigned divide by 10 -unsigned int divu10(unsigned int n) { - unsigned long q, r; - q = (n >> 1) + (n >> 2); - q = q + (q >> 4); - q = q + (q >> 8); - q = q + (q >> 16); - q = q >> 3; - r = n - q*10; - return q + ((r + 6) >> 4); -// return q + (r > 9); -} - -//Signed divide by 10 -int divs10(long n) { - long q, r; - n = n + (n>>31 & 9); - q = (n >> 1) + (n >> 2); - q = q + (q >> 4); - q = q + (q >> 8); - q = q + (q >> 16); - q = q >> 3; - r = n - q*10; - return q + ((r + 6) >> 4); -// return q + (r > 9); -} - -//Signed divide by 100 -int divs100(long n) { - return (n / 100); // Amazingly, gcc is producing a better /divide by 100 function than this - long q, r; - n = n + (n>>31 & 99); - q = (n >> 1) + (n >> 3) + (n >> 6) - (n >> 10) + - (n >> 12) + (n >> 13) - (n >> 16); - q = q + (q >> 20); - q = q >> 6; - r = n - q*100; - return q + ((r + 28) >> 7); -// return q + (r > 99); -} - -//Unsigned divide by 100 -unsigned long divu100(unsigned long n) { - //return (n / 100); // No difference with this on/off - unsigned long q, r; - q = (n >> 1) + (n >> 3) + (n >> 6) - (n >> 10) + - (n >> 12) + (n >> 13) - (n >> 16); - q = q + (q >> 20); - q = q >> 6; - r = n - q*100; - return q + ((r + 28) >> 7); -// return q + (r > 99); -} - -//Return x percent of y -//This is a relatively fast approximation of a percentage value. -unsigned long percentage(byte x, unsigned long y) -{ - return (y * x) / 100; //For some reason this is faster - //return divu100(y * x); -} - -/* - * Calculates integer power values. Same as pow() but with ints - */ -inline long powint(int factor, unsigned int exponent) -{ - long product = 1; - while (exponent--) - product *= factor; - return product; -} - -#endif // MATH_H +#endif diff --git a/math.ino b/math.ino new file mode 100644 index 0000000..3237a19 --- /dev/null +++ b/math.ino @@ -0,0 +1,95 @@ + + +//Replace the standard arduino map() function to use the div function instead +int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max) +{ + return ldiv( ((x - in_min) * (out_max - out_min)) , (in_max - in_min) ).quot + out_min; + //return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +//This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range +//This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings) +//int fastMap1023toX(unsigned long x, int in_min, int in_max, int out_min, int out_max) +//removed ununsed variables, in_min and out_min is aways 0, in_max is aways 1023 +int fastMap1023toX(unsigned long x, int out_max) +{ + return (x * out_max) >> 10; +} + +/* +The following are all fast versions of specific divisions +Ref: http://www.hackersdelight.org/divcMore.pdf +*/ + +//Unsigned divide by 10 +unsigned int divu10(unsigned int n) { + unsigned long q, r; + q = (n >> 1) + (n >> 2); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); + q = q >> 3; + r = n - q*10; + return q + ((r + 6) >> 4); +// return q + (r > 9); +} + +//Signed divide by 10 +int divs10(long n) { + long q, r; + n = n + (n>>31 & 9); + q = (n >> 1) + (n >> 2); + q = q + (q >> 4); + q = q + (q >> 8); + q = q + (q >> 16); + q = q >> 3; + r = n - q*10; + return q + ((r + 6) >> 4); +// return q + (r > 9); +} + +//Signed divide by 100 +int divs100(long n) { + return (n / 100); // Amazingly, gcc is producing a better /divide by 100 function than this + long q, r; + n = n + (n>>31 & 99); + q = (n >> 1) + (n >> 3) + (n >> 6) - (n >> 10) + + (n >> 12) + (n >> 13) - (n >> 16); + q = q + (q >> 20); + q = q >> 6; + r = n - q*100; + return q + ((r + 28) >> 7); +// return q + (r > 99); +} + +//Unsigned divide by 100 +unsigned long divu100(unsigned long n) { + //return (n / 100); // No difference with this on/off + unsigned long q, r; + q = (n >> 1) + (n >> 3) + (n >> 6) - (n >> 10) + + (n >> 12) + (n >> 13) - (n >> 16); + q = q + (q >> 20); + q = q >> 6; + r = n - q*100; + return q + ((r + 28) >> 7); +// return q + (r > 99); +} + +//Return x percent of y +//This is a relatively fast approximation of a percentage value. +unsigned long percentage(byte x, unsigned long y) +{ + return (y * x) / 100; //For some reason this is faster + //return divu100(y * x); +} + +/* + * Calculates integer power values. Same as pow() but with ints + */ +inline long powint(int factor, unsigned int exponent) +{ + long product = 1; + while (exponent--) + product *= factor; + return product; +}