Merge pull request #17 from noisymime/master
Get latest fixes from Josh
This commit is contained in:
commit
e510c0e909
|
@ -1,4 +1,4 @@
|
|||
;-------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
#unset CAN_COMMANDS
|
||||
#unset enablehardware_test
|
||||
|
||||
|
@ -2393,6 +2393,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
boostCutOut = { boostCutFuel || boostCutSpark }
|
||||
lambda = { afr / stoich }
|
||||
MAPxRPM = { rpm * map }
|
||||
loopsPerRev = { loopsPerSecond / (rpm / 60) }
|
||||
|
||||
;Manifold pressure in weirdo units
|
||||
map_bar = { (map - baro) / 101.33 }
|
||||
|
|
|
@ -377,7 +377,8 @@ void triggerSec_DualWheel()
|
|||
{
|
||||
toothLastToothTime = micros();
|
||||
//CONFIRM THE BELOW! IT DOESN'T LOOK RIGHT (toothOneTime??)
|
||||
toothLastMinusOneToothTime = (toothOneTime - 6000000) / configPage4.triggerTeeth; //Fixes RPM at 10rpm until a full revolution has taken place
|
||||
//toothLastMinusOneToothTime = (toothOneTime - 6000000) / configPage4.triggerTeeth; //Fixes RPM at 10rpm until a full revolution has taken place
|
||||
toothLastMinusOneToothTime = micros() - (6000000 / configPage4.triggerTeeth); //Fixes RPM at 10rpm until a full revolution has taken place
|
||||
toothCurrentCount = configPage4.triggerTeeth;
|
||||
|
||||
currentStatus.hasSync = true;
|
||||
|
@ -1025,7 +1026,8 @@ void triggerSetup_24X()
|
|||
toothAngles[23] = 357;
|
||||
|
||||
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
||||
toothCurrentCount = 25; //We set the initial tooth value to be something that should never be reached. This indicates no sync
|
||||
if(initialisationComplete == false) { toothCurrentCount = 25; toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initi check to prevent the fuel pump just staying on all the time
|
||||
//We set the initial tooth value to be something that should never be reached. This indicates no sync
|
||||
secondDerivEnabled = false;
|
||||
decoderIsSequential = true;
|
||||
}
|
||||
|
@ -1043,24 +1045,29 @@ void triggerPri_24X()
|
|||
toothCurrentCount = 1; //Reset the counter
|
||||
toothOneMinusOneTime = toothOneTime;
|
||||
toothOneTime = curTime;
|
||||
revolutionOne = !revolutionOne; //Sequential revolution flip
|
||||
currentStatus.hasSync = true;
|
||||
currentStatus.startRevolutions++; //Counter
|
||||
triggerToothAngle = 15; //Always 15 degrees for tooth #15
|
||||
}
|
||||
else
|
||||
{
|
||||
toothCurrentCount++; //Increment the tooth counter
|
||||
triggerToothAngle = toothAngles[(toothCurrentCount-1)] - toothAngles[(toothCurrentCount-2)]; //Calculate the last tooth gap in degrees
|
||||
}
|
||||
|
||||
addToothLogEntry(curGap);
|
||||
|
||||
toothLastToothTime = curTime;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void triggerSec_24X()
|
||||
{
|
||||
toothCurrentCount = 0; //All we need to do is reset the tooth count back to zero, indicating that we're at the beginning of a new revolution
|
||||
return;
|
||||
revolutionOne = 1; //Sequential revolution reset
|
||||
}
|
||||
|
||||
uint16_t getRPM_24X()
|
||||
|
@ -1071,11 +1078,12 @@ int getCrankAngle_24X(int timePerDegree)
|
|||
{
|
||||
//This is the current angle ATDC the engine is at. This is the last known position based on what tooth was last 'seen'. It is only accurate to the resolution of the trigger wheel (Eg 36-1 is 10 degrees)
|
||||
unsigned long tempToothLastToothTime;
|
||||
int tempToothCurrentCount;
|
||||
int tempToothCurrentCount, tempRevolutionOne;
|
||||
//Grab some variables that are used in the trigger code and assign them to temp variables.
|
||||
noInterrupts();
|
||||
tempToothCurrentCount = toothCurrentCount;
|
||||
tempToothLastToothTime = toothLastToothTime;
|
||||
tempRevolutionOne = revolutionOne;
|
||||
interrupts();
|
||||
|
||||
int crankAngle;
|
||||
|
@ -1087,6 +1095,9 @@ int getCrankAngle_24X(int timePerDegree)
|
|||
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
|
||||
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
|
||||
|
||||
//Sequential check (simply sets whether we're on the first or 2nd revoltuion of the cycle)
|
||||
if (tempRevolutionOne) { crankAngle += 360; }
|
||||
|
||||
if (crankAngle >= 720) { crankAngle -= 720; }
|
||||
if (crankAngle > CRANK_ANGLE_MAX) { crankAngle -= CRANK_ANGLE_MAX; }
|
||||
if (crankAngle < 0) { crankAngle += 360; }
|
||||
|
|
|
@ -412,8 +412,8 @@ struct Schedule {
|
|||
void (*StartCallback)(); //Start Callback function for schedule
|
||||
void (*EndCallback)(); //Start Callback function for schedule
|
||||
volatile unsigned long startTime; //The system time (in uS) that the schedule started
|
||||
volatile unsigned int startCompare; //The counter value of the timer when this will start
|
||||
volatile unsigned int endCompare;
|
||||
volatile uint16_t startCompare; //The counter value of the timer when this will start
|
||||
volatile uint16_t endCompare;
|
||||
|
||||
unsigned int nextStartCompare;
|
||||
unsigned int nextEndCompare;
|
||||
|
|
|
@ -288,13 +288,13 @@ void setFuelSchedule(struct Schedule *targetSchedule, unsigned long timeout, uns
|
|||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
if (timeout > MAX_TIMER_PERIOD) { timeout_timer_compare = uS_TO_TIMER_COMPARE( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
targetSchedule->startCompare = *targetSchedule->counter + timeout_timer_compare;
|
||||
targetSchedule->endCompare = targetSchedule->startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
targetSchedule->endCompare = targetSchedule->startCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
targetSchedule->Status = PENDING; //Turn this schedule on
|
||||
targetSchedule->schedulesSet++; //Increment the number of times this schedule has been set
|
||||
|
||||
|
@ -306,8 +306,8 @@ void setFuelSchedule(struct Schedule *targetSchedule, unsigned long timeout, uns
|
|||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
targetSchedule->nextStartCompare = *targetSchedule->counter + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
targetSchedule->nextEndCompare = targetSchedule->nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
targetSchedule->nextStartCompare = *targetSchedule->counter + uS_TO_TIMER_COMPARE(timeout);
|
||||
targetSchedule->nextEndCompare = targetSchedule->nextStartCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
targetSchedule->hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
|
@ -316,141 +316,160 @@ void setFuelSchedule(struct Schedule *targetSchedule, unsigned long timeout, uns
|
|||
//void setFuelSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
void setFuelSchedule1(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule1.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
|
||||
if(timeout < MAX_TIMER_PERIOD_SLOW)
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule1.StartCallback = startCallback;
|
||||
//fuelSchedule1.EndCallback = endCallback;
|
||||
fuelSchedule1.duration = duration;
|
||||
if(fuelSchedule1.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule1.StartCallback = startCallback;
|
||||
//fuelSchedule1.EndCallback = endCallback;
|
||||
fuelSchedule1.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if ((timeout+duration) > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1 - duration) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule1.startCompare = FUEL1_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule1.endCompare = fuelSchedule1.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule1.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule1.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
//Schedule 1 shares a timer with schedule 5
|
||||
//if(channel5InjEnabled) { FUEL1_COMPARE = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, FUEL1_COUNTER); }
|
||||
//else { timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1; FUEL1_COMPARE = fuelSchedule1.startCompare; }
|
||||
//timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1;
|
||||
FUEL1_COMPARE = fuelSchedule1.startCompare;
|
||||
interrupts();
|
||||
FUEL1_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule1.nextStartCompare = FUEL1_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule1.nextEndCompare = fuelSchedule1.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule1.hasNextSchedule = true;
|
||||
}
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule1.startCompare = FUEL1_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule1.endCompare = fuelSchedule1.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule1.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule1.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
//Schedule 1 shares a timer with schedule 5
|
||||
//if(channel5InjEnabled) { FUEL1_COMPARE = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, FUEL1_COUNTER); }
|
||||
//else { timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1; FUEL1_COMPARE = fuelSchedule1.startCompare; }
|
||||
//timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1;
|
||||
FUEL1_COMPARE = fuelSchedule1.startCompare;
|
||||
interrupts();
|
||||
FUEL1_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
noInterrupts();
|
||||
fuelSchedule1.nextStartCompare = FUEL1_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule1.nextEndCompare = fuelSchedule1.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule1.duration = duration;
|
||||
fuelSchedule1.hasNextSchedule = true;
|
||||
interrupts();
|
||||
} //Schedule is RUNNING
|
||||
} //Timeout less than threshold
|
||||
}
|
||||
|
||||
void setFuelSchedule2(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule2.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
|
||||
if(timeout < MAX_TIMER_PERIOD_SLOW)
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule2.StartCallback = startCallback;
|
||||
//fuelSchedule2.EndCallback = endCallback;
|
||||
fuelSchedule2.duration = duration;
|
||||
if(fuelSchedule2.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule2.StartCallback = startCallback;
|
||||
//fuelSchedule2.EndCallback = endCallback;
|
||||
fuelSchedule2.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule2.startCompare = FUEL2_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule2.endCompare = fuelSchedule2.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL2_COMPARE = fuelSchedule2.startCompare; //Use the B compare unit of timer 3
|
||||
fuelSchedule2.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule2.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL2_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule2.nextStartCompare = FUEL2_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule2.nextEndCompare = fuelSchedule2.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule2.hasNextSchedule = true;
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule2.startCompare = FUEL2_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule2.endCompare = fuelSchedule2.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL2_COMPARE = fuelSchedule2.startCompare; //Use the B compare unit of timer 3
|
||||
fuelSchedule2.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule2.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL2_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule2.nextStartCompare = FUEL2_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule2.nextEndCompare = fuelSchedule2.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule2.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//void setFuelSchedule3(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
void setFuelSchedule3(unsigned long timeout, unsigned long duration)
|
||||
{
|
||||
if(fuelSchedule3.Status != RUNNING)//Check that we're not already part way through a schedule
|
||||
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
|
||||
if(timeout < MAX_TIMER_PERIOD_SLOW)
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule3.StartCallback = startCallback;
|
||||
//fuelSchedule3.EndCallback = endCallback;
|
||||
fuelSchedule3.duration = duration;
|
||||
if(fuelSchedule3.Status != RUNNING)//Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule3.StartCallback = startCallback;
|
||||
//fuelSchedule3.EndCallback = endCallback;
|
||||
fuelSchedule3.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule3.startCompare = FUEL3_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule3.endCompare = fuelSchedule3.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL3_COMPARE = fuelSchedule3.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule3.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule3.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL3_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule3.nextStartCompare = FUEL3_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule3.nextEndCompare = fuelSchedule3.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule3.hasNextSchedule = true;
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule3.startCompare = FUEL3_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule3.endCompare = fuelSchedule3.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL3_COMPARE = fuelSchedule3.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule3.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule3.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL3_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule3.nextStartCompare = FUEL3_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule3.nextEndCompare = fuelSchedule3.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule3.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//void setFuelSchedule4(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||
void setFuelSchedule4(unsigned long timeout, unsigned long duration) //Uses timer 4 compare B
|
||||
{
|
||||
if(fuelSchedule4.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
|
||||
if(timeout < MAX_TIMER_PERIOD_SLOW)
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule4.StartCallback = startCallback;
|
||||
//fuelSchedule4.EndCallback = endCallback;
|
||||
fuelSchedule4.duration = duration;
|
||||
if(fuelSchedule4.Status != RUNNING) //Check that we're not already part way through a schedule
|
||||
{
|
||||
//Callbacks no longer used, but retained for now:
|
||||
//fuelSchedule4.StartCallback = startCallback;
|
||||
//fuelSchedule4.EndCallback = endCallback;
|
||||
fuelSchedule4.duration = duration;
|
||||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule4.startCompare = FUEL4_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule4.endCompare = fuelSchedule4.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL4_COMPARE = fuelSchedule4.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule4.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule4.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL4_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule4.nextStartCompare = FUEL4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule4.nextEndCompare = fuelSchedule4.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule4.hasNextSchedule = true;
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
fuelSchedule4.startCompare = FUEL4_COUNTER + timeout_timer_compare;
|
||||
fuelSchedule4.endCompare = fuelSchedule4.startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
FUEL4_COMPARE = fuelSchedule4.startCompare; //Use the C copmare unit of timer 3
|
||||
fuelSchedule4.Status = PENDING; //Turn this schedule on
|
||||
fuelSchedule4.schedulesSet++; //Increment the number of times this schedule has been set
|
||||
interrupts();
|
||||
FUEL4_TIMER_ENABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the schedule is already running, we can set the next schedule so it is ready to go
|
||||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule4.nextStartCompare = FUEL4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule4.nextEndCompare = fuelSchedule4.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule4.hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -764,7 +783,7 @@ static inline void fuelSchedule1Interrupt() //Most ARM chips can simply call a f
|
|||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { openInjector1and4(); }
|
||||
else { openInjector1(); }
|
||||
fuelSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL1_COMPARE = fuelSchedule1.endCompare;
|
||||
FUEL1_COMPARE = FUEL1_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule1.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule1.Status == RUNNING)
|
||||
{
|
||||
|
@ -801,7 +820,7 @@ static inline void fuelSchedule2Interrupt() //Most ARM chips can simply call a f
|
|||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { openInjector2and3(); }
|
||||
else { openInjector2(); }
|
||||
fuelSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL2_COMPARE = fuelSchedule2.endCompare;
|
||||
FUEL2_COMPARE = FUEL2_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule2.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule2.Status == RUNNING)
|
||||
{
|
||||
|
@ -837,7 +856,7 @@ static inline void fuelSchedule3Interrupt() //Most ARM chips can simply call a f
|
|||
if(channel5InjEnabled) { openInjector3and5(); }
|
||||
else { openInjector3(); }
|
||||
fuelSchedule3.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL3_COMPARE = fuelSchedule3.endCompare;
|
||||
FUEL3_COMPARE = FUEL3_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule3.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule3.Status == RUNNING)
|
||||
{
|
||||
|
@ -872,7 +891,7 @@ static inline void fuelSchedule4Interrupt() //Most ARM chips can simply call a f
|
|||
//fuelSchedule4.StartCallback();
|
||||
openInjector4();
|
||||
fuelSchedule4.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL4_COMPARE = fuelSchedule4.endCompare;
|
||||
FUEL4_COMPARE = FUEL4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule4.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule4.Status == RUNNING)
|
||||
{
|
||||
|
@ -940,11 +959,12 @@ static inline void ignitionSchedule1Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule1.StartCallback();
|
||||
ignitionSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule1.startTime = micros();
|
||||
IGN1_COMPARE = ignitionSchedule1.endCompare;
|
||||
//IGN1_COMPARE = ignitionSchedule1.endCompare;
|
||||
IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE(ignitionSchedule1.duration); //Doing this here prevents a potential overflow on restarts
|
||||
//This code is all to do with the staged ignition timing testing. That is, calling this interrupt slightly before the true ignition point and recalculating the end time for more accuracy
|
||||
//IGN1_COMPARE = ignitionSchedule1.endCompare - 50;
|
||||
//ignitionSchedule1.Status = STAGED;
|
||||
}
|
||||
}
|
||||
else if (ignitionSchedule1.Status == STAGED)
|
||||
{
|
||||
int16_t crankAngle = getCrankAngle(timePerDegree);
|
||||
|
@ -978,7 +998,7 @@ static inline void ignitionSchedule2Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule2.StartCallback();
|
||||
ignitionSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule2.startTime = micros();
|
||||
IGN2_COMPARE = ignitionSchedule2.endCompare; //OCR5B = TCNT5 + (ignitionSchedule2.duration >> 2);
|
||||
IGN2_COMPARE = IGN2_COUNTER + uS_TO_TIMER_COMPARE(ignitionSchedule2.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule2.Status == RUNNING)
|
||||
{
|
||||
|
@ -1001,7 +1021,7 @@ static inline void ignitionSchedule3Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule3.StartCallback();
|
||||
ignitionSchedule3.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule3.startTime = micros();
|
||||
IGN3_COMPARE = ignitionSchedule3.endCompare; //OCR5C = TCNT5 + (ignitionSchedule3.duration >> 2);
|
||||
IGN3_COMPARE = IGN3_COUNTER + uS_TO_TIMER_COMPARE(ignitionSchedule3.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule3.Status == RUNNING)
|
||||
{
|
||||
|
@ -1034,7 +1054,7 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule4.StartCallback();
|
||||
ignitionSchedule4.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule4.startTime = micros();
|
||||
IGN4_COMPARE = ignitionSchedule4.endCompare;
|
||||
IGN4_COMPARE = IGN4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(ignitionSchedule4.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule4.Status == RUNNING)
|
||||
{
|
||||
|
@ -1067,7 +1087,7 @@ static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule5.StartCallback();
|
||||
ignitionSchedule5.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule5.startTime = micros();
|
||||
IGN5_COMPARE = ignitionSchedule5.endCompare;
|
||||
IGN5_COMPARE = IGN5_COUNTER + uS_TO_TIMER_COMPARE_SLOW(ignitionSchedule5.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule5.Status == RUNNING)
|
||||
{
|
||||
|
|
|
@ -1227,6 +1227,7 @@ void loop()
|
|||
//Calculate start angle for each channel
|
||||
//1 cylinder (Everyone gets this)
|
||||
ignition1EndAngle = CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
if(ignition1EndAngle > CRANK_ANGLE_MAX_IGN) {ignition1EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition1StartAngle = ignition1EndAngle - dwellAngle; // 360 - desired advance angle - number of degrees the dwell will take
|
||||
if(ignition1StartAngle < 0) {ignition1StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
|
@ -1235,35 +1236,41 @@ void loop()
|
|||
{
|
||||
//2 cylinders
|
||||
case 2:
|
||||
ignition2EndAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
|
||||
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition2StartAngle = ignition2EndAngle - dwellAngle;
|
||||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
break;
|
||||
//3 cylinders
|
||||
case 3:
|
||||
ignition2EndAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
|
||||
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition2StartAngle = ignition2EndAngle - dwellAngle;
|
||||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition3EndAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
|
||||
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition3StartAngle = channel3IgnDegrees + 360 - currentStatus.advance - dwellAngle;
|
||||
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
break;
|
||||
//4 cylinders
|
||||
case 4:
|
||||
ignition2EndAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
|
||||
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition2StartAngle = ignition2EndAngle - dwellAngle;
|
||||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
if(configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
|
||||
{
|
||||
ignition3EndAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
|
||||
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition3StartAngle = ignition3EndAngle - dwellAngle;
|
||||
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition4EndAngle = channel4IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition4EndAngle = channel4IgnDegrees - currentStatus.advance;
|
||||
if(ignition4EndAngle > CRANK_ANGLE_MAX_IGN) {ignition4EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition4StartAngle = ignition4EndAngle - dwellAngle;
|
||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
}
|
||||
else if(configPage4.sparkMode == IGN_MODE_ROTARY)
|
||||
{
|
||||
|
@ -1288,18 +1295,20 @@ void loop()
|
|||
break;
|
||||
//5 cylinders
|
||||
case 5:
|
||||
ignition2EndAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
|
||||
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition2StartAngle = ignition2EndAngle - dwellAngle;
|
||||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition3EndAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
|
||||
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition3StartAngle = ignition3EndAngle - dwellAngle;
|
||||
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition4EndAngle = channel4IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
if(ignition4EndAngle > CRANK_ANGLE_MAX_IGN) {ignition4EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition4StartAngle = ignition4EndAngle - dwellAngle;
|
||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition5StartAngle = channel5IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle;
|
||||
if(ignition5StartAngle > CRANK_ANGLE_MAX_IGN) {ignition5StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
|
@ -1307,27 +1316,32 @@ void loop()
|
|||
break;
|
||||
//6 cylinders
|
||||
case 6:
|
||||
ignition2EndAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
|
||||
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition2StartAngle = ignition2EndAngle - dwellAngle;
|
||||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition3EndAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
|
||||
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition3StartAngle = ignition3EndAngle - dwellAngle;
|
||||
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
break;
|
||||
//8 cylinders
|
||||
case 8:
|
||||
ignition2EndAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
|
||||
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition2StartAngle = ignition2EndAngle - dwellAngle;
|
||||
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition3EndAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
|
||||
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition3StartAngle = ignition3EndAngle - dwellAngle;
|
||||
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
|
||||
ignition4EndAngle = channel4IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance;
|
||||
ignition4EndAngle = channel4IgnDegrees - currentStatus.advance;
|
||||
if(ignition4EndAngle > CRANK_ANGLE_MAX_IGN) {ignition4EndAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
ignition4StartAngle = ignition4EndAngle - dwellAngle;
|
||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||
break;
|
||||
|
||||
//Will hit the default case on 1 cylinder or >8 cylinders. Do nothing in these cases
|
||||
|
|
|
@ -29,6 +29,7 @@ struct table2D {
|
|||
//Store the last input and output for caching
|
||||
int16_t lastInput;
|
||||
int16_t lastOutput;
|
||||
byte cacheTime; //TRacks when the last cache value was set so it can expire after x seconds. A timeout is required to pickup when a tuning value is changed, otherwise the old cached value will continue to be returned as the X value isn't changing.
|
||||
};
|
||||
|
||||
void table2D_setSize(struct table2D targetTable, byte newSize);
|
||||
|
|
|
@ -59,111 +59,121 @@ int table2D_getValue(struct table2D *fromTable, int X_in)
|
|||
bool valueFound = false;
|
||||
|
||||
int X = X_in;
|
||||
|
||||
int xMinValue, xMaxValue;
|
||||
if (fromTable->valueSize == SIZE_BYTE)
|
||||
{
|
||||
//Byte version
|
||||
xMinValue = fromTable->axisX[0];
|
||||
xMaxValue = fromTable->axisX[fromTable->xSize-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//int version
|
||||
xMinValue = fromTable->axisX16[0];
|
||||
xMaxValue = fromTable->axisX16[fromTable->xSize-1];
|
||||
}
|
||||
int xMin = 0;
|
||||
int xMax = 0;
|
||||
|
||||
//If the requested X value is greater/small than the maximum/minimum bin, reset X to be that value
|
||||
if(X > xMaxValue) { X = xMaxValue; }
|
||||
if(X < xMinValue) { X = xMinValue; }
|
||||
|
||||
|
||||
if (fromTable->valueSize == SIZE_BYTE)
|
||||
//Check whether the X input is the same as last time this ran
|
||||
if(X_in == fromTable->lastInput && fromTable->cacheTime == currentStatus.secl)
|
||||
{
|
||||
//**** Byte version ****
|
||||
|
||||
//1st check is whether we're still in the same X bin as last time
|
||||
if ( (X <= fromTable->axisX[fromTable->lastXMax]) && (X > fromTable->axisX[fromTable->lastXMin]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX[fromTable->lastXMax];
|
||||
xMinValue = fromTable->axisX[fromTable->lastXMin];
|
||||
xMax = fromTable->lastXMax;
|
||||
xMin = fromTable->lastXMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we're not in the same bin, loop through to find where we are
|
||||
for (int x = fromTable->xSize-1; x >= 0; x--)
|
||||
{
|
||||
//Checks the case where the X value is exactly what was requested
|
||||
if ( (X == fromTable->axisX[x]) || (x == 0) )
|
||||
{
|
||||
returnValue = fromTable->values[x]; //Simply return the coresponding value
|
||||
valueFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Normal case
|
||||
if ( (X <= fromTable->axisX[x]) && (X > fromTable->axisX[x-1]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX[x];
|
||||
xMinValue = fromTable->axisX[x-1];
|
||||
xMax = x;
|
||||
fromTable->lastXMax = xMax;
|
||||
xMin = x-1;
|
||||
fromTable->lastXMin = xMin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
returnValue = fromTable->lastOutput;
|
||||
valueFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// **** INT VERSION ****
|
||||
fromTable->cacheTime = currentStatus.secl; //As we're not using the cache value, set the current secl value to track when this new value was calc'd
|
||||
|
||||
//1st check is whether we're still in the same X bin as last time
|
||||
if ( (X <= fromTable->axisX16[fromTable->lastXMax]) && (X > fromTable->axisX16[fromTable->lastXMin]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX16[fromTable->lastXMax];
|
||||
xMinValue = fromTable->axisX16[fromTable->lastXMin];
|
||||
xMax = fromTable->lastXMax;
|
||||
xMin = fromTable->lastXMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we're not in the same bin, loop through to find where we are
|
||||
for (int x = fromTable->xSize-1; x >= 0; x--)
|
||||
{
|
||||
//Checks the case where the X value is exactly what was requested
|
||||
if ( (X == fromTable->axisX16[x]) || (x == 0) )
|
||||
{
|
||||
returnValue = fromTable->values16[x]; //Simply return the coresponding value
|
||||
valueFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Normal case
|
||||
if ( (X <= fromTable->axisX16[x]) && (X > fromTable->axisX16[x-1]) )
|
||||
if (fromTable->valueSize == SIZE_BYTE)
|
||||
{
|
||||
//Byte version
|
||||
xMinValue = fromTable->axisX[0];
|
||||
xMaxValue = fromTable->axisX[fromTable->xSize-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
//int version
|
||||
xMinValue = fromTable->axisX16[0];
|
||||
xMaxValue = fromTable->axisX16[fromTable->xSize-1];
|
||||
}
|
||||
|
||||
//If the requested X value is greater/small than the maximum/minimum bin, reset X to be that value
|
||||
if(X > xMaxValue) { X = xMaxValue; }
|
||||
if(X < xMinValue) { X = xMinValue; }
|
||||
|
||||
|
||||
if (fromTable->valueSize == SIZE_BYTE)
|
||||
{
|
||||
//**** Byte version ****
|
||||
|
||||
//1st check is whether we're still in the same X bin as last time
|
||||
if ( (X <= fromTable->axisX[fromTable->lastXMax]) && (X > fromTable->axisX[fromTable->lastXMin]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX[fromTable->lastXMax];
|
||||
xMinValue = fromTable->axisX[fromTable->lastXMin];
|
||||
xMax = fromTable->lastXMax;
|
||||
xMin = fromTable->lastXMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we're not in the same bin, loop through to find where we are
|
||||
for (int x = fromTable->xSize-1; x >= 0; x--)
|
||||
{
|
||||
//Checks the case where the X value is exactly what was requested
|
||||
if ( (X == fromTable->axisX[x]) || (x == 0) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX16[x];
|
||||
xMinValue = fromTable->axisX16[x-1];
|
||||
xMax = x;
|
||||
fromTable->lastXMax = xMax;
|
||||
xMin = x-1;
|
||||
fromTable->lastXMin = xMin;
|
||||
returnValue = fromTable->values[x]; //Simply return the coresponding value
|
||||
valueFound = true;
|
||||
break;
|
||||
} //Found in loop
|
||||
} //Exact hit
|
||||
} //For loop
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Normal case
|
||||
if ( (X <= fromTable->axisX[x]) && (X > fromTable->axisX[x-1]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX[x];
|
||||
xMinValue = fromTable->axisX[x-1];
|
||||
xMax = x;
|
||||
fromTable->lastXMax = xMax;
|
||||
xMin = x-1;
|
||||
fromTable->lastXMin = xMin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// **** INT VERSION ****
|
||||
|
||||
}
|
||||
//1st check is whether we're still in the same X bin as last time
|
||||
if ( (X <= fromTable->axisX16[fromTable->lastXMax]) && (X > fromTable->axisX16[fromTable->lastXMin]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX16[fromTable->lastXMax];
|
||||
xMinValue = fromTable->axisX16[fromTable->lastXMin];
|
||||
xMax = fromTable->lastXMax;
|
||||
xMin = fromTable->lastXMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we're not in the same bin, loop through to find where we are
|
||||
for (int x = fromTable->xSize-1; x >= 0; x--)
|
||||
{
|
||||
//Checks the case where the X value is exactly what was requested
|
||||
if ( (X == fromTable->axisX16[x]) || (x == 0) )
|
||||
{
|
||||
returnValue = fromTable->values16[x]; //Simply return the coresponding value
|
||||
valueFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Normal case
|
||||
if ( (X <= fromTable->axisX16[x]) && (X > fromTable->axisX16[x-1]) )
|
||||
{
|
||||
xMaxValue = fromTable->axisX16[x];
|
||||
xMinValue = fromTable->axisX16[x-1];
|
||||
xMax = x;
|
||||
fromTable->lastXMax = xMax;
|
||||
xMin = x-1;
|
||||
fromTable->lastXMin = xMin;
|
||||
break;
|
||||
} //Found in loop
|
||||
} //Exact hit
|
||||
} //For loop
|
||||
} //In cache or not
|
||||
} //byte or int values
|
||||
} //X_in same as last time
|
||||
|
||||
if (valueFound == false)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue