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/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; diff --git a/globals.h b/globals.h index 5b88dc0..a7f2006 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 diff --git a/math.h b/math.h index e671cd9..bf94c51 100644 --- a/math.h +++ b/math.h @@ -1,96 +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) -{ - 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; +} diff --git a/sensors.h b/sensors.h index 5d87415..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; /* @@ -20,5 +23,8 @@ volatile byte flexCounter = 0; void instanteneousMAPReading(); void readMAP(); +void flexPulse(); + +unsigned int tempReading; #endif // SENSORS_H diff --git a/sensors.ino b/sensors.ino index 0c2b8bf..5578ac2 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 */ -unsigned int tempReading; - void instanteneousMAPReading() { //Instantaneous MAP readings @@ -16,7 +14,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 +49,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 +75,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 +88,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 +101,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 +109,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 +117,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 +131,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); } @@ -141,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 59f22f0..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__ @@ -227,7 +228,17 @@ void setup() //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 >= 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 //Perform all initialisations initialiseSchedulers(); @@ -1494,3 +1505,4 @@ void endCoil2and4Charge() { digitalWrite(pinCoil2, coilLOW); digitalWrite(pinCoi void nullCallback() { return; } + diff --git a/src/DigitalWriteFast/digitalWriteFast.h b/src/DigitalWriteFast/digitalWriteFast.h new file mode 100644 index 0000000..b2676a7 --- /dev/null +++ b/src/DigitalWriteFast/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/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 diff --git a/table.ino b/table.ino index 6882c28..f277032 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,8 +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 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) @@ -358,50 +355,23 @@ 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 - // 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) / (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; int o = ((256-p) * q) >> 8; int r = (p * q) >> 8; return ( (A * m) + (B * n) + (C * o) + (D * r) ) >> 8; - } +}