Merge remote-tracking branch 'refs/remotes/noisymime/master'

This commit is contained in:
VitorBoss 2016-10-26 10:28:43 -02:00
commit 011d625bd4
19 changed files with 477 additions and 185 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

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

View File

@ -661,7 +661,7 @@ void sendPage(bool useChar)
}
case seqFuelPage:
{
byte response[200]; //Bit hacky, but the size is: (8x8 + 8 + 8) + (8x8 + 8 + 8) = 160
byte response[200]; //The size is: (6x6 + 6 + 6) * 4 + 8 (Leftover values)
for (int x = 0; x < 200; x++) { 0; }
@ -748,9 +748,12 @@ void sendPage(bool useChar)
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
byte response[map_page_size];
for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - x / 16][x % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged
for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - x / 16][x % 16]; if ( (x & 15) == 1) { loop(); } } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
loop();
for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / 100); } //RPM Bins for VE table (Need to be dvidied by 100)
loop();
for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)]); } //MAP or TPS bins for VE table
loop();
Serial.write((byte *)&response, sizeof(response));
}
}
@ -773,6 +776,7 @@ void sendPage(bool useChar)
for (byte x = 0; x < page_size; x++)
{
response[x] = *((byte *)pnt_configPage + x); //Each byte is simply the location in memory of the configPage + the offset + the variable number (x)
if ( (x & 31) == 1) { loop(); } //Every 32 loops, do a manual call to loop() to ensure that there is no misses
}
Serial.write((byte *)&response, sizeof(response));
// }
@ -911,6 +915,7 @@ void sendToothLog(bool useChar)
}
BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY);
}
toothLogRead = true;
}
void testComm()

36
contributing.md Normal file
View File

