This commit is contained in:
Josh Stewart 2021-09-11 10:42:39 +10:00
parent 3297321d9c
commit b2878d66f8
3 changed files with 138 additions and 136 deletions

View File

@ -558,11 +558,11 @@ page = 4
FILTER_FLEX = scalar, U08, 125, "%", 1.0, 0.0, 0, 240, 0
#if CELSIUS
vvtMinClt = array, U08, 126, "C", 1.0, -40, -40, 215, 0
vvtMinClt = scalar, U08, 126, "C", 1.0, -40, -40, 215, 0
#else
vvtMinClt = scalar, U08, 126, "F", 1.8, -22.23, -40, 215, 0
vvtMinClt = scalar, U08, 126, "F", 1.8, -22.23, -40, 215, 0
#endif
vvtDelay = scalar, U08, 127, "S", 5.0, 0.0, 0, 1275, 0
vvtDelay = scalar, U08, 127, "S", 5.0, 0.0, 0, 1275, 0
;--------------------------------------------------
@ -2096,21 +2096,21 @@ menuDialog = main
vvtCLMinAng = "Safety limit for minimum expected cam angle value. If cam angle gets smaller or equal to this, it triggers VVT error state, closed loop adjustment is disabled and VVT output duty drops to 0%"
vvtCLMaxAng = "Safety limit for maximum expected cam angle value. If cam angle gets bigger than this, it triggers VVT error state, closed loop adjustment is disabled and VVT output duty drops to 0%"
ANGLEFILTER_VVT = "Can be used to smooth out cam angle readings if needed. Only supported on specific decoders that have cam angle reading capability"
vvtMinClt = "Minimum coolant temp to activate VVT"
vvtDelay = "Time to wait after reaching minimum coolant temp (additional time for oil warmup)"
vvtMinClt = "Minimum coolant temp to activate VVT"
vvtDelay = "Time to wait after reaching minimum coolant temp (additional time for oil warmup)"
stagedInjSizePri= "Size of the primary injectors. The sum of the Pri and Sec injectors values MUST match the value used in the req_fuel calculation"
stagedInjSizeSec= "Size of the secondary injectors. The sum of the Pri and Sec injectors values MUST match the value used in the req_fuel calculation"
#if resetcontrol_adv
resetControl = "How to control the Arduino's automatic reset feature. NOTE: Some of these settings require modifying your hardware and replacing the Arduino bootloader. See the Wiki for more details.\n\nDisabled: Allow the Arduino to reset when a new serial connection is made.\n\nPrevent When Running: Hold the control pin high while the engine is running.\n\nPrevent Always: Always hold the control pin high.\n\nSerial Command: Normally hold the control pin high, but pull it low when the 'U' serial command is issued and reset upon receiving more data."
resetControl = "How to control the Arduino's automatic reset feature. NOTE: Some of these settings require modifying your hardware and replacing the Arduino bootloader. See the Wiki for more details.\n\nDisabled: Allow the Arduino to reset when a new serial connection is made.\n\nPrevent When Running: Hold the control pin high while the engine is running.\n\nPrevent Always: Always hold the control pin high.\n\nSerial Command: Normally hold the control pin high, but pull it low when the 'U' serial command is issued and reset upon receiving more data."
#else
resetControl = "If set to Serial Command, normally hold the control pin high but pull it low when the 'U' serial command is issued and reset upon receiving more data. The control pin should be connected to the Arduino's reset pin."
resetControl = "If set to Serial Command, normally hold the control pin high but pull it low when the 'U' serial command is issued and reset upon receiving more data. The control pin should be connected to the Arduino's reset pin."
#endif
resetControlPin = "The Arduino pin used to control resets."
resetControlPin = "The Arduino pin used to control resets."
battVCorMode = "The Battery Voltage Correction value from the table below can either be applied on the whole injection Pulse Width value, or only on the Open Time value."
dwellTable = "Sets the dwell time in milliseconds based on RPM/load. This can be used to reduce stress/wear on ignition system where long dwell is not needed. And other areas can use longer dwell value if needed for stronger spark. Battery voltage correction is applied for these dwell values."
useDwellMap = "In normal operation mode this is set to No and speeduino will use fixed running dwell value. But if different dwell values are required across engine RPM/load range, this can be set to Yes and separate Dwell table defines running dwell value."
battVCorMode = "The Battery Voltage Correction value from the table below can either be applied on the whole injection Pulse Width value, or only on the Open Time value."
dwellTable = "Sets the dwell time in milliseconds based on RPM/load. This can be used to reduce stress/wear on ignition system where long dwell is not needed. And other areas can use longer dwell value if needed for stronger spark. Battery voltage correction is applied for these dwell values."
useDwellMap = "In normal operation mode this is set to No and speeduino will use fixed running dwell value. But if different dwell values are required across engine RPM/load range, this can be set to Yes and separate Dwell table defines running dwell value."
[UserDefined]

