Files
MX5-Arduino/cas.ino
T
2019-05-06 18:01:30 +01:00

146 lines
4.7 KiB
Arduino

void cas_process()
{
// SGT is a pulse for TDC of *any* cylinder. By combining this with SGT it's possible to
// identify which cylinder it is
byte sgt = digitalRead(pin_cas_sgt);
unsigned long timestamp = micros();
// Simple rev limiter, drop the spark until we're slow again and set a flag so we log it
// at the next chance we get
if(rpm_current_value > rpm_range_max)
{
rpm_limited_log = 1;
rpm_limited = 1;
}else{
rpm_limited = 0;
}
// Find rising edge
if(sgt == 1)
{
if(cas_sgt_lastvalue == 0)
{
// Handle tach
task_tach_high = micros();
// Log when it was
cas_sgt_lastrise = timestamp;
}
}
// Find falling edge
if(sgt == 0)
{
if(cas_sgt_lastvalue == 1)
{
// Difference between last and current is 180 degrees
usec_per_degree = (timestamp - cas_sgt_lastfall) / 180;
// Log when it was
cas_sgt_lastfall = timestamp;
// If we have crank pulse present then cyl1 is TDC
if(digitalRead(pin_cas_sgc) == HIGH)
{
// If we've arrived at cylinder 1 unexpectedly then we need to know!
// We'll drop sparks until we're back and log it
if(cylinder_next_seq[cylinder_tdc] != 1)
{
// Don't output if it's already happened once
if(cas_sync_fail == 0)
cas_sync_fail_log=1;
// Log fail so we abandon time sensitive stuff
cas_sync_fail=1;
}
else
{
// Clear it if we're in sync, but don't clear log flag
if(cas_sync_initial == 1)
{
cas_sync_initial = 0;
cas_sync_fail = 0;
cas_sync_fail_log = 0;
}
}
// Use this number because we KNOW it's right
cylinder_tdc = 1;
}
else
{
cylinder_tdc = cylinder_next_seq[cylinder_tdc];
}
// Schedule next cylinder, this one is already past TDC
cylinder_next_fire = cylinder_next_seq[cylinder_tdc];
// If we're out of sync, we kill ignition for a bit for now. Same if we're at crazy RPM
if((cas_sync_fail == 0) && (rpm_limited == 0))
{
// Igntion
if((cylinder_next_fire == 1) || (cylinder_next_fire == 4))
{
task_coil1_fire = micros() + (usec_per_degree * (180 + ignition_offset - table_ignition[rpm_current_index + (map_current_index << 4)]));
task_coil1_charge = task_coil1_fire - (coil_dwell + table_dwell_voltage[battery_voltage_index] + table_dwell_rpm[rpm_current_index]);
}else if((cylinder_next_fire == 2) || (cylinder_next_fire == 3))
{
task_coil2_fire = micros() + (usec_per_degree * (180 + ignition_offset - table_ignition[rpm_current_index + (map_current_index << 4)]));
task_coil2_charge = task_coil2_fire - (coil_dwell + table_dwell_voltage[battery_voltage_index] + table_dwell_rpm[rpm_current_index]);
}
// Injection
if(cylinder_next_fire == 1)
{
task_injector1_close = micros() + (usec_per_degree * (360 + ignition_offset + 130));
task_injector1_open = task_injector1_close - table_pulsewidth[rpm_current_index + (map_current_index << 4)];
}else if(cylinder_next_fire == 2)
{
task_injector2_close = micros() + (usec_per_degree * (360 + ignition_offset + 130));
task_injector2_open = task_injector2_close - table_pulsewidth[rpm_current_index + (map_current_index << 4)];
}else if(cylinder_next_fire == 3)
{
task_injector3_close = micros() + (usec_per_degree * (360 + ignition_offset + 130));
task_injector3_open = task_injector3_close - table_pulsewidth[rpm_current_index + (map_current_index << 4)];
}else if(cylinder_next_fire == 4)
{
task_injector4_close = micros() + (usec_per_degree * (360 + ignition_offset + 130));
task_injector4_open = task_injector4_close - table_pulsewidth[rpm_current_index + (map_current_index << 4)];
}
}
}
}
// Save current state
cas_sgt_lastvalue = sgt;
// SGC is the once per revolution pulse. Used to identify when Cyl 1 is TDC (as opposed to 4)
// and is also handy for determining RPM if you trigger on the leading edge
byte sgc = digitalRead(pin_cas_sgc);
timestamp = micros();
// Find rising edge
if(sgc == 1)
{
if(cas_sgc_lastvalue == 0)
{
// For rising edge (the consitent one) we need to update RPM
rpm_current_value = 60000000 / (timestamp - cas_sgc_lastrise);
cas_sgc_lastrise = timestamp;
}
}
// Find falling edge
if(sgc == 0)
{
if(cas_sgc_lastvalue == 1)
{
cas_sgc_lastfall= timestamp;
}
}
cas_sgc_lastvalue = sgc;
}