Merge pull request #54 from noisymime/pr/50

Merging branch Pr/50 (Closes #50)
This commit is contained in:
Josh Stewart 2016-10-26 10:43:20 +11:00 committed by GitHub
commit 903381160c
13 changed files with 375 additions and 144 deletions

View File

@ -4,6 +4,7 @@
void initialiseAuxPWM();
void boostControl();
void vvtControl();
void initialiseFan();
volatile byte *boost_pin_port;
volatile byte boost_pin_mask;

View File

@ -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

View File

@ -1,5 +1,24 @@
#ifndef DECODERS_H
#define DECODERS_H
#include <limits.h>
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

View File

@ -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;

View File

@ -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

94
math.h
View File

@ -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

95
math.ino Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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; }

View File

@ -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_

View File

@ -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

View File

@ -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;
}
}