View File

@ -35,6 +35,8 @@ void wmiControl();
#define N2O_STAGE2_PIN_HIGH() *n2o_stage2_pin_port |= (n2o_stage2_pin_mask)
#define READ_N2O_ARM_PIN() ((*n2o_arming_pin_port & n2o_arming_pin_mask) ? true : false)
#define VVT_TIME_DELAY_MULTIPLIER 50
#define FAN_ON() ((configPage6.fanInv) ? FAN_PIN_LOW() : FAN_PIN_HIGH())
#define FAN_OFF() ((configPage6.fanInv) ? FAN_PIN_HIGH() : FAN_PIN_LOW())
@ -62,6 +64,9 @@ long boost_pwm_target_value;
long boost_cl_target_boost;
byte boostCounter;
byte vvtCounter;
uint32_t vvtWarmTime;
bool vvtIsHot;
bool vvtTimeHold;
byte fanHIGH = HIGH; // Used to invert the cooling fan output
byte fanLOW = LOW; // Used to invert the cooling fan output

View File

@ -9,16 +9,12 @@ A full copy of the license may be found in the projects root directory
#include "src/PID_v1/PID_v1.h"
#include "decoders.h"
uint32_t vvtTime;
bool vvtHot;
bool vvtTimeHold;
//Old PID method. Retained incase the new one has issues
//integerPID boostPID(&MAPx100, &boost_pwm_target_value, &boostTargetx100, configPage6.boostKP, configPage6.boostKI, configPage6.boostKD, DIRECT);
integerPID_ideal boostPID(&currentStatus.MAP, &currentStatus.boostDuty , &currentStatus.boostTarget, &configPage10.boostSens, &configPage10.boostIntv, configPage6.boostKP, configPage6.boostKI, configPage6.boostKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
integerPID vvtPID(&vvt_pid_current_angle, &currentStatus.vvt1Duty, &vvt_pid_target_angle, configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD, configPage6.vvtPWMdir); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
integerPID vvt2PID(&vvt2_pid_current_angle, &currentStatus.vvt2Duty, &vvt2_pid_target_angle, configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD, configPage4.vvt2PWMdir); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
/*
Fan control
*/
@ -130,8 +126,8 @@ void initialiseAuxPWM()
ENABLE_VVT_TIMER(); //Turn on the B compare unit (ie turn on the interrupt)
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
vvtTimeHold=false;
if (currentStatus.coolant >= (int)(configPage4.vvtMinClt - CALIBRATION_TEMPERATURE_OFFSET)) {vvtHot=true;} //Checks to see if coolant's already at operating temperature
vvtTimeHold = false;
if (currentStatus.coolant >= (int)(configPage4.vvtMinClt - CALIBRATION_TEMPERATURE_OFFSET)) { vvtIsHot = true; } //Checks to see if coolant's already at operating temperature
}
if( (configPage6.vvtEnabled == 0) && (configPage10.wmiEnabled >= 1) )
{
@ -306,150 +302,151 @@ void vvtControl()
{
if( (configPage6.vvtEnabled == 1) && (currentStatus.coolant >= (int)(configPage4.vvtMinClt - CALIBRATION_TEMPERATURE_OFFSET)) && (BIT_CHECK(currentStatus.engine, BIT_ENGINE_RUN)))
{
if (vvtTimeHold==false)
{
vvtTime = runSecsX10;
vvtTimeHold=true;
}
if (((runSecsX10 - vvtTime) >= (configPage4.vvtDelay * 50)) || (vvtHot==true)) {
vvtHot=true;
//currentStatus.vvt1Duty = 0;
//Calculate the current cam angle
if( configPage4.TrigPattern == 9 ) { currentStatus.vvt1Angle = getCamAngle_Miata9905(); }
if( (configPage6.vvtMode == VVT_MODE_OPEN_LOOP) || (configPage6.vvtMode == VVT_MODE_ONOFF) )
if(vvtTimeHold == false)
{
//Lookup VVT duty based on either MAP or TPS
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt1Duty = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt1Duty = get3DTableValue(&vvtTable, currentStatus.MAP, currentStatus.RPM); }
vvtWarmTime = runSecsX10;
vvtTimeHold = true;
}
if( (vvtIsHot == true) || ((runSecsX10 - vvtWarmTime) >= (configPage4.vvtDelay * VVT_TIME_DELAY_MULTIPLIER)) )
{
vvtIsHot = true;
//VVT table can be used for controlling on/off switching. If this is turned on, then disregard any interpolation or non-binary values
if( (configPage6.vvtMode == VVT_MODE_ONOFF) && (currentStatus.vvt1Duty < 200) ) { currentStatus.vvt1Duty = 0; }
//Calculate the current cam angle
if( configPage4.TrigPattern == 9 ) { currentStatus.vvt1Angle = getCamAngle_Miata9905(); }
vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
if( (configPage6.vvtMode == VVT_MODE_OPEN_LOOP) || (configPage6.vvtMode == VVT_MODE_ONOFF) )
{
//Lookup VVT duty based on either MAP or TPS
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt2Duty = get3DTableValue(&vvt2Table, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt2Duty = get3DTableValue(&vvt2Table, currentStatus.MAP, currentStatus.RPM); }
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt1Duty = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt1Duty = get3DTableValue(&vvtTable, currentStatus.MAP, currentStatus.RPM); }
//VVT table can be used for controlling on/off switching. If this is turned on, then disregard any interpolation or non-binary values
if( (configPage6.vvtMode == VVT_MODE_ONOFF) && (currentStatus.vvt2Duty < 200) ) { currentStatus.vvt2Duty = 0; }
if( (configPage6.vvtMode == VVT_MODE_ONOFF) && (currentStatus.vvt1Duty < 200) ) { currentStatus.vvt1Duty = 0; }
vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
}
} //Open loop
else if( (configPage6.vvtMode == VVT_MODE_CLOSED_LOOP) )
{
//Lookup VVT duty based on either MAP or TPS
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt1TargetAngle = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt1TargetAngle = get3DTableValue(&vvtTable, currentStatus.MAP, currentStatus.RPM); }
if( (vvtCounter & 31) == 1) { vvtPID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
vvtPID.SetControllerDirection(configPage6.vvtPWMdir); }
// safety check that the cam angles are ok. The engine will be totally undriveable if the cam sensor is faulty and giving wrong cam angles, so if that happens, default to 0 duty.
// This also prevents using zero or negative current angle values for PID adjustment, because those don't work in integer PID.
if ( currentStatus.vvt1Angle <= configPage10.vvtCLMinAng || currentStatus.vvt1Angle > configPage10.vvtCLMaxAng )
{
currentStatus.vvt1Duty = 0;
vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
BIT_SET(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
//Check that we're not already at the angle we want to be
else if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt1TargetAngle == currentStatus.vvt1Angle) )
{
currentStatus.vvt1Duty = configPage10.vvtCLholdDuty;
vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
vvtPID.Initialize();
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
else
{
//This is dumb, but need to convert the current angle into a long pointer.
vvt_pid_target_angle = (unsigned long)currentStatus.vvt1TargetAngle;
vvt_pid_current_angle = (long)currentStatus.vvt1Angle;
//If not already at target angle, calculate new value from PID
bool PID_compute = vvtPID.Compute(true);
//vvtPID.Compute2(currentStatus.vvt1TargetAngle, currentStatus.vvt1Angle, false);
//vvt_pwm_target_value = percentage(40, vvt_pwm_max_count);
//if (currentStatus.vvt1Angle > currentStatus.vvt1TargetAngle) { vvt_pwm_target_value = 0; }
if(PID_compute == true) { vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count); }
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
{
//Lookup VVT duty based on either MAP or TPS
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt2Duty = get3DTableValue(&vvt2Table, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt2Duty = get3DTableValue(&vvt2Table, currentStatus.MAP, currentStatus.RPM); }
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
//VVT table can be used for controlling on/off switching. If this is turned on, then disregard any interpolation or non-binary values
if( (configPage6.vvtMode == VVT_MODE_ONOFF) && (currentStatus.vvt2Duty < 200) ) { currentStatus.vvt2Duty = 0; }
vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
}
} //Open loop
else if( (configPage6.vvtMode == VVT_MODE_CLOSED_LOOP) )
{
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt2TargetAngle = get3DTableValue(&vvt2Table, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt2TargetAngle = get3DTableValue(&vvt2Table, currentStatus.MAP, currentStatus.RPM); }
//Lookup VVT duty based on either MAP or TPS
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt1TargetAngle = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt1TargetAngle = get3DTableValue(&vvtTable, currentStatus.MAP, currentStatus.RPM); }
if( vvtCounter == 30) { vvt2PID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
vvt2PID.SetControllerDirection(configPage4.vvt2PWMdir); }
if( (vvtCounter & 31) == 1) { vvtPID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
vvtPID.SetControllerDirection(configPage6.vvtPWMdir); }
// safety check that the cam angles are ok. The engine will be totally undriveable if the cam sensor is faulty and giving wrong cam angles, so if that happens, default to 0 duty.
// This also prevents using zero or negative current angle values for PID adjustment, because those don't work in integer PID.
if ( currentStatus.vvt2Angle <= configPage10.vvtCLMinAng || currentStatus.vvt2Angle > configPage10.vvtCLMaxAng )
if ( currentStatus.vvt1Angle <= configPage10.vvtCLMinAng || currentStatus.vvt1Angle > configPage10.vvtCLMaxAng )
{
currentStatus.vvt2Duty = 0;
vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
BIT_SET(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
currentStatus.vvt1Duty = 0;
vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
BIT_SET(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
//Check that we're not already at the angle we want to be
else if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt2TargetAngle == currentStatus.vvt2Angle) )
else if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt1TargetAngle == currentStatus.vvt1Angle) )
{
currentStatus.vvt2Duty = configPage10.vvtCLholdDuty;
vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
vvt2PID.Initialize();
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
currentStatus.vvt1Duty = configPage10.vvtCLholdDuty;
vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count);
vvtPID.Initialize();
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
else
{
//This is dumb, but need to convert the current angle into a long pointer.
vvt2_pid_target_angle = (unsigned long)currentStatus.vvt2TargetAngle;
vvt2_pid_current_angle = (long)currentStatus.vvt2Angle;
//If not already at target angle, calculate new value from PID
bool PID_compute = vvt2PID.Compute(true);
if(PID_compute == true) { vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count); }
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
}
//currentStatus.vvt1Duty = 0;
vvtCounter++;
}
vvt_pid_target_angle = (unsigned long)currentStatus.vvt1TargetAngle;
vvt_pid_current_angle = (long)currentStatus.vvt1Angle;
//Set the PWM state based on the above lookups
if( (currentStatus.vvt1Duty == 0) && (currentStatus.vvt2Duty == 0) )
{
//Make sure solenoid is off (0% duty)
VVT1_PIN_OFF();
VVT2_PIN_OFF();
vvt1_pwm_state = false;
vvt1_max_pwm = false;
vvt2_pwm_state = false;
vvt2_max_pwm = false;
DISABLE_VVT_TIMER();
}
else if( (currentStatus.vvt1Duty >= 200) && (currentStatus.vvt2Duty >= 200) )
{
//Make sure solenoid is on (100% duty)
VVT1_PIN_ON();
VVT2_PIN_ON();
vvt1_pwm_state = true;
vvt1_max_pwm = true;
vvt2_pwm_state = true;
vvt2_max_pwm = true;
DISABLE_VVT_TIMER();
}
else
{
//Duty cycle is between 0 and 100. Make sure the timer is enabled
ENABLE_VVT_TIMER();
if(currentStatus.vvt1Duty < 200) { vvt1_max_pwm = false; }
if(currentStatus.vvt2Duty < 200) { vvt2_max_pwm = false; }
}
//If not already at target angle, calculate new value from PID
bool PID_compute = vvtPID.Compute(true);
//vvtPID.Compute2(currentStatus.vvt1TargetAngle, currentStatus.vvt1Angle, false);
//vvt_pwm_target_value = percentage(40, vvt_pwm_max_count);
//if (currentStatus.vvt1Angle > currentStatus.vvt1TargetAngle) { vvt_pwm_target_value = 0; }
if(PID_compute == true) { vvt1_pwm_value = halfPercentage(currentStatus.vvt1Duty, vvt_pwm_max_count); }
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT1_ERROR);
}
if (configPage10.vvt2Enabled == 1) // same for VVT2 if it's enabled
{
if(configPage6.vvtLoadSource == VVT_LOAD_TPS) { currentStatus.vvt2TargetAngle = get3DTableValue(&vvt2Table, currentStatus.TPS, currentStatus.RPM); }
else { currentStatus.vvt2TargetAngle = get3DTableValue(&vvt2Table, currentStatus.MAP, currentStatus.RPM); }
if( vvtCounter == 30) { vvt2PID.SetTunings(configPage10.vvtCLKP, configPage10.vvtCLKI, configPage10.vvtCLKD); //This only needs to be run very infrequently, once every 32 calls to vvtControl(). This is approx. once per second
vvt2PID.SetControllerDirection(configPage4.vvt2PWMdir); }
// safety check that the cam angles are ok. The engine will be totally undriveable if the cam sensor is faulty and giving wrong cam angles, so if that happens, default to 0 duty.
// This also prevents using zero or negative current angle values for PID adjustment, because those don't work in integer PID.
if ( currentStatus.vvt2Angle <= configPage10.vvtCLMinAng || currentStatus.vvt2Angle > configPage10.vvtCLMaxAng )
{
currentStatus.vvt2Duty = 0;
vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
BIT_SET(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
//Check that we're not already at the angle we want to be
else if((configPage6.vvtCLUseHold > 0) && (currentStatus.vvt2TargetAngle == currentStatus.vvt2Angle) )
{
currentStatus.vvt2Duty = configPage10.vvtCLholdDuty;
vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count);
vvt2PID.Initialize();
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
else
{
//This is dumb, but need to convert the current angle into a long pointer.
vvt2_pid_target_angle = (unsigned long)currentStatus.vvt2TargetAngle;
vvt2_pid_current_angle = (long)currentStatus.vvt2Angle;
//If not already at target angle, calculate new value from PID
bool PID_compute = vvt2PID.Compute(true);
if(PID_compute == true) { vvt2_pwm_value = halfPercentage(currentStatus.vvt2Duty, vvt_pwm_max_count); }
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_VVT2_ERROR);
}
}
//currentStatus.vvt1Duty = 0;
vvtCounter++;
}
//Set the PWM state based on the above lookups
if( (currentStatus.vvt1Duty == 0) && (currentStatus.vvt2Duty == 0) )
{
//Make sure solenoid is off (0% duty)
VVT1_PIN_OFF();
VVT2_PIN_OFF();
vvt1_pwm_state = false;
vvt1_max_pwm = false;
vvt2_pwm_state = false;
vvt2_max_pwm = false;
DISABLE_VVT_TIMER();
}
else if( (currentStatus.vvt1Duty >= 200) && (currentStatus.vvt2Duty >= 200) )
{
//Make sure solenoid is on (100% duty)
VVT1_PIN_ON();
VVT2_PIN_ON();
vvt1_pwm_state = true;
vvt1_max_pwm = true;
vvt2_pwm_state = true;
vvt2_max_pwm = true;
DISABLE_VVT_TIMER();
}
else
{
//Duty cycle is between 0 and 100. Make sure the timer is enabled
ENABLE_VVT_TIMER();
if(currentStatus.vvt1Duty < 200) { vvt1_max_pwm = false; }
if(currentStatus.vvt2Duty < 200) { vvt2_max_pwm = false; }
}
}
}