mirror of https://github.com/rusefi/speeduino.git
Complete but experimental 5 cylinder support
This commit is contained in:
parent
b5b5155bf8
commit
65d6cdd9e9
|
@ -43,6 +43,7 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
||||||
#define IGN2_COUNTER TCNT5
|
#define IGN2_COUNTER TCNT5
|
||||||
#define IGN3_COUNTER TCNT5
|
#define IGN3_COUNTER TCNT5
|
||||||
#define IGN4_COUNTER TCNT4
|
#define IGN4_COUNTER TCNT4
|
||||||
|
#define IGN5_COUNTER TCNT1
|
||||||
|
|
||||||
#define FUEL1_COMPARE OCR3A
|
#define FUEL1_COMPARE OCR3A
|
||||||
#define FUEL2_COMPARE OCR3B
|
#define FUEL2_COMPARE OCR3B
|
||||||
|
@ -53,6 +54,7 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
||||||
#define IGN2_COMPARE OCR5B
|
#define IGN2_COMPARE OCR5B
|
||||||
#define IGN3_COMPARE OCR5C
|
#define IGN3_COMPARE OCR5C
|
||||||
#define IGN4_COMPARE OCR4A
|
#define IGN4_COMPARE OCR4A
|
||||||
|
#define IGN5_COMPARE OCR1C
|
||||||
|
|
||||||
#define FUEL1_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3A) //Turn on the A compare unit (ie turn on the interrupt)
|
#define FUEL1_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3A) //Turn on the A compare unit (ie turn on the interrupt)
|
||||||
#define FUEL2_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //Turn on the B compare unit (ie turn on the interrupt)
|
#define FUEL2_TIMER_ENABLE() TIMSK3 |= (1 << OCIE3B) //Turn on the B compare unit (ie turn on the interrupt)
|
||||||
|
@ -68,11 +70,13 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
||||||
#define IGN2_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5B) //Turn on the B compare unit (ie turn on the interrupt)
|
#define IGN2_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5B) //Turn on the B compare unit (ie turn on the interrupt)
|
||||||
#define IGN3_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5C) //Turn on the C compare unit (ie turn on the interrupt)
|
#define IGN3_TIMER_ENABLE() TIMSK5 |= (1 << OCIE5C) //Turn on the C compare unit (ie turn on the interrupt)
|
||||||
#define IGN4_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4A) //Turn on the A compare unit (ie turn on the interrupt)
|
#define IGN4_TIMER_ENABLE() TIMSK4 |= (1 << OCIE4A) //Turn on the A compare unit (ie turn on the interrupt)
|
||||||
|
#define IGN5_TIMER_ENABLE() TIMSK1 |= (1 << OCIE1C) //Turn on the A compare unit (ie turn on the interrupt)
|
||||||
|
|
||||||
#define IGN1_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5A) //Turn off this output compare unit
|
#define IGN1_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5A) //Turn off this output compare unit
|
||||||
#define IGN2_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5B) //Turn off this output compare unit
|
#define IGN2_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5B) //Turn off this output compare unit
|
||||||
#define IGN3_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5C) //Turn off this output compare unit
|
#define IGN3_TIMER_DISABLE() TIMSK5 &= ~(1 << OCIE5C) //Turn off this output compare unit
|
||||||
#define IGN4_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4A) //Turn off this output compare unit
|
#define IGN4_TIMER_DISABLE() TIMSK4 &= ~(1 << OCIE4A) //Turn off this output compare unit
|
||||||
|
#define IGN5_TIMER_DISABLE() TIMSK1 &= ~(1 << OCIE1C) //Turn off this output compare unit
|
||||||
|
|
||||||
#define MAX_TIMER_PERIOD 262140 //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 4, as each timer tick is 4uS)
|
#define MAX_TIMER_PERIOD 262140 //The longest period of time (in uS) that the timer can permit (IN this case it is 65535 * 4, as each timer tick is 4uS)
|
||||||
#define uS_TO_TIMER_COMPARE(uS1) (uS1 >> 2) //Converts a given number of uS into the required number of timer ticks until that time has passed
|
#define uS_TO_TIMER_COMPARE(uS1) (uS1 >> 2) //Converts a given number of uS into the required number of timer ticks until that time has passed
|
||||||
|
|
|
@ -131,11 +131,13 @@ void initialiseSchedulers()
|
||||||
ignitionSchedule2.Status = OFF;
|
ignitionSchedule2.Status = OFF;
|
||||||
ignitionSchedule3.Status = OFF;
|
ignitionSchedule3.Status = OFF;
|
||||||
ignitionSchedule4.Status = OFF;
|
ignitionSchedule4.Status = OFF;
|
||||||
|
ignitionSchedule5.Status = OFF;
|
||||||
|
|
||||||
ignitionSchedule1.schedulesSet = 0;
|
ignitionSchedule1.schedulesSet = 0;
|
||||||
ignitionSchedule2.schedulesSet = 0;
|
ignitionSchedule2.schedulesSet = 0;
|
||||||
ignitionSchedule3.schedulesSet = 0;
|
ignitionSchedule3.schedulesSet = 0;
|
||||||
ignitionSchedule4.schedulesSet = 0;
|
ignitionSchedule4.schedulesSet = 0;
|
||||||
|
ignitionSchedule5.schedulesSet = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,21 +353,25 @@ void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsign
|
||||||
}
|
}
|
||||||
void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||||
{
|
{
|
||||||
return;
|
if(ignitionSchedule5.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
|
||||||
if(ignitionSchedule1.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
|
|
||||||
|
|
||||||
ignitionSchedule5.StartCallback = startCallback; //Name the start callback function
|
ignitionSchedule5.StartCallback = startCallback; //Name the start callback function
|
||||||
ignitionSchedule5.EndCallback = endCallback; //Name the start callback function
|
ignitionSchedule5.EndCallback = endCallback; //Name the start callback function
|
||||||
ignitionSchedule5.duration = duration;
|
ignitionSchedule5.duration = duration;
|
||||||
|
|
||||||
//As the timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
|
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
|
||||||
if (timeout > 262140) { timeout = 262100; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking. This must be set slightly lower than the max of 262140 to avoid strangeness
|
//The timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
|
||||||
|
//Note this is different to the other ignition timers
|
||||||
|
if (timeout > MAX_TIMER_PERIOD) { timeout = 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.
|
||||||
|
|
||||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
|
noInterrupts();
|
||||||
OCR5A = TCNT5 + (timeout >> 2); //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
|
ignitionSchedule5.startCompare = IGN5_COUNTER + (timeout >> 4); //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
|
||||||
|
ignitionSchedule5.endCompare = ignitionSchedule5.startCompare + (duration >> 4);
|
||||||
|
IGN5_COMPARE = ignitionSchedule5.startCompare;
|
||||||
ignitionSchedule5.Status = PENDING; //Turn this schedule on
|
ignitionSchedule5.Status = PENDING; //Turn this schedule on
|
||||||
TIMSK5 |= (1 << OCIE5A); //Turn on the A compare unit (ie turn on the interrupt)
|
ignitionSchedule5.schedulesSet++;
|
||||||
#endif
|
interrupts();
|
||||||
|
IGN5_TIMER_ENABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************************************************************************************************************************************/
|
/*******************************************************************************************************************************************************************************************************/
|
||||||
|
@ -554,6 +560,32 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
|
||||||
|
ISR(TIMER1_COMPC_vect) //ignitionSchedule5
|
||||||
|
#elif defined (CORE_TEENSY)
|
||||||
|
static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call a function
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (ignitionSchedule5.Status == PENDING) //Check to see if this schedule is turn on
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
ign5LastRev = startRevolutions;
|
||||||
|
IGN5_COMPARE = ignitionSchedule5.endCompare;
|
||||||
|
}
|
||||||
|
else if (ignitionSchedule5.Status == RUNNING)
|
||||||
|
{
|
||||||
|
ignitionSchedule5.Status = OFF; //Turn off the schedule
|
||||||
|
ignitionSchedule5.EndCallback();
|
||||||
|
ignitionSchedule5.schedulesSet = 0;
|
||||||
|
ignitionCount += 1; //Increment the igintion counter
|
||||||
|
IGN5_TIMER_DISABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CORE_TEENSY)
|
#if defined(CORE_TEENSY)
|
||||||
void ftm0_isr(void)
|
void ftm0_isr(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,6 +60,7 @@ volatile byte ign1LastRev;
|
||||||
volatile byte ign2LastRev;
|
volatile byte ign2LastRev;
|
||||||
volatile byte ign3LastRev;
|
volatile byte ign3LastRev;
|
||||||
volatile byte ign4LastRev;
|
volatile byte ign4LastRev;
|
||||||
|
volatile byte ign5LastRev;
|
||||||
bool ignitionOn = false; //The current state of the ignition system
|
bool ignitionOn = false; //The current state of the ignition system
|
||||||
bool fuelOn = false; //The current state of the ignition system
|
bool fuelOn = false; //The current state of the ignition system
|
||||||
bool fuelPumpOn = false; //The current status of the fuel pump
|
bool fuelPumpOn = false; //The current status of the fuel pump
|
||||||
|
@ -639,7 +640,7 @@ void setup()
|
||||||
|
|
||||||
channel1InjEnabled = true;
|
channel1InjEnabled = true;
|
||||||
channel2InjEnabled = true;
|
channel2InjEnabled = true;
|
||||||
channel3InjEnabled = true;
|
channel3InjEnabled = false; //this is disabled as injector 5 function calls 3 & 5 together
|
||||||
channel4InjEnabled = true;
|
channel4InjEnabled = true;
|
||||||
channel5InjEnabled = true;
|
channel5InjEnabled = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1171,6 +1172,22 @@ void loop()
|
||||||
ignition4StartAngle = channel4IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle;
|
ignition4StartAngle = channel4IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle;
|
||||||
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
//5 cylinders
|
||||||
|
case 5:
|
||||||
|
ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle;
|
||||||
|
if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||||
|
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
|
||||||
|
|
||||||
|
ignition3StartAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle;
|
||||||
|
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||||
|
|
||||||
|
ignition4StartAngle = channel4IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle;
|
||||||
|
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||||
|
|
||||||
|
ignition5StartAngle = channel5IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle;
|
||||||
|
if(ignition5StartAngle > CRANK_ANGLE_MAX_IGN) {ignition5StartAngle -= CRANK_ANGLE_MAX_IGN;}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//6 cylinders
|
//6 cylinders
|
||||||
case 6:
|
case 6:
|
||||||
|
@ -1309,10 +1326,11 @@ void loop()
|
||||||
if (tempStartAngle <= tempCrankAngle && fuelSchedule5.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
if (tempStartAngle <= tempCrankAngle && fuelSchedule5.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
|
||||||
if ( tempStartAngle > tempCrankAngle )
|
if ( tempStartAngle > tempCrankAngle )
|
||||||
{
|
{
|
||||||
setFuelSchedule5(openInjector5,
|
//Note the hacky use of fuel schedule 3 below
|
||||||
|
setFuelSchedule3(openInjector3and5,
|
||||||
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
|
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
|
||||||
(unsigned long)currentStatus.PW1,
|
(unsigned long)currentStatus.PW1,
|
||||||
closeInjector5
|
closeInjector3and5
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1496,6 +1514,9 @@ void openInjector1and4() { digitalWrite(pinInjector1, HIGH); digitalWrite(pinInj
|
||||||
void closeInjector1and4() { digitalWrite(pinInjector1, LOW); digitalWrite(pinInjector4, LOW);BIT_CLEAR(currentStatus.squirt, 0); }
|
void closeInjector1and4() { digitalWrite(pinInjector1, LOW); digitalWrite(pinInjector4, LOW);BIT_CLEAR(currentStatus.squirt, 0); }
|
||||||
void openInjector2and3() { digitalWrite(pinInjector2, HIGH); digitalWrite(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, 1); }
|
void openInjector2and3() { digitalWrite(pinInjector2, HIGH); digitalWrite(pinInjector3, HIGH); BIT_SET(currentStatus.squirt, 1); }
|
||||||
void closeInjector2and3() { digitalWrite(pinInjector2, LOW); digitalWrite(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, 1); }
|
void closeInjector2and3() { digitalWrite(pinInjector2, LOW); digitalWrite(pinInjector3, LOW); BIT_CLEAR(currentStatus.squirt, 1); }
|
||||||
|
//Below functions are used for 5 cylinder support
|
||||||
|
void openInjector3and5() { digitalWrite(pinInjector3, HIGH); digitalWrite(pinInjector5, HIGH); BIT_SET(currentStatus.squirt, 0); }
|
||||||
|
void closeInjector3and5() { digitalWrite(pinInjector3, LOW); digitalWrite(pinInjector5, LOW);BIT_CLEAR(currentStatus.squirt, 0); }
|
||||||
|
|
||||||
//As above but for ignition (Wasted COP mode)
|
//As above but for ignition (Wasted COP mode)
|
||||||
void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); }
|
void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); }
|
||||||
|
|
Loading…
Reference in New Issue