@ -0,0 +1,36 @@
# How to contribute
The Speeduino project is always looking for new contributors so thanks for your interest in this!
If you haven't already, jump onto our Slack team as that is where most of the development discussion takes place: https://speeduino.com/forum/app.php/page/slack
Here are some important resources:
* [Coding style guide](http://speeduino.com/wiki/index.php/Style_code)
* [Project forum](https://speeduino.com/forum)
* [Slack team](https://speeduino.com/forum/app.php/page/slack)
## Testing
All contributions should be in a working, compilable state. If your change does not compile cleanly it will be rejected immediately.
## Submitting changes
Please send a [GitHub Pull Request to Speeduino](https://github.com/noisymime/speeduino/pull/new/master) with a clear list of what you've done (read more about [pull requests](http://help.github.com/pull-requests/)).
Please try to make each pull request atomic, that is, there should be a single defined intent or feature for the pull request. If you are adding multiple features or fixing different bugs, please split these up and submit multiple pull requests.
Always write a clear log message for your commits. One-line messages are fine for small changes, but bigger changes should look like this:
$ git commit -m "A brief summary of the commit
>
> A paragraph describing what changed and its impact."
## Contributor Licensing
Note that all contributions to the project are made under the Github Contributor Lincensing Agreement: https://cla.github.com/agreement
This ensures that all contributions made to the project are licensed in the same way as the existing work. Such an agreement is not intended to deprive contributors of their copyright, but to protect the project from claims by malicious contributors.
## Coding conventions
The coding style guide can be found on the project wiki: http://speeduino.com/wiki/index.php/Style_code

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;
@ -18,6 +37,7 @@ volatile unsigned long toothOneMinusOneTime = 0; //The 2nd to last time (micros(
volatile bool revolutionOne = 0; // For sequential operation, this tracks whether the current revolution is 1 or 2 (not 1)
volatile unsigned int toothHistory[TOOTH_LOG_BUFFER];
volatile unsigned int toothHistoryIndex = 0;
volatile bool toothLogRead = false; //Flag to indicate whether the current tooth log values have been read out yet
volatile byte secondaryToothCount; //Used for identifying the current secondary (Usually cam) tooth for patterns with multiple secondary teeth
volatile unsigned long secondaryLastToothTime = 0; //The time (micros()) that the last tooth was registered (Cam input)
@ -36,4 +56,4 @@ int toothAngles[24]; //An array for storing fixed tooth angles. Currently sized
#define LONG 0;
#define SHORT 1;
#endif

View File

@ -21,12 +21,19 @@ toothLastToothTime - The time (In uS) that the last primary tooth was 'seen'
*/
static inline void addToothLogEntry(unsigned long time)
static inline void addToothLogEntry(unsigned long toothTime)
{
//High speed tooth logging history
toothHistory[toothHistoryIndex] = time;
toothHistory[toothHistoryIndex] = toothTime;
if(toothHistoryIndex == (TOOTH_LOG_BUFFER-1))
{ toothHistoryIndex = 0; BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY); } //The tooth log ready bit is cleared to ensure that we only get a set of concurrent values.
{
if (toothLogRead)
{
toothHistoryIndex = 0;
BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY);
toothLogRead = false; //The tooth log ready bit is cleared to ensure that we only get a set of concurrent values.
}
}
else
{ toothHistoryIndex++; }
}
@ -64,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;
@ -106,6 +113,7 @@ void triggerPri_missingTooth()
if ( curGap > targetGap || toothCurrentCount > triggerActualTeeth)
{
if(toothCurrentCount < (triggerActualTeeth) && currentStatus.hasSync) { currentStatus.hasSync = false; return; } //This occurs when we're at tooth #1, but haven't seen all the other teeth. This indicates a signal issue so we flag lost sync so this will attempt to resync on the next revolution.
toothCurrentCount = 1;
revolutionOne = !revolutionOne; //Flip sequential revolution tracker
toothOneMinusOneTime = toothOneTime;

View File

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

View File

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

96
math.h
View File

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

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

@ -496,7 +496,15 @@ page = 9
fuelTrim4loadBins = array, U08, 186,[ 6], "TPS", 1.0, 0.0, 0.0, 255.0, 0
#endif
unused9-192 = scalar, U08, 192, "RPM", 100.0, 0.0, 100, 25500, 0
fuelTrimEnabled = bits, U08, 192, [0:0], "No", "Yes"
unused9-192b = bits, U08, 192, [1:1], "No", "Yes"
unused9-192c = bits, U08, 192, [2:2], "No", "Yes"
unused9-192d = bits, U08, 192, [3:3], "No", "Yes"
unused9-192e = bits, U08, 192, [4:4], "No", "Yes"
unused9-192f = bits, U08, 192, [5:5], "No", "Yes"
unused9-192g = bits, U08, 192, [6:6], "No", "Yes"
unused9-192h = bits, U08, 192, [7:7], "No", "Yes"
unused9-193 = scalar, U08, 193, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-194 = scalar, U08, 194, "RPM", 100.0, 0.0, 100, 25500, 0
unused9-195 = scalar, U08, 195, "RPM", 100.0, 0.0, 100, 25500, 0
@ -1000,13 +1008,13 @@ menuDialog = main
;Fuel trim composite dialog
dialog = inj_trim1TblTitle, "Channel #1"
panel = fuelTrimTable1Tbl, Center
panel = fuelTrimTable1Tbl, Center, { fuelTrimEnabled }
dialog = inj_trim2TblTitle, "Channel #2"
panel = fuelTrimTable1Tbl
panel = fuelTrimTable2Tbl, { fuelTrimEnabled }
dialog = inj_trim3TblTitle, "Channel #3"
panel = fuelTrimTable1Tbl
panel = fuelTrimTable3Tbl, { fuelTrimEnabled }
dialog = inj_trim4TblTitle, "Channel #4"
panel = fuelTrimTable1Tbl
panel = fuelTrimTable4Tbl, { fuelTrimEnabled }
dialog = inj_trimadt, "", xAxis
panel = inj_trim1TblTitle
@ -1016,9 +1024,9 @@ menuDialog = main
panel = inj_trim4TblTitle
dialog = inj_trimad,"Injector Cyl 1-4 Trims", yAxis
topicHelp = "file://$getProjectsDirPath()/docs/Megasquirt3_TunerStudio_MS_Lite_Reference-1.4.pdf#injtrim1-4"
panel = inj_trimadt
panel = inj_trimadb
field = "Individual fuel trim enabled", fuelTrimEnabled
panel = inj_trimadt, North
panel = inj_trimadb, South
;-------------------------------------------------------------------------------
; General help text
@ -1198,19 +1206,62 @@ menuDialog = main
upDownLabel = "HIGHER", "LOWER"
;--------- Sequential fuel trim maps -----------
table = fuelTrimTable1Tbl, fuelTrimTable1Map, "Fuel trim Table", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim1rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim1loadBins, map
#else
yBins = fuelTrim1loadBins, throttle
#endif
zBins = fuelTrim1Table
table = fuelTrimTable1Tbl, fuelTrimTable1Map, "Fuel trim Table", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim1rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim1loadBins, map
#else
yBins = fuelTrim1loadBins, throttle
#endif
zBins = fuelTrim1Table
gridHeight = 2.0
gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees.
upDownLabel = "(RICHER)", "(LEANER)"
gridHeight = 2.0
gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees.
upDownLabel = "(RICHER)", "(LEANER)"
table = fuelTrimTable2Tbl, fuelTrimTable2Map, "Fuel trim Table", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim2rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim2loadBins, map
#else
yBins = fuelTrim2loadBins, throttle
#endif
zBins = fuelTrim2Table
gridHeight = 2.0
gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees.
upDownLabel = "(RICHER)", "(LEANER)"
table = fuelTrimTable3Tbl, fuelTrimTable3Map, "Fuel trim Table", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim3rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim3loadBins, map
#else
yBins = fuelTrim3loadBins, throttle
#endif
zBins = fuelTrim3Table
gridHeight = 2.0
gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees.
upDownLabel = "(RICHER)", "(LEANER)"
table = fuelTrimTable4Tbl, fuelTrimTable4Map, "Fuel trim Table", 9
topicHelp = "http://speeduino.com/wiki/index.php/Tuning"
xBins = fuelTrim4rpmBins, rpm
#if SPEED_DENSITY
yBins = fuelTrim4loadBins, map
#else
yBins = fuelTrim4loadBins, throttle
#endif
zBins = fuelTrim4Table
gridHeight = 2.0
gridOrient = 250, 0, 340 ; Space 123 rotation of grid in degrees.
upDownLabel = "(RICHER)", "(LEANER)"
;-------------------------------------------------------------------------------

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
*/
int tempReading;
void instanteneousMAPReading()
{
//Instantaneous MAP readings
@ -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__
@ -74,6 +75,10 @@ struct table3D ignitionTable; //16x16 ignition map
struct table3D afrTable; //16x16 afr target map
struct table3D boostTable; //8x8 boost map
struct table3D vvtTable; //8x8 vvt map
struct table3D trim1Table; //6x6 Fuel trim 1 map
struct table3D trim2Table; //6x6 Fuel trim 2 map
struct table3D trim3Table; //6x6 Fuel trim 3 map
struct table3D trim4Table; //6x6 Fuel trim 4 map
struct table2D taeTable; //4 bin TPS Acceleration Enrichment map (2D)
struct table2D WUETable; //10 bin Warm Up Enrichment map (2D)
struct table2D dwellVCorrectionTable; //6 bin dwell voltage correction (2D)
@ -96,7 +101,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
@ -164,6 +168,10 @@ void setup()
table3D_setSize(&afrTable, 16);
table3D_setSize(&boostTable, 8);
table3D_setSize(&vvtTable, 8);
table3D_setSize(&trim1Table, 6);
table3D_setSize(&trim2Table, 6);
table3D_setSize(&trim3Table, 6);
table3D_setSize(&trim4Table, 6);
loadConfig();
@ -202,18 +210,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, LOW);
digitalWrite(pinInjector2, LOW);
digitalWrite(pinInjector3, LOW);
digitalWrite(pinInjector4, LOW);
digitalWrite(pinInjector5, LOW);
//Set the tacho output default state
digitalWrite(pinTachOut, HIGH);
@ -225,10 +233,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
LastBaro = currentStatus.baro = currentStatus.MAP;
else
currentStatus.baro = LastBaro; //last baro correction
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();
@ -747,6 +757,19 @@ void setup()
ign5EndFunction = endCoil5Charge;
}
break;
case IGN_MODE_SEQUENTIAL:
ign1StartFunction = beginCoil1Charge;
ign1EndFunction = endCoil1Charge;
ign2StartFunction = beginCoil2Charge;
ign2EndFunction = endCoil2Charge;
ign3StartFunction = beginCoil3Charge;
ign3EndFunction = endCoil3Charge;
ign4StartFunction = beginCoil4Charge;
ign4EndFunction = endCoil4Charge;
ign5StartFunction = beginCoil5Charge;
ign5EndFunction = endCoil5Charge;
break;
default:
//Wasted spark (Shouldn't ever happen anyway)
@ -772,8 +795,6 @@ void setup()
}
void loop()
{
do
{
mainLoopCount++;
//Check for any requets from serial. Serial operations are checked under 2 scenarios:
@ -884,7 +905,7 @@ do
//And check whether the tooth log buffer is ready
if(toothHistoryIndex > TOOTH_LOG_SIZE) { BIT_SET(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY); }
}
if(toothHistoryIndex > TOOTH_LOG_SIZE) { BIT_SET(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY); }
//The IAT and CLT readings can be done less frequently. This still runs about 4 times per second
if ((mainLoopCount & 255) == 1)
{
@ -1405,8 +1426,7 @@ do
}
}while(1); //Some tests result this in a 1.2% faster at 8500RPM
}
}
//************************************************************************************************
//Interrupts

View File

@ -39,42 +39,64 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
-----------------------------------------------------
*/
#define EEPROM_CONFIG1_XSIZE 1
#define EEPROM_CONFIG1_YSIZE 2
#define EEPROM_CONFIG1_MAP 3
#define EEPROM_CONFIG1_XBINS 259
#define EEPROM_CONFIG1_YBINS 275
#define EEPROM_CONFIG2_START 291
#define EEPROM_CONFIG2_END 355 // +64 131
#define EEPROM_CONFIG3_XSIZE 355
#define EEPROM_CONFIG3_YSIZE 356
#define EEPROM_CONFIG3_MAP 357
#define EEPROM_CONFIG3_XBINS 613
#define EEPROM_CONFIG3_YBINS 629
#define EEPROM_CONFIG4_START 645
#define EEPROM_CONFIG4_END 709
#define EEPROM_CONFIG5_XSIZE 709
#define EEPROM_CONFIG5_YSIZE 710
#define EEPROM_CONFIG5_MAP 711
#define EEPROM_CONFIG5_XBINS 967
#define EEPROM_CONFIG5_YBINS 983
#define EEPROM_CONFIG6_START 999
#define EEPROM_CONFIG6_END 1063
#define EEPROM_CONFIG7_START 1063
#define EEPROM_CONFIG7_END 1127
#define EEPROM_CONFIG1_XSIZE 1
#define EEPROM_CONFIG1_YSIZE 2
#define EEPROM_CONFIG1_MAP 3
#define EEPROM_CONFIG1_XBINS 259
#define EEPROM_CONFIG1_YBINS 275
#define EEPROM_CONFIG2_START 291
#define EEPROM_CONFIG2_END 355 // +64 131
#define EEPROM_CONFIG3_XSIZE 355
#define EEPROM_CONFIG3_YSIZE 356
#define EEPROM_CONFIG3_MAP 357
#define EEPROM_CONFIG3_XBINS 613
#define EEPROM_CONFIG3_YBINS 629
#define EEPROM_CONFIG4_START 645
#define EEPROM_CONFIG4_END 709
#define EEPROM_CONFIG5_XSIZE 709
#define EEPROM_CONFIG5_YSIZE 710
#define EEPROM_CONFIG5_MAP 711
#define EEPROM_CONFIG5_XBINS 967
#define EEPROM_CONFIG5_YBINS 983
#define EEPROM_CONFIG6_START 999
#define EEPROM_CONFIG6_END 1063
#define EEPROM_CONFIG7_START 1063
#define EEPROM_CONFIG7_END 1127
#define EEPROM_CONFIG8_XSIZE1 1127
#define EEPROM_CONFIG8_YSIZE1 1128
#define EEPROM_CONFIG8_MAP1 1129
#define EEPROM_CONFIG8_MAP1 1129
#define EEPROM_CONFIG8_XBINS1 1193
#define EEPROM_CONFIG8_YBINS1 1201
#define EEPROM_CONFIG8_XSIZE2 1209
#define EEPROM_CONFIG8_YSIZE2 1210
#define EEPROM_CONFIG8_MAP2 1211
#define EEPROM_CONFIG8_MAP2 1211
#define EEPROM_CONFIG8_XBINS2 1275
#define EEPROM_CONFIG8_YBINS2 1283
#define EEPROM_CONFIG8_END 1291
#define EEPROM_CONFIG8_END 1291
#define EEPROM_CONFIG9_XSIZE1 1291
#define EEPROM_CONFIG9_YSIZE1 1292
#define EEPROM_CONFIG9_MAP1 1293
#define EEPROM_CONFIG9_XBINS1 1329
#define EEPROM_CONFIG9_YBINS1 1335
#define EEPROM_CONFIG9_XSIZE2 1341
#define EEPROM_CONFIG9_YSIZE2 1342
#define EEPROM_CONFIG9_MAP2 1343
#define EEPROM_CONFIG9_XBINS2 1379
#define EEPROM_CONFIG9_YBINS2 1385
//BELOW VALUES NOT YET RIGHT!!
#define EEPROM_CONFIG9_XSIZE3 1341
#define EEPROM_CONFIG9_YSIZE3 1342
#define EEPROM_CONFIG9_MAP3 1343
#define EEPROM_CONFIG9_XBINS3 1379
#define EEPROM_CONFIG9_YBINS3 1385
#define EEPROM_CONFIG9_XSIZE4 1341
#define EEPROM_CONFIG9_YSIZE4 1342
#define EEPROM_CONFIG9_MAP4 1343
#define EEPROM_CONFIG9_XBINS4 1379
#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

@ -196,6 +196,74 @@ void writeConfig()
if(EEPROM.read(y) != vvtTable.axisY[offset]) { EEPROM.write(y, vvtTable.axisY[offset]); }
y++;
}
/*---------------------------------------------------
| Fuel trim tables (See storage.h for data layout) - Page 9
| 6x6 tables itself + the 6 values along each of the axis
-----------------------------------------------------*/
//Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1)
EEPROM.update(EEPROM_CONFIG9_XSIZE1,trim1Table.xSize); //Write the boost Table RPM dimension size
EEPROM.update(EEPROM_CONFIG9_YSIZE1,trim1Table.ySize); //Write the boost Table MAP/TPS dimension size
EEPROM.update(EEPROM_CONFIG9_XSIZE2,trim2Table.xSize); //Write the boost Table RPM dimension size
EEPROM.update(EEPROM_CONFIG9_YSIZE2,trim2Table.ySize); //Write the boost Table MAP/TPS dimension size
EEPROM.update(EEPROM_CONFIG9_XSIZE3,trim3Table.xSize); //Write the boost Table RPM dimension size
EEPROM.update(EEPROM_CONFIG9_YSIZE3,trim3Table.ySize); //Write the boost Table MAP/TPS dimension size
EEPROM.update(EEPROM_CONFIG9_XSIZE4,trim4Table.xSize); //Write the boost Table RPM dimension size
EEPROM.update(EEPROM_CONFIG9_YSIZE4,trim4Table.ySize); //Write the boost Table MAP/TPS dimension size
y = EEPROM_CONFIG9_MAP2; //We do the 4 maps together in the same loop
int z = EEPROM_CONFIG9_MAP3; //We do the 4 maps together in the same loop
int i = EEPROM_CONFIG9_MAP4; //We do the 4 maps together in the same loop
for(int x=EEPROM_CONFIG9_MAP1; x<EEPROM_CONFIG9_XBINS1; x++)
{
offset = x - EEPROM_CONFIG9_MAP1;
EEPROM.update(x, trim1Table.values[5-offset/6][offset%6]); //Write the 6x6 map
offset = y - EEPROM_CONFIG9_MAP2;
EEPROM.update(y, trim2Table.values[5-offset/6][offset%6]); //Write the 6x6 map
offset = z - EEPROM_CONFIG9_MAP3;
EEPROM.update(z, trim3Table.values[5-offset/6][offset%6]); //Write the 6x6 map
offset = i - EEPROM_CONFIG9_MAP4;
EEPROM.update(i, trim4Table.values[5-offset/6][offset%6]); //Write the 6x6 map
y++;
z++;
i++;
}
//RPM bins
y = EEPROM_CONFIG9_XBINS2;
z = EEPROM_CONFIG9_XBINS3;
i = EEPROM_CONFIG9_XBINS4;
for(int x=EEPROM_CONFIG9_XBINS1; x<EEPROM_CONFIG9_YBINS1; x++)
{
offset = x - EEPROM_CONFIG9_XBINS1;
EEPROM.update(x, byte(trim1Table.axisX[offset]/100)); //RPM bins are divided by 100 and converted to a byte
offset = y - EEPROM_CONFIG9_XBINS2;
EEPROM.update(y, byte(trim2Table.axisX[offset]/100)); //RPM bins are divided by 100 and converted to a byte
offset = z - EEPROM_CONFIG9_XBINS3;
EEPROM.update(z, byte(trim3Table.axisX[offset]/100)); //RPM bins are divided by 100 and converted to a byte
offset = i - EEPROM_CONFIG9_XBINS4;
EEPROM.update(i, byte(trim4Table.axisX[offset]/100)); //RPM bins are divided by 100 and converted to a byte
y++;
z++;
i++;
}
//TPS/MAP bins
y=EEPROM_CONFIG9_YBINS2;
z=EEPROM_CONFIG9_YBINS3;
i=EEPROM_CONFIG9_YBINS4;
for(int x=EEPROM_CONFIG9_YBINS1; x<EEPROM_CONFIG9_XSIZE2; x++)
{
offset = x - EEPROM_CONFIG9_YBINS1;
EEPROM.update(x, trim1Table.axisY[offset]);
offset = y - EEPROM_CONFIG9_YBINS2;
EEPROM.update(y, trim2Table.axisY[offset]);
offset = z - EEPROM_CONFIG9_YBINS3;
EEPROM.update(z, trim3Table.axisY[offset]);
offset = i - EEPROM_CONFIG9_YBINS4;
EEPROM.update(i, trim4Table.axisY[offset]);
y++;
z++;
i++;
}
}
void loadConfig()
@ -342,6 +410,64 @@ void loadConfig()
vvtTable.axisY[offset] = EEPROM.read(y);
y++;
}
//*********************************************************************************************************************************************************************************
// Fuel trim tables load
y = EEPROM_CONFIG9_MAP2;
int z = EEPROM_CONFIG9_MAP3;
int i = EEPROM_CONFIG9_MAP4;
for(int x=EEPROM_CONFIG9_MAP1; x<EEPROM_CONFIG9_XBINS1; x++)
{
offset = x - EEPROM_CONFIG9_MAP1;
trim1Table.values[5-offset/6][offset%6] = EEPROM.read(x); //Read the 6x6 map
offset = y - EEPROM_CONFIG9_MAP2;
trim2Table.values[5-offset/6][offset%6] = EEPROM.read(y); //Read the 6x6 map
offset = z - EEPROM_CONFIG9_MAP3;
trim3Table.values[5-offset/6][offset%6] = EEPROM.read(z); //Read the 6x6 map
offset = i - EEPROM_CONFIG9_MAP4;
trim4Table.values[5-offset/6][offset%6] = EEPROM.read(i); //Read the 6x6 map
y++;
z++;
i++;
}
//RPM bins
y = EEPROM_CONFIG9_XBINS2;
z = EEPROM_CONFIG9_XBINS3;
i = EEPROM_CONFIG9_XBINS4;
for(int x=EEPROM_CONFIG9_XBINS1; x<EEPROM_CONFIG9_YBINS1; x++)
{
offset = x - EEPROM_CONFIG9_XBINS1;
trim1Table.axisX[offset] = (EEPROM.read(x) * 100); //RPM bins are divided by 100 when stored. Multiply them back now
offset = y - EEPROM_CONFIG9_XBINS2;
trim2Table.axisX[offset] = (EEPROM.read(y) * 100); //RPM bins are divided by 100 when stored. Multiply them back now
offset = z - EEPROM_CONFIG9_XBINS3;
trim3Table.axisX[offset] = (EEPROM.read(z) * 100); //RPM bins are divided by 100 when stored. Multiply them back now
offset = i - EEPROM_CONFIG9_XBINS4;
trim4Table.axisX[offset] = (EEPROM.read(i) * 100); //RPM bins are divided by 100 when stored. Multiply them back now
y++;
z++;
i++;
}
//TPS/MAP bins
y = EEPROM_CONFIG9_YBINS2;
z = EEPROM_CONFIG9_YBINS3;
i = EEPROM_CONFIG9_YBINS4;
for(int x=EEPROM_CONFIG9_YBINS1; x<EEPROM_CONFIG9_XSIZE2; x++)
{
offset = x - EEPROM_CONFIG9_YBINS1;
trim1Table.axisY[offset] = EEPROM.read(x);
offset = y - EEPROM_CONFIG9_YBINS2;
trim2Table.axisY[offset] = EEPROM.read(y);
offset = z - EEPROM_CONFIG9_YBINS3;
trim3Table.axisY[offset] = EEPROM.read(z);
offset = i - EEPROM_CONFIG9_YBINS4;
trim4Table.axisY[offset] = EEPROM.read(i);
y++;
z++;
i++;
}
}
/*

View File

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