Complete but experimental 5 cylinder support

This commit is contained in:
Josh Stewart 2016-12-28 22:52:00 +11:00
parent b5b5155bf8
commit 65d6cdd9e9
3 changed files with 69 additions and 12 deletions

View File

@ -43,6 +43,7 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
#define IGN2_COUNTER TCNT5
#define IGN3_COUNTER TCNT5
#define IGN4_COUNTER TCNT4
#define IGN5_COUNTER TCNT1
#define FUEL1_COMPARE OCR3A
#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 IGN3_COMPARE OCR5C
#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 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 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 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 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 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 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

View File

@ -131,11 +131,13 @@ void initialiseSchedulers()
ignitionSchedule2.Status = OFF;
ignitionSchedule3.Status = OFF;
ignitionSchedule4.Status = OFF;
ignitionSchedule5.Status = OFF;
ignitionSchedule1.schedulesSet = 0;
ignitionSchedule2.schedulesSet = 0;
ignitionSchedule3.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)())
{
return;
if(ignitionSchedule1.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
if(ignitionSchedule5.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
ignitionSchedule5.StartCallback = startCallback; //Name the start callback function
ignitionSchedule5.EndCallback = endCallback; //Name the start callback function
ignitionSchedule5.duration = duration;
//As the timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
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
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
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)
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
//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.
noInterrupts();
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
TIMSK5 |= (1 << OCIE5A); //Turn on the A compare unit (ie turn on the interrupt)
#endif
ignitionSchedule5.schedulesSet++;
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)
void ftm0_isr(void)
{

View File

@ -60,6 +60,7 @@ volatile byte ign1LastRev;
volatile byte ign2LastRev;
volatile byte ign3LastRev;
volatile byte ign4LastRev;
volatile byte ign5LastRev;
bool ignitionOn = 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
@ -639,7 +640,7 @@ void setup()
channel1InjEnabled = true;
channel2InjEnabled = true;
channel3InjEnabled = true;
channel3InjEnabled = false; //this is disabled as injector 5 function calls 3 & 5 together
channel4InjEnabled = true;
channel5InjEnabled = true;
break;
@ -1171,6 +1172,22 @@ void loop()
ignition4StartAngle = channel4IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle;
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;
//6 cylinders
case 6:
@ -1309,10 +1326,11 @@ void loop()
if (tempStartAngle <= tempCrankAngle && fuelSchedule5.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
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)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 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); }
//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)
void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); digitalWrite(pinTachOut, LOW); }