Experimental 3 wire idle support

This commit is contained in:
Josh Stewart 2016-01-13 17:06:55 +11:00
parent aac02e1984
commit 0830e6d834
7 changed files with 33 additions and 8 deletions

View File

@ -58,6 +58,7 @@ void vvtControl()
}
//The interrupt to control the Boost PWM
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ISR(TIMER1_COMPA_vect)
{
if(!configPage3.boostEnabled) { return; }
@ -94,3 +95,7 @@ ISR(TIMER1_COMPB_vect)
vvt_pwm_state = true;
}
}
#elif defined(PROCESSOR_TEENSY_3_1) || defined(PROCESSOR_TEENSY_3_2)
#endif

View File

@ -239,6 +239,8 @@ void sendValues(int length)
response[32] = highByte(currentStatus.rpmDOT);
Serial.write(response, (size_t)packetSize);
//if(Serial.available()) { command(); }
//Serial.flush();
return;
}
@ -849,7 +851,6 @@ void sendToothLog(bool useChar)
}
}
void testComm()
{
Serial.write(1);

View File

@ -103,6 +103,7 @@ struct statuses {
byte iatCorrection; //The amount of inlet air temperature adjustment currently being applied
byte launchCorrection; //The amount of correction being applied if launch control is active
byte afrTarget;
byte idleDuty;
unsigned long TAEEndTime; //The target end time used whenever TAE is turned on
volatile byte squirt;
volatile byte spark;
@ -338,7 +339,8 @@ struct config4 {
byte iacAlgorithm : 3; //Valid values are: "None", "On/Off", "PWM", "PWM Closed Loop", "Stepper", "Stepper Closed Loop"
byte iacStepTime : 3; //How long to pulse the stepper for to ensure the step completes (ms)
byte unused52 : 2;
byte iacChannels : 1; //How many outputs to use in PWM mode (0 = 1 channel, 1 = 2 channels)
byte unused52 : 1;
byte iacFastTemp; //Fast idle temp when using a simple on/off valve

2
idle.h
View File

@ -25,6 +25,8 @@ unsigned int iacStepTime;
volatile byte *idle_pin_port;
volatile byte idle_pin_mask;
volatile byte *idle2_pin_port;
volatile byte idle2_pin_mask;
volatile bool idle_pwm_state;
unsigned int idle_pwm_max_count; //Used for variable PWM frequency
volatile unsigned int idle_pwm_cur_value;

View File

@ -42,6 +42,8 @@ void initialiseIdle()
idle_pin_port = portOutputRegister(digitalPinToPort(pinIdle1));
idle_pin_mask = digitalPinToBitMask(pinIdle1);
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
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
TIMSK4 |= (1 << OCIE4C); //Turn on the A compare unit (ie turn on the interrupt)
break;
@ -112,15 +114,15 @@ void idleControl()
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
{
//Currently cranking. Use the cranking table
byte idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idle_pwm_target_value = percentage(idleDuty, idle_pwm_max_count);
currentStatus.idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
idleOn = true;
}
else if( currentStatus.coolant < (iacPWMTable.values[IDLE_TABLE_SIZE-1] + CALIBRATION_TEMPERATURE_OFFSET))
{
//Standard running
byte idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idle_pwm_target_value = percentage(idleDuty, idle_pwm_max_count);
currentStatus.idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
idleOn = true;
}
else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; }
@ -209,20 +211,26 @@ void homeStepper()
}
//The interrupt to turn off the idle pwm
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ISR(TIMER4_COMPC_vect)
{
if (idle_pwm_state)
{
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
if(configPage4.iacChannels) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
OCR4C = TCNT4 + (idle_pwm_max_count - idle_pwm_cur_value);
idle_pwm_state = false;
}
else
{
*idle_pin_port |= (idle_pin_mask); // Switch pin high
if(configPage4.iacChannels) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
OCR4C = TCNT4 + idle_pwm_target_value;
idle_pwm_cur_value = idle_pwm_target_value;
idle_pwm_state = true;
}
}
#elif defined(PROCESSOR_TEENSY_3_1) || defined(PROCESSOR_TEENSY_3_2)
void idle_off() { }
#endif

View File

@ -343,7 +343,8 @@ page = 7
iacAlgorithm = bits , U08, 52, [0:2], "None", "On/Off", "PWM", "INVALID", "Stepper", "INVALID", "INVALID", "INVALID"
iacStepTime = bits , U08, 52, [3:5], "1", "2", "3", "4", "5", "6"
unused7-52 = bits , U08, 52, [6:7], "One", "INVALID", "INVALID", "INVALID"
iacChannels = bits, U08, 52, [6:6], "1", "2"
unused7-52f = bits , U08, 52, [7:7], "One", "INVALID"
#if CELSIUS
iacFastTemp = scalar, U08, 53, "C", 1.0, -40, -40, 215, 0
@ -539,6 +540,7 @@ page = 8
sparkMode = "Wasted Spark: Ignition outputs are on the channels <= half the number of cylinders. Eg 4 cylinder outputs on IGN1 and IGN2.\nSingle Channel: All ignition pulses are output on IGN1.\nWasted COP: Ignition pulses are output on all ignition channels up to the number of cylinders. Eg 4 cylinder outputs on all ignition channels. No valid for >4 cylinders"
iacChannels = "The number of output channels used for PWM valves. Select 1 for 2-wire valves or 2 for 3-wire valves.
iacStepTime = "Time between each stepper motor step.\nIncrease this if the motor appears to behave intermittently."
iacStepHome = "On startup the stepper motor moves this many steps to return to its home position. Set this value to a few more than the actual number to ensure the motor has returned to its full position."
iacStepHyster = "The minimum number of steps to move in any one go."
@ -632,6 +634,7 @@ page = 8
field = "Minimum Steps", iacStepHyster, { iacAlgorithm == 4 || iacAlgorithm == 5 }
dialog = pwm_idle, "PWM Idle"
field = "Number of outputs", iacChannels, { iacAlgorithm == 2 || iacAlgorithm == 3 }
field = "Idle valve frequency", idleFreq, { iacAlgorithm == 2 || iacAlgorithm == 3 }
dialog = idleSettings, "Idle Settings"

View File

@ -79,7 +79,10 @@ void setPinMapping(byte boardID)
pinDisplayReset = 48; // OLED reset pin
pinTachOut = 49; //Tacho output pin
pinIdle1 = 5; //Single wire idle control
pinIdle2 = 7; //2 wire idle control
pinFuelPump = 4; //Fuel pump output
pinStepperDir = 16; //Direction pin for DRV8825 driver
pinStepperStep = 17; //Step pin for DRV8825 driver
break;
@ -104,6 +107,7 @@ void setPinMapping(byte boardID)
pinDisplayReset = 48; // OLED reset pin
pinTachOut = 49; //Tacho output pin
pinIdle1 = 5; //Single wire idle control
pinIdle2 = 7; //2 wire idle control (Note this is shared with boost!!!)
pinFuelPump = 45; //Fuel pump output
pinStepperDir = 16; //Direction pin for DRV8825 driver
pinStepperStep = 17; //Step pin for DRV8825 driver