diff -Naur firmware-20041124/dispatcher.c firmware-20041127/dispatcher.c --- firmware-20041124/dispatcher.c 2004-11-19 14:10:55.000000000 +0100 +++ firmware-20041127/dispatcher.c 2005-08-03 23:03:35.000000000 +0200 @@ -156,23 +156,20 @@ // #ifndef NOIGN void disp_edis_stop_saw(uint8_t upper_v){ // EDIS_STOP_SAW: - ign_deactivate(); + ign_deactivate(upper_v); heap_del1st(heap_normal); // no need to insert an event (next PIP pulse will) } -void disp_ignact(uint8_t upper_v){ // IGNACT: +void disp_ignact(uint8_t upper_v){ // IGNACT: igncount is passed as argument // now one pin, later the right channel: - ign_activate(); -#ifdef KNOCK_8101 - // check that the mainloop can keep up - if (knock_stats.ve_igncount != engine.igncount) - knock_stats.dwell_err++; -#endif + ign_activate(upper_v); + // only schedule the firing if it's not yet done: if(engine.ignstate != 3){ if(engine.ignstate == 1){ - event_insert_destroy(engine.sparkat, IGNDEACT); + + event_insert_destroy(engine.sparkat, v_shiftup(upper_v) + IGNDEACT); engine.ignstate = 2; #ifdef V3_IGN_DRIVE_A test_ign_deactivate_at(engine.sparkat); @@ -180,7 +177,7 @@ } else { // state is probably 2, IGNDEACT already scheduled // state cannot be 0, but just in case: if(engine.ignstate==0){ - ign_deactivate(); + ign_deactivate(upper_v); } heap_del1st(heap_normal); // do not touch ignstate @@ -189,39 +186,26 @@ heap_del1st(heap_normal); engine.ignstate = 4; // if trigger is stopped, dummyign coils would fry? - // see megasquirt.c protection in sevenms that + // see vems.c protection in sevenms that // deactivates ignition. // Releasing a spark at arbitrary time is also not very good. // sudden outage of trigger signal at high RPM // (only case when we can get here) is not good in general. } + } -void disp_igndeact(uint8_t upper_v){ // IGNDEACT: - uint8_t t8; +void disp_igndeact(uint8_t upper_v){ // IGNDEACT: igncount is passed as argument // London's burning: - ign_deactivate(); - -#ifdef KNOCK_8101 - // check that the mainloop can keep up - if (knock_stats.ve_igncount != engine.igncount) - knock_stats.adv_err++; -// t8 is used by the knock detection to determine which cylinder is fired. - t8 = engine.igncount; // remember which cylinder is on fire -#endif + ign_deactivate(upper_v); - if(engine.igncount) engine.igncount--; - else engine.igncount = config.ignchmax; -#ifdef BENCHMARK - benchmark_histogram(ic3_histogram, etime.now - engine.sparkat, IC3HISTOGRAM_BUCKETS); -#endif // engine.ignstate is 2 here, I guess // always let 400 usec for off: #define IGN_MIN_INACTIVE (100) // early_dwellstart only set if last rpm_period was small or trig2spark was small if((engine.status_ext & _BV(early_dwellstart)) && ((engine.rpm_period >> 16)==0)){ - uint16_t inactive_time, per, de; + uint16_t inactive_time, per, de, ic; #ifdef LATE_CORRECTION uint8_t late; @@ -241,21 +225,21 @@ else // we shorten the dwell if we don't have enough time: inactive_time = IGN_MIN_INACTIVE; -// event_insert_destroy(engine.sparkat + inactive_time, IGNACT); - event_insert_destroy(etime.now + inactive_time, IGNACT); + ic = next_igncount(upper_v); + event_insert_destroy(etime.now + inactive_time, v_shiftup(ic) + IGNACT); #ifdef V3_IGN_DRIVE_A test_ign_activate_at(engine.sparkat + inactive_time); #endif #ifdef KNOCK_8101 if (knock_ready()) - event_insert(etime.now + knock.window_start, v_shiftup(t8) + KNOCK_START); + event_insert(etime.now + knock.window_start, v_shiftup(upper_v) + KNOCK_START); #endif engine.ignstate = 3; } else { #ifdef KNOCK_8101 if (knock_ready()) - event_insert_destroy(etime.now + knock.window_start, v_shiftup(t8) + KNOCK_START); + event_insert_destroy(etime.now + knock.window_start, v_shiftup(upper_v) + KNOCK_START); else #endif heap_del1st(heap_normal); @@ -269,21 +253,28 @@ // #endif // NOIGN void disp_stim_low(uint8_t upper_v){ // STIM_LOW: - uint16_t newtime; if(debug.stim_period >= 32){ + uint8_t t, stim_tooth; + uint16_t newtime; #ifdef GENBOARDv3 digitalout(config.act_wot_channel, DLOW); #else // on v2 using panel LED for stim-out LEDPORT &= ~_BV(LED_STATUS); #endif - newtime = debug.stim_nexttime + debug.stim_period; - // upcounting ??? what?? - debug.stim_toothnow ++; - if(debug.stim_toothnow >= (debug.stim_tooth & 63)){ // let's insert some missing teeth - debug.stim_toothnow = 0; - // not >>6 because we want 2 * mst.._upper2bits * debug.stim_period - // don't care about overflow. - newtime += mult16_8(debug.stim_period,(uint8_t)(debug.stim_tooth>>5)); + newtime = debug.stim_nexttime; + t = debug.stim_toothnow; + stim_tooth = debug.stim_tooth; + if((t == 0) && (stim_tooth & 0xC0)){ + // let's insert some missing teeth + debug.stim_toothnow = (stim_tooth & 0x3F) - 1; + // not >> 6 because we want + // debug.stim_period * (2 * mst.._upper2bits + 1 ) + // user must prevent overflow. + newtime += mult16_8(debug.stim_period,(uint8_t)(stim_tooth>>5) | 1); + } else { + newtime += debug.stim_period; + t--; + debug.stim_toothnow = t; } event_insert_destroy(newtime, STIM_HIGH); debug.stim_nexttime = newtime; diff -Naur firmware-20041124/doc/my_make firmware-20041127/doc/my_make --- firmware-20041124/doc/my_make 2004-10-14 18:51:10.000000000 +0200 +++ firmware-20041127/doc/my_make 2004-11-25 00:57:23.000000000 +0100 @@ -52,7 +52,7 @@ # MY_CONF += -D DIRECT_IGN # MSTweak3000 is broken, we zero the idle bit (send status & 127) so it does not fall to knees -MY_CONF += -D MS_COMPATIBILITY +#MY_CONF += -D MS_COMPATIBILITY # WBO2 related config: (you need a license to enable it, see Copyright in wbo2.c) # WBO2 support on v2 (with helper circuit) will be gone soon diff -Naur firmware-20041124/edis.c firmware-20041127/edis.c --- firmware-20041124/edis.c 2004-10-10 00:32:25.000000000 +0200 +++ firmware-20041127/edis.c 2005-08-03 23:03:35.000000000 +0200 @@ -44,10 +44,15 @@ */ #define ignport_map(x) (hwmap.table[2*HWMAP_SIZE+x]) + +static inline uint8_t next_igncount(uint8_t ic) { + if (ic) ic--; + else ic = config.ignchmax; + return ic; +} -static inline void ign_activate(void){ +static inline void ign_activate(uint8_t enignct){ uint8_t ch, sign; - uint8_t enignct = engine.igncount; ch = ignport_map(enignct); sign = config.ign_out & _BV(IGN_INVERTOUT); if(sign) { @@ -79,9 +84,8 @@ * MUST be called under cli() * \return none */ -static inline void ign_deactivate(void){ +static inline void ign_deactivate(uint8_t enignct){ uint8_t ch, sign; - uint8_t enignct = engine.igncount; /* this condition could only set a variable to DHIGH or DLOW * However by using constants, maybe gcc makes some optimizations, * using slightly more flash @@ -175,7 +179,7 @@ * * \return none */ -static inline void ign_activate(void){ +static inline void ign_activate(uint8_t t){ if(config.ign_out & _BV(IGN_INVERTOUT)) IGN_PORT &= ~_BV(IGN_OUT); else @@ -187,7 +191,7 @@ * * \return none */ -static inline void ign_deactivate(void){ +static inline void ign_deactivate(uint8_t t){ if(config.ign_out & _BV(IGN_INVERTOUT)) IGN_PORT |= _BV(IGN_OUT); else @@ -233,7 +237,7 @@ #else // GENBOARD v2.2 IGN_DDR |= _BV(IGN_OUT); // set port to output #ifdef __MEGASQUIRT_C__ - ign_deactivate(); + ign_deactivate(0); #else // arghhh.: // ioinit() when used from bootloader does not know about config diff -Naur firmware-20041124/eventqueue.h firmware-20041127/eventqueue.h --- firmware-20041124/eventqueue.h 2004-09-19 22:40:45.000000000 +0200 +++ firmware-20041127/eventqueue.h 2004-11-24 22:57:00.000000000 +0100 @@ -130,10 +130,6 @@ uint16_t strig_capturedtime_dwell; - uint8_t tooth_cnt; // tooth wheel in sync when etime.tooth_cnt < 128. Initial sync sequence is downcounting from 255 - uint32_t prev_missing_tooth; - uint16_t average_tooth_period; - uint32_t primary_trigger; uint8_t ego_warmup_cnt; diff -Naur firmware-20041124/fuelcalc.c firmware-20041127/fuelcalc.c --- firmware-20041124/fuelcalc.c 2005-08-03 22:38:30.000000000 +0200 +++ firmware-20041127/fuelcalc.c 2005-08-03 23:03:35.000000000 +0200 @@ -125,6 +125,7 @@ } #endif +#ifdef GENBOARDv3 // calculate injector bitmask used when firing all injectors simultaneously i = config.alternate & 0x0f; mask = injport_map(i); @@ -133,6 +134,7 @@ mask |= injport_map(i); } engine.injector_bitmask = mask; +#endif } void init_fuelcalc(void) { diff -Naur firmware-20041124/fuelcontrol.c firmware-20041127/fuelcontrol.c --- firmware-20041124/fuelcontrol.c 2004-11-02 15:47:03.000000000 +0100 +++ firmware-20041127/fuelcontrol.c 2005-08-03 23:03:35.000000000 +0200 @@ -32,6 +32,7 @@ #include "benchmark.h" #include "timing.h" #include "knock.h" +#include "multitooth.c" #ifdef CAPTURE_ALIEN_ECU #include "ign_logging.h" @@ -186,7 +187,7 @@ engine.status_trig = 0; // the toothwheel is initially not in sync - etime.tooth_cnt = 255; + init_toothwheel(&toothwheel1); etime.cam_sync_cnt = 0; diff -Naur firmware-20041124/global.h firmware-20041127/global.h --- firmware-20041124/global.h 2004-11-19 14:31:25.000000000 +0100 +++ firmware-20041127/global.h 2004-11-26 17:41:20.000000000 +0100 @@ -17,6 +17,9 @@ #include #include +#ifndef IGNORE_WARNING +#warning "***** CENTRAL PARTS OF THE FIRMWARE ARE BEING REWORKED, BE VERY CAREFUL! *****" +#endif /* special hardware is defined in my_make (see doc/) */ #ifdef GENBOARDv3 @@ -427,6 +430,7 @@ uint8_t cam_sync_f_edge_phase; // cam sync, falling edge, engine phase at next primary trigger uint8_t reset_engphase_after; // engphase, when to reset + uint8_t engphase_sync; // engphase, set phase at missing tooth uint8_t ign_tdcdelay; // TDC after the trigger(0.5crankdeg) uint8_t ign_dwell14; // dwell above 14V (64usec) @@ -554,6 +558,7 @@ #define trigger_edge 0 // if 1, then rising edge #define ptrig_coil 1 // if 1, then use coil to trigger instead of toothwheel #define trigger_filter 2 // if 1, then filtering is enabled +#define simple_trigger (config.primary_trigger & _BV(ptrig_coil)) // trigger2 //#define trigger_edge 0 // if 1, then rising edge diff -Naur firmware-20041124/lcd_display.c firmware-20041127/lcd_display.c --- firmware-20041124/lcd_display.c 2005-08-03 22:40:00.000000000 +0200 +++ firmware-20041127/lcd_display.c 2005-08-03 23:03:35.000000000 +0200 @@ -30,6 +30,7 @@ #include "pid.h" #include "spi.h" #include "knock.h" +#include "multitooth.h" #include "lcd.h" #include "lcd_display.h" @@ -653,7 +654,7 @@ void lcd_S(void) { lcd_putch('S'); - printhex(etime.tooth_cnt); + printhex(toothwheel1.tooth_cnt); } void lcd_I(void) @@ -700,7 +701,7 @@ lcd_putch('E'); // Trigger error else if(engine.status_ext & _BV(baro_problem)) lcd_putch('B'); // MAP problem - else if((etime.tooth_cnt < 128) || (config.primary_trigger & _BV(ptrig_coil))) + else if((toothwheel1.tooth_cnt < 128) || (config.primary_trigger & _BV(ptrig_coil))) lcd_putch(' '); // Synchronized to wheel (or coil trigger), all OK. else lcd_putch('S'); // Wheel sync error @@ -1035,8 +1036,10 @@ #endif // MCP3208 int2BCDn(egtreading, lcd.next_pos, BCD_DIGIT4); +#ifdef MCP3208 } read_mcp3208(5); +#endif } diff -Naur firmware-20041124/magicstr.h firmware-20041127/magicstr.h --- firmware-20041124/magicstr.h 2005-08-03 22:37:17.000000000 +0200 +++ firmware-20041127/magicstr.h 2005-08-03 23:03:37.000000000 +0200 @@ -167,54 +167,55 @@ char _magic_str_199[] PROGMEM = "cam sync, rising edge, engine phase at next primary trigger"; char _magic_str_200[] PROGMEM = "cam sync, falling edge, engine phase at next primary trigger"; char _magic_str_201[] PROGMEM = "engphase, when to reset"; -char _magic_str_202[] PROGMEM = "TDC after the trigger(0.5crankdeg)"; -char _magic_str_203[] PROGMEM = "dwell above 14V (64usec)"; -char _magic_str_204[] PROGMEM = "added dwell time at 6V (27usec)"; -char _magic_str_205[] PROGMEM = "ignition advance at cranking [0.25crankdeg]"; -char _magic_str_206[] PROGMEM = "EDIS:0x0? dummy: 0x7? disable:0xff bit0: invertout"; -char _magic_str_207[] PROGMEM = "h[2] maxindex for ignition channel lookup"; -char _magic_str_208[] PROGMEM = "turn off fuelpump after inactivity time [262msec]"; -char _magic_str_209[] PROGMEM = "minimum time to leave fuelpump on at startup [262msec]"; -char _magic_str_210[] PROGMEM = "output selection for fuelpump"; -char _magic_str_211[] PROGMEM = "secondary injectors rate to calculated pw [0.4%]"; -char _magic_str_212[] PROGMEM = "secondary injectors open above given throttle"; -char _magic_str_213[] PROGMEM = "secondary injectors open above given manifold pressure"; -char _magic_str_214[] PROGMEM = "als,auto-off below this rpm [100 rpm]"; -char _magic_str_215[] PROGMEM = "als,maximum TPS position"; -char _magic_str_216[] PROGMEM = "als,ignition retard [1/4 crankdegrees]"; -char _magic_str_217[] PROGMEM = "als,mixture enrichment in percents [0.4%]"; -char _magic_str_218[] PROGMEM = "misc1out,minimum rpm [100 rpm]"; -char _magic_str_219[] PROGMEM = "misc1out,maximum rpm [100 rpm]"; -char _magic_str_220[] PROGMEM = "misc1out,minimum tps position"; -char _magic_str_221[] PROGMEM = "misc1out,maximum tps position"; -char _magic_str_222[] PROGMEM = "misc1out,minimum manifold pressure"; -char _magic_str_223[] PROGMEM = "misc1out,maximum manifold pressure"; -char _magic_str_224[] PROGMEM = "misc1out,output channel selector"; -char _magic_str_225[] PROGMEM = "misc2out,minimum rpm [100 rpm]"; -char _magic_str_226[] PROGMEM = "misc2out,maximum rpm [100 rpm]"; -char _magic_str_227[] PROGMEM = "misc2out,minimum tps position"; -char _magic_str_228[] PROGMEM = "misc2out,maximum tps position"; -char _magic_str_229[] PROGMEM = "misc2out,minimum manifold pressure"; -char _magic_str_230[] PROGMEM = "misc2out,maximum manifold pressure"; -char _magic_str_231[] PROGMEM = "misc2out,output channel selector"; -char _magic_str_232[] PROGMEM = "WOT switch RPM threshold (FF=disable)"; -char _magic_str_233[] PROGMEM = "WOT switch output channel selector (P259_0)"; -char _magic_str_234[] PROGMEM = "RPM switch RPM threshold (FF=disable)"; -char _magic_str_235[] PROGMEM = "RPM switch output channel selector"; -char _magic_str_236[] PROGMEM = "EGT calibration multiplier"; -char _magic_str_237[] PROGMEM = "EGT offset (signed)"; -char _magic_str_238[] PROGMEM = "boostcontrol flags bit0 0:boosttarget,1:MAPtarget"; -char _magic_str_239[] PROGMEM = "boostcontrol target offset applied after b[RPM]*t[TPS]"; -char _magic_str_240[] PROGMEM = "actuator OFF below this pressure"; -char _magic_str_241[] PROGMEM = "boostcontrol pid kp"; -char _magic_str_242[] PROGMEM = "boostcontrol pid ki"; -char _magic_str_243[] PROGMEM = "boostcontrol pid kd"; -char _magic_str_244[] PROGMEM = "boostcontrol pid integral limit"; -char _magic_str_245[] PROGMEM = "boostcontrol solenoid"; -char _magic_str_246[] PROGMEM = "water pump, start temperature"; -char _magic_str_247[] PROGMEM = "water pump, hysteresis"; -char _magic_str_248[] PROGMEM = "water pump, output selection"; -char _magic_str_249[] PROGMEM = "No more variable, go back, don't touch"; +char _magic_str_202[] PROGMEM = "engphase, set phase at missing tooth"; +char _magic_str_203[] PROGMEM = "TDC after the trigger(0.5crankdeg)"; +char _magic_str_204[] PROGMEM = "dwell above 14V (64usec)"; +char _magic_str_205[] PROGMEM = "added dwell time at 6V (27usec)"; +char _magic_str_206[] PROGMEM = "ignition advance at cranking [0.25crankdeg]"; +char _magic_str_207[] PROGMEM = "EDIS:0x0? dummy: 0x7? disable:0xff bit0: invertout"; +char _magic_str_208[] PROGMEM = "h[2] maxindex for ignition channel lookup"; +char _magic_str_209[] PROGMEM = "turn off fuelpump after inactivity time [262msec]"; +char _magic_str_210[] PROGMEM = "minimum time to leave fuelpump on at startup [262msec]"; +char _magic_str_211[] PROGMEM = "output selection for fuelpump"; +char _magic_str_212[] PROGMEM = "secondary injectors rate to calculated pw [0.4%]"; +char _magic_str_213[] PROGMEM = "secondary injectors open above given throttle"; +char _magic_str_214[] PROGMEM = "secondary injectors open above given manifold pressure"; +char _magic_str_215[] PROGMEM = "als,auto-off below this rpm [100 rpm]"; +char _magic_str_216[] PROGMEM = "als,maximum TPS position"; +char _magic_str_217[] PROGMEM = "als,ignition retard [1/4 crankdegrees]"; +char _magic_str_218[] PROGMEM = "als,mixture enrichment in percents [0.4%]"; +char _magic_str_219[] PROGMEM = "misc1out,minimum rpm [100 rpm]"; +char _magic_str_220[] PROGMEM = "misc1out,maximum rpm [100 rpm]"; +char _magic_str_221[] PROGMEM = "misc1out,minimum tps position"; +char _magic_str_222[] PROGMEM = "misc1out,maximum tps position"; +char _magic_str_223[] PROGMEM = "misc1out,minimum manifold pressure"; +char _magic_str_224[] PROGMEM = "misc1out,maximum manifold pressure"; +char _magic_str_225[] PROGMEM = "misc1out,output channel selector"; +char _magic_str_226[] PROGMEM = "misc2out,minimum rpm [100 rpm]"; +char _magic_str_227[] PROGMEM = "misc2out,maximum rpm [100 rpm]"; +char _magic_str_228[] PROGMEM = "misc2out,minimum tps position"; +char _magic_str_229[] PROGMEM = "misc2out,maximum tps position"; +char _magic_str_230[] PROGMEM = "misc2out,minimum manifold pressure"; +char _magic_str_231[] PROGMEM = "misc2out,maximum manifold pressure"; +char _magic_str_232[] PROGMEM = "misc2out,output channel selector"; +char _magic_str_233[] PROGMEM = "WOT switch RPM threshold (FF=disable)"; +char _magic_str_234[] PROGMEM = "WOT switch output channel selector (P259_0)"; +char _magic_str_235[] PROGMEM = "RPM switch RPM threshold (FF=disable)"; +char _magic_str_236[] PROGMEM = "RPM switch output channel selector"; +char _magic_str_237[] PROGMEM = "EGT calibration multiplier"; +char _magic_str_238[] PROGMEM = "EGT offset (signed)"; +char _magic_str_239[] PROGMEM = "boostcontrol flags bit0 0:boosttarget,1:MAPtarget"; +char _magic_str_240[] PROGMEM = "boostcontrol target offset applied after b[RPM]*t[TPS]"; +char _magic_str_241[] PROGMEM = "actuator OFF below this pressure"; +char _magic_str_242[] PROGMEM = "boostcontrol pid kp"; +char _magic_str_243[] PROGMEM = "boostcontrol pid ki"; +char _magic_str_244[] PROGMEM = "boostcontrol pid kd"; +char _magic_str_245[] PROGMEM = "boostcontrol pid integral limit"; +char _magic_str_246[] PROGMEM = "boostcontrol solenoid"; +char _magic_str_247[] PROGMEM = "water pump, start temperature"; +char _magic_str_248[] PROGMEM = "water pump, hysteresis"; +char _magic_str_249[] PROGMEM = "water pump, output selection"; +char _magic_str_250[] PROGMEM = "No more variable, go back, don't touch"; PGM_VOID_P magicstr[] PROGMEM = { _magic_str_0, @@ -431,6 +432,7 @@ _magic_str_247, _magic_str_248, _magic_str_249, -NULL,NULL,NULL,NULL,NULL,NULL, +_magic_str_250, +NULL,NULL,NULL,NULL,NULL, NULL }; diff -Naur firmware-20041124/menu.c firmware-20041127/menu.c --- firmware-20041124/menu.c 2004-11-05 14:04:53.000000000 +0100 +++ firmware-20041127/menu.c 2005-08-03 23:03:35.000000000 +0200 @@ -1,4 +1,4 @@ -/* $Id: menu.c,v 1.133 2004/11/05 13:04:53 caffrey Exp $ */ +/* $Id: menu.c,v 1.134 2004/11/26 15:41:23 caffrey Exp $ */ /* written by Marcell Gal, cell at x-dsl.hu * similar as comm.c but with multichar commands. * TODO: control LCD or RS232 VT100 display according to the current submenu @@ -170,7 +170,7 @@ case MNUM_IGNDWELL: engine.igncount = newval; cli(); - ign_activate(); + ign_activate(engine.igncount); sei_nop_cli(); readTMR(); event_insert(etime.now + engine.dwell, IGNDEACT); diff -Naur firmware-20041124/multitooth.c firmware-20041127/multitooth.c --- firmware-20041124/multitooth.c 2004-10-09 23:29:49.000000000 +0200 +++ firmware-20041127/multitooth.c 2005-08-03 23:03:35.000000000 +0200 @@ -22,44 +22,53 @@ #include "eventqueue.h" #include "fuelcontrol.h" #include "benchmark.h" +#include "multitooth.h" +#include "edis.c" #include -#define TW_TRIG 0 -#define TW_MISSING 1 +struct multitooth_t toothwheel1; +struct trigger_t trigger1; + +static void init_toothwheel(struct multitooth_t *mt) { + mt->tooth_cnt = 255; +} + +static inline uint16_t next_tooth_period(struct multitooth_t *mt) { + return ((mt->average_tooth_period<<1) - mt->average_tooth_period_prev); +} + -// true if a > 1.5 * b (NOTE: b2 must be b/2) -#define significantly_bigger(a, b, b2) ((a > b) && ((a - b) > b2)) /* Tooth detection. Used from trigger interrupt. - - Bit definitions of trigger: - bit 0: trigger - bit 1: missing tooth - - tooth wheel in sync when etime.tooth_cnt < 128 - - tooth_detection operates on 16 bit period instead of 32 bit + + Tooth wheel in sync when etime.tooth_cnt < 128 */ -static inline uint8_t tooth_detection(uint16_t period16, uint32_t capturedtime) { +static inline uint8_t tooth_detection(uint16_t period16, uint32_t capturedtime, struct multitooth_t *mt) { uint8_t trigger = 0, tooth_cnt, c_trigger_tooth, c_another_trigger_tooth; - uint16_t etime_atp, etime_atp2; + uint16_t mt_atp, mt_atp2; - tooth_cnt = etime.tooth_cnt; - - etime_atp = etime.average_tooth_period; - etime_atp2 = etime_atp >> 1; // half + tooth_cnt = mt->tooth_cnt; + + mt_atp = mt->average_tooth_period; + mt_atp2 = mt_atp >> 1; // half if (tooth_cnt < 128) { // wheel_in_sync tooth_cnt++; - if (significantly_bigger(period16, etime_atp, etime_atp2)) { // found the missing tooth +#ifdef GENBOARDv3 + PORTD &= ~_BV(CS_CAN); +#endif + if (significantly_bigger(period16, mt_atp, mt_atp2)) { // found the missing tooth if (tooth_cnt == config.tooth_wheel) { - engine.rpm_period = capturedtime - etime.prev_missing_tooth; - etime.prev_missing_tooth = capturedtime; + engine.rpm_period = capturedtime - mt->prev_missing_tooth; + mt->prev_missing_tooth = capturedtime; engine.status_ext |= _BV(new_rpm); // start a rpm calculation trigger = _BV(TW_MISSING); // trigger was 0 tooth_cnt = 0; +#ifdef GENBOARDv3 + PORTD |= _BV(CS_CAN); +#endif } else { // something went wrong, result of the tooth wheel decoding cannot be trusted engine.status_trig |= _BV(wheel_error); @@ -73,35 +82,33 @@ } } } else { // NOT wheel_in_sync -#define TOOTH_WHEEL_NOISE 4 -#define TOOTH_WHEEL_CNT 4 -#define TOOTH_WHEEL_LISTEN (TOOTH_WHEEL_NOISE + TOOTH_WHEEL_CNT) engine_is_running(); //turn on fuelpump etc. // do a rather long sync sequence to avoid getting wild rpm readings during the first rotation if (tooth_cnt < (255 - TOOTH_WHEEL_LISTEN)) { // initialization done, find the missing tooth - if (significantly_bigger(period16, etime_atp, etime_atp2)) { // got the tooth + if (significantly_bigger(period16, mt_atp, mt_atp2)) { // got the tooth engine.status_trig &= ~_BV(wheel_error); - etime.prev_missing_tooth = capturedtime; - trigger |= _BV(TW_MISSING); + mt->prev_missing_tooth = capturedtime; + trigger |= _BV(TW_MISSING) | _BV(TW_MISSING_SYNC); tooth_cnt = 0; } // else stay unsynced tooth_cnt kept constant at 254 - TOOTH_WHEEL_LISTEN - // note that we do update etime.average_tooth_period before return + // note that we do update mt->average_tooth_period before return } else { // assume the first pulses are noise --tooth_cnt; if (tooth_cnt > 255 - TOOTH_WHEEL_NOISE){ // we don't even avarage at this point. // (although a bogus 0xffff * 4usec would decay fast) - etime.average_tooth_period = period16; // doesn't hurt to save it - etime.tooth_cnt = tooth_cnt; + mt->average_tooth_period = period16; // doesn't hurt to save it + mt->tooth_cnt = tooth_cnt; return 0; } // else note the average_tooth_period averaging } } +//#ifndef TRIG_FROM_LAST_TOOTH // the trigger can be "moved" through config // this allows all kind of strange setups, ex. having the missing tooth 180 degrees BTDC c_trigger_tooth = config.trigger_tooth; @@ -121,16 +128,31 @@ // rpmk and ncyl could be used to handle this, but this way we use a more recent rpm_period // TODO: more than 4 cyl if (c_another_trigger_tooth && tooth_cnt == c_another_trigger_tooth) { - engine.rpm_period = capturedtime - etime.prev_missing_tooth; - etime.prev_missing_tooth = capturedtime; + engine.rpm_period = capturedtime - mt->prev_missing_tooth; + mt->prev_missing_tooth = capturedtime; engine.status_ext |= _BV(new_rpm); // start a rpm calculation - // trigger = _BV(TW_MISSING); // TODO: do we want this ?? +#ifdef GENBOARDv3 + PORTD |= _BV(CS_CAN); +#endif + // trigger = _BV(TW_MISSING); // TODO: do we want this ?? NO! } - etime.tooth_cnt = tooth_cnt; +#ifdef TRIG_FROM_LAST_TOOTH +#ifdef DEBUG_LAST_TRIG + // this is the old-style trigger scheme + if (tooth_cnt == c_trigger_tooth + || tooth_cnt == c_trigger_tooth + c_another_trigger_tooth) { + trigger |= _BV(TW_REGULAR_TRIG); + } +#endif +#endif +//#endif // TRIG_FROM_LAST_TOOTH + mt->tooth_cnt = tooth_cnt; // first take the half, than add them! Overflow is more concern than 4 usec precision - etime.average_tooth_period = etime_atp2 + (period16 >> 1); +// mt->average_tooth_period_prev = mt->average_tooth_period; + mt->average_tooth_period = mt_atp2 + (period16 >> 1); return trigger; } + #endif diff -Naur firmware-20041124/multitooth.h firmware-20041127/multitooth.h --- firmware-20041124/multitooth.h 1970-01-01 01:00:00.000000000 +0100 +++ firmware-20041127/multitooth.h 2004-11-26 23:55:29.000000000 +0100 @@ -0,0 +1,49 @@ +#ifndef __MULTITOOTH_H__ +#define __MULTITOOTH_H__ + +#include +#include "ve.h" + +// Bit definitions of trigger: +// bit 0: trigger +// bit 1: missing tooth +// bit 2: missing tooth (sync), hint that the tooth was found during the synchronization sequence +// bit 3: debug +#define TW_TRIG 0 +#define TW_MISSING 1 +#define TW_MISSING_SYNC 2 +#define TW_REGULAR_TRIG 3 + +// true if a > 1.5 * b (NOTE: b2 must be b/2) +#define significantly_bigger(a, b, b2) ((a > b) && ((a - b) > b2)) + + +// these are used during wheel syncronization +#define TOOTH_WHEEL_NOISE 4 +#define TOOTH_WHEEL_CNT 4 +#define TOOTH_WHEEL_LISTEN (TOOTH_WHEEL_NOISE + TOOTH_WHEEL_CNT) + + +struct multitooth_t { + uint8_t tooth_cnt; // tooth wheel in sync when etime.tooth_cnt < 128. Initial sync sequence is downcounting from 255 + + uint32_t prev_missing_tooth; + uint16_t average_tooth_period; + uint16_t average_tooth_period_prev; +}; + + +struct trigger_t { + uint8_t trigger_phase; + uint8_t previous_trigger_phase; // remember which phase was used to trig from + + uint8_t proposed_trigger_phase[HWMAP_SIZE]; + uint8_t proposed_trig2spark[HWMAP_SIZE]; +}; + +extern struct multitooth_t toothwheel1; +extern struct trigger_t trigger1; + + +#endif + diff -Naur firmware-20041124/my_make firmware-20041127/my_make --- firmware-20041124/my_make 2005-08-03 22:37:16.000000000 +0200 +++ firmware-20041127/my_make 2005-08-03 23:03:36.000000000 +0200 @@ -52,7 +52,7 @@ # MY_CONF += -D DIRECT_IGN # MSTweak3000 is broken, we zero the idle bit (send status & 127) so it does not fall to knees -MY_CONF += -D MS_COMPATIBILITY +#MY_CONF += -D MS_COMPATIBILITY # WBO2 related config: (you need a license to enable it, see Copyright in wbo2.c) # WBO2 support on v2 (with helper circuit) will be gone soon diff -Naur firmware-20041124/timing.c firmware-20041127/timing.c --- firmware-20041124/timing.c 2004-11-19 15:26:27.000000000 +0100 +++ firmware-20041127/timing.c 2005-08-03 23:03:35.000000000 +0200 @@ -20,6 +20,7 @@ #include "edis.h" #include "benchmark.h" #include "timing.h" +#include "multitooth.h" #include #include @@ -139,7 +140,7 @@ #ifdef BENCHMARK benchstats.ocr0cnt++; #endif - ign_deactivate(); // it should not normally have been started though + ign_deactivate(engine.igncount); // it should not normally have been started though #ifdef V3_IGN_DRIVE_A test_ign_turnoff(); #endif @@ -150,7 +151,7 @@ per = (uint16_t)( engine.rpm_period >> DSCL); t32 = mult16_16(per, engine.trig2spark); if(lsr24(t32) >= (16/PDSCL)){ // too much delay, sorry - ign_deactivate(); // it should not normally have been started though + ign_deactivate(engine.igncount); // it should not normally have been started though #ifdef V3_IGN_DRIVE_A test_ign_turnoff(); #endif @@ -159,14 +160,14 @@ // at this low RPM value doing <previous_trigger_phase = t->trigger_phase; + t->trigger_phase = t->proposed_trigger_phase[ic]; +#ifdef TRIG_FROM_LAST_TOOTH + engine.trig2spark = t->proposed_trig2spark[ic]; +#endif } + /* Synhronize engine phase to cam trigger updates engine.status_trig (est) @@ -438,7 +512,7 @@ // currently we examine just bits 23:16 with lsr16() tooth_wheel_trigger = tooth_detection( ((lsr16(period32) == 0) ? (uint16_t) period32 : 0xffff) - , capturedtime); + , capturedtime, &toothwheel1); #ifdef GENBOARDv3 /* @@ -462,18 +536,30 @@ // this condition should be sg. like ifdef DIRECT_IGN (which is true for v3) #ifdef GENBOARDv3 update_engphase(tooth_wheel_trigger); -#endif +#ifdef TRIG_FROM_LAST_TOOTH +#ifdef DEBUG_LAST_TRIG + if (tooth_wheel_trigger & _BV(TW_REGULAR_TRIG)) { + // store when the trigger occured (used in alien capture: self check) + etime.primary_trigger = capturedtime; + } +#endif // debug +#endif // trig +#endif //genboardv3 + PORTG &= ~_BV(CS_FLASH); + +#ifdef TRIG_FROM_LAST_TOOTH + if (simple_trigger || engphase_trig()) { +#else if ((config.primary_trigger & _BV(ptrig_coil)) || (tooth_wheel_trigger & _BV(TW_TRIG))) { +#endif +#ifndef DEBUG_LAST_TRIG etime.primary_trigger = capturedtime; // store when the trigger occured - +#endif #ifdef BENCHMARK benchstats.trig_prim_cnt++; #endif - -#ifdef GENBOARDv3 - cam_trigger_sync(); -#endif + PORTG |= _BV(CS_FLASH); #ifndef NOIGN engine.ignstate = ign_trigger_here((uint16_t)capturedtime); @@ -481,7 +567,12 @@ // 3=>1 particularly // but it's a rare case, doesn't hurt to call always new_event=1; + + // the IGNDEACT has been scheduled, prepare for next + // event, eg. latch /next/ trigger phase and trig2spark + next_engphase_trigger(&trigger1); #endif + engine_is_running(); //turn on fuelpump etc. if (engine.status & _BV(crank)) { // TODO: drop this ?? @@ -1051,7 +1142,7 @@ { // the toothwheel is initially not in sync - etime.tooth_cnt = 255; + init_toothwheel(&toothwheel1); etime.trigcount = config.divider; etime.ase_cyl_count = (config.config11>>4) + 1; diff -Naur firmware-20041124/varstr.h firmware-20041127/varstr.h --- firmware-20041124/varstr.h 2005-08-03 22:37:17.000000000 +0200 +++ firmware-20041127/varstr.h 2005-08-03 23:03:37.000000000 +0200 @@ -167,53 +167,54 @@ char _varname_str_199[] PROGMEM = "cam_sync_r_edge_phase"; char _varname_str_200[] PROGMEM = "cam_sync_f_edge_phase"; char _varname_str_201[] PROGMEM = "reset_engphase_after"; -char _varname_str_202[] PROGMEM = "ign_tdcdelay"; -char _varname_str_203[] PROGMEM = "ign_dwell14"; -char _varname_str_204[] PROGMEM = "ign_dwell6"; -char _varname_str_205[] PROGMEM = "ign_crank_advance"; -char _varname_str_206[] PROGMEM = "ign_out"; -char _varname_str_207[] PROGMEM = "ignchmax"; -char _varname_str_208[] PROGMEM = "engine_off_delay"; -char _varname_str_209[] PROGMEM = "pump_on_mintime"; -char _varname_str_210[] PROGMEM = "fuelpump_channel"; -char _varname_str_211[] PROGMEM = "inj_stage2_rate"; -char _varname_str_212[] PROGMEM = "inj_stage2_start_tps"; -char _varname_str_213[] PROGMEM = "inj_stage2_start_map"; -char _varname_str_214[] PROGMEM = "als_lowrpm"; -char _varname_str_215[] PROGMEM = "als_maxtps"; -char _varname_str_216[] PROGMEM = "als_ignretard"; -char _varname_str_217[] PROGMEM = "als_rich"; -char _varname_str_218[] PROGMEM = "misc1out_minrpm"; -char _varname_str_219[] PROGMEM = "misc1out_maxrpm"; -char _varname_str_220[] PROGMEM = "misc1out_mintps"; -char _varname_str_221[] PROGMEM = "misc1out_maxtps"; -char _varname_str_222[] PROGMEM = "misc1out_minmap"; -char _varname_str_223[] PROGMEM = "misc1out_maxmap"; -char _varname_str_224[] PROGMEM = "misc1out_channel"; -char _varname_str_225[] PROGMEM = "misc2out_minrpm"; -char _varname_str_226[] PROGMEM = "misc2out_maxrpm"; -char _varname_str_227[] PROGMEM = "misc2out_mintps"; -char _varname_str_228[] PROGMEM = "misc2out_maxtps"; -char _varname_str_229[] PROGMEM = "misc2out_minmap"; -char _varname_str_230[] PROGMEM = "misc2out_maxmap"; -char _varname_str_231[] PROGMEM = "misc2out_channel"; -char _varname_str_232[] PROGMEM = "act_wot_rpm"; -char _varname_str_233[] PROGMEM = "act_wot_channel"; -char _varname_str_234[] PROGMEM = "act_rpm_rpm"; -char _varname_str_235[] PROGMEM = "act_rpm_channel"; -char _varname_str_236[] PROGMEM = "egt1_cal"; -char _varname_str_237[] PROGMEM = "egt1_offs"; -char _varname_str_238[] PROGMEM = "boost_conf"; -char _varname_str_239[] PROGMEM = "boost_targetoffs"; -char _varname_str_240[] PROGMEM = "boost_minpressure"; -char _varname_str_241[] PROGMEM = "boost_pid_kp"; -char _varname_str_242[] PROGMEM = "boost_pid_ki"; -char _varname_str_243[] PROGMEM = "boost_pid_kd"; -char _varname_str_244[] PROGMEM = "boost_pid_ilimit"; -char _varname_str_245[] PROGMEM = "boost_channel"; -char _varname_str_246[] PROGMEM = "water_pump_temp"; -char _varname_str_247[] PROGMEM = "water_pump_hyst"; -char _varname_str_248[] PROGMEM = "water_pump_channel"; +char _varname_str_202[] PROGMEM = "engphase_sync"; +char _varname_str_203[] PROGMEM = "ign_tdcdelay"; +char _varname_str_204[] PROGMEM = "ign_dwell14"; +char _varname_str_205[] PROGMEM = "ign_dwell6"; +char _varname_str_206[] PROGMEM = "ign_crank_advance"; +char _varname_str_207[] PROGMEM = "ign_out"; +char _varname_str_208[] PROGMEM = "ignchmax"; +char _varname_str_209[] PROGMEM = "engine_off_delay"; +char _varname_str_210[] PROGMEM = "pump_on_mintime"; +char _varname_str_211[] PROGMEM = "fuelpump_channel"; +char _varname_str_212[] PROGMEM = "inj_stage2_rate"; +char _varname_str_213[] PROGMEM = "inj_stage2_start_tps"; +char _varname_str_214[] PROGMEM = "inj_stage2_start_map"; +char _varname_str_215[] PROGMEM = "als_lowrpm"; +char _varname_str_216[] PROGMEM = "als_maxtps"; +char _varname_str_217[] PROGMEM = "als_ignretard"; +char _varname_str_218[] PROGMEM = "als_rich"; +char _varname_str_219[] PROGMEM = "misc1out_minrpm"; +char _varname_str_220[] PROGMEM = "misc1out_maxrpm"; +char _varname_str_221[] PROGMEM = "misc1out_mintps"; +char _varname_str_222[] PROGMEM = "misc1out_maxtps"; +char _varname_str_223[] PROGMEM = "misc1out_minmap"; +char _varname_str_224[] PROGMEM = "misc1out_maxmap"; +char _varname_str_225[] PROGMEM = "misc1out_channel"; +char _varname_str_226[] PROGMEM = "misc2out_minrpm"; +char _varname_str_227[] PROGMEM = "misc2out_maxrpm"; +char _varname_str_228[] PROGMEM = "misc2out_mintps"; +char _varname_str_229[] PROGMEM = "misc2out_maxtps"; +char _varname_str_230[] PROGMEM = "misc2out_minmap"; +char _varname_str_231[] PROGMEM = "misc2out_maxmap"; +char _varname_str_232[] PROGMEM = "misc2out_channel"; +char _varname_str_233[] PROGMEM = "act_wot_rpm"; +char _varname_str_234[] PROGMEM = "act_wot_channel"; +char _varname_str_235[] PROGMEM = "act_rpm_rpm"; +char _varname_str_236[] PROGMEM = "act_rpm_channel"; +char _varname_str_237[] PROGMEM = "egt1_cal"; +char _varname_str_238[] PROGMEM = "egt1_offs"; +char _varname_str_239[] PROGMEM = "boost_conf"; +char _varname_str_240[] PROGMEM = "boost_targetoffs"; +char _varname_str_241[] PROGMEM = "boost_minpressure"; +char _varname_str_242[] PROGMEM = "boost_pid_kp"; +char _varname_str_243[] PROGMEM = "boost_pid_ki"; +char _varname_str_244[] PROGMEM = "boost_pid_kd"; +char _varname_str_245[] PROGMEM = "boost_pid_ilimit"; +char _varname_str_246[] PROGMEM = "boost_channel"; +char _varname_str_247[] PROGMEM = "water_pump_temp"; +char _varname_str_248[] PROGMEM = "water_pump_hyst"; +char _varname_str_249[] PROGMEM = "water_pump_channel"; PGM_VOID_P varstr[] PROGMEM = { _varname_str_0, @@ -429,5 +430,6 @@ _varname_str_246, _varname_str_247, _varname_str_248, +_varname_str_249, NULL }; diff -Naur firmware-20041124/ve.c firmware-20041127/ve.c --- firmware-20041124/ve.c 2004-11-18 23:41:12.000000000 +0100 +++ firmware-20041127/ve.c 2005-08-03 23:03:35.000000000 +0200 @@ -43,6 +43,7 @@ #include "knock.h" #include "iac.h" #include "boostcontrol.h" +#include "multitooth.h" #include #include @@ -96,6 +97,144 @@ // EDIS return edis_sawlen(); } + +// calculate the time needed for the crank to rotate d/4 degrees +// todo: limits checking (d < 4096) +uint16_t degree2time(uint16_t d) +{ + uint8_t ncyl2; + uint16_t t16; + + // usage: time = engine.rpm_period * degree2time(n) / 4096; + // note: t16 is max 510 (/4 = 127.5 crankdegree). + // the rpm_period depends on ncyl (180 degree for 4 cyl, 90 deg for 8 cyl) + // for 8 cyl t16=360 (90 degree) scales the period with *= 1.0 (return 4096) + // for 4 cyl t16=360 (90 degree) scales the period with *= 0.5 (return 2048) + // reference period value is 0xffff: RPM=57.22 for 8cyl + + // not ncyl, but 2 * ncyl + ncyl2 = ((config.config11 & 0xF0) >> 3) + 2; + // reusing variable: + t16 = mult16_8(d, ncyl2); // max 510 * 15 * 2 + return mult16_8(t16, 182)>>8; +} + +static inline void calc_trigger(uint8_t adv, uint8_t igncount) +{ +/* + precise ignition trigger - the hack way. I want something working + now, then the fine java models can contribute when they are finished :) + + Calculate trigger tooth N, and the time from tooth N to spark 'trig2spark'. + In the multitooth handler, the d(tooth_period) is calculated: + tooth_period{N+1} = 2*tooth_period{N} - tooth_period{N-1}. + + when tooth_period{N+1} is found, the event is scheduled to obtain a + precise firing of the spark. + + Example: + Say trigger tooth is defined (in config) to be 7 teeth BTDC (10 + degrees/tooth), and an advance of 36 degrees is requested. + The trigger tooth will be N=3 and 4 degrees remains. + In the multitooth handler, IGNDEACT is scheduled to + t = k * 4/10 * tooth_period{N+1}, where k is computed in a similar + way as done in trig2spark(). + +*/ + uint8_t trigphase; + uint16_t tdcdelay, degr, t; + + tdcdelay = ((uint16_t)config.ign_tdcdelay)<<1; // going 1/4 crankdeg resolution + + if (adv > tdcdelay) { + // argh, the user configured higher advance than ign_tdcdelay? + // just fire the spark as soon as possible... + degr = 0; + + } else { +#ifdef TRIG_FROM_LAST_TOOTH + if (!(simple_trigger)) { // simple trigger has no use for this + uint8_t toothw, total_adv, phase; + +#define tdc_engphase_map(x) (hwmap.table[HWMAP_SIZE+x]) +#define degrees_per_tooth 10 // this will be moved to config. + + toothw = degrees_per_tooth << 2; // going 1/4 degree resolution + total_adv = 0; + phase = 0; + // start from TDC and backtrack until a suitable trigger tooth is found + while (total_adv < adv) { + total_adv += toothw; + phase += config.tooth_wheel_twidth1; + } + tdcdelay = total_adv; + + trigphase = tdc_engphase_map(igncount); + if (trigphase > phase) { + trigphase -= phase; + } else { + // take care of underflow + uint8_t p; + p = phase - trigphase; + trigphase = config.reset_engphase_after - p; + } +/* + TODO: + if the trigphase is located in the middle of the missing tooth, then + enphase_trig() will never trig. + SOLUTION: + backtrack another tooth. + How do we know this trigphase is in the middle of the missing tooth? +*/ + +// if (trigphase_is_in_missing_tooth) { +// tdcdelay += toothw; +// // again, take care of underflow... +// trigphase -= config.tooth_wheel_twidth1; +// } + } +#endif + degr = tdcdelay - adv; + } + + // here we reuse the old trig2spark behavior... + t = degree2time(degr); + +/* + now the trigger tooth is (from tooth_detection()): + + c_trigger_tooth = config.trigger_tooth + trigtooth; + if (tooth_cnt == c_trigger_tooth + || tooth_cnt == c_trigger_tooth + c_another_trigger_tooth) { + + if (tdcdelay == 0) { + IGNDEACT now; + } else { + schedule IGNDEACT at (now+trig2spark) + // where trig2spark is a function of 'tdcdelay' + } + } + // double buffering of variables are needed. + +*/ + + cli(); + trigger1.proposed_trigger_phase[igncount] = trigphase; + trigger1.proposed_trig2spark[igncount] = t; +#ifndef TRIG_FROM_LAST_TOOTH + engine.trig2spark = t; +#endif + // simple trigger doesn't use the double buffering + if (simple_trigger) { + engine.trig2spark = t; + } + + engine.ignadv = adv; + + sei(); +} + +/* // we get ignition advance and return value for engine.trig2spark scaler // which will be used in trigger.c static inline uint16_t trig2spark(uint8_t adv) @@ -123,27 +262,8 @@ adv16 = mult16_8(t16, ncyl2); // max 510 * 15 * 2 return mult16_8(adv16, 182)>>8; } +*/ -// calculate the time needed for the crank to rotate d/4 degrees -// todo: limits checking (d < 4096) -uint16_t degree2time(uint16_t d) -{ - uint8_t ncyl2; - uint16_t t16; - - // usage: time = engine.rpm_period * degree2time(n) / 4096; - // note: t16 is max 510 (/4 = 127.5 crankdegree). - // the rpm_period depends on ncyl (180 degree for 4 cyl, 90 deg for 8 cyl) - // for 8 cyl t16=360 (90 degree) scales the period with *= 1.0 (return 4096) - // for 4 cyl t16=360 (90 degree) scales the period with *= 0.5 (return 2048) - // reference period value is 0xffff: RPM=57.22 for 8cyl - - // not ncyl, but 2 * ncyl - ncyl2 = ((config.config11 & 0xF0) >> 3) + 2; - // reusing variable: - t16 = mult16_8(d, ncyl2); // max 510 * 15 * 2 - return mult16_8(t16, 182)>>8; -} #endif // NOIGN void search_rpm_kpa_index(void) { @@ -160,7 +280,7 @@ uint16_t w_11, w_12, w_21, w_22; // weights of the 2x2 box uint16_t rpm_weight, kpa_weight, rpm_weight255, kpa_weight255; uint16_t rx21_rl, rx21_kl, dist_rpm, rpm_vhr; - uint8_t ku; + uint8_t ku, igncount; uint16_t t1, t2; if (config.config13 & _BV(CONTROL_STRATEGY)) { //Alpha-N @@ -266,26 +386,13 @@ // engine.ignadv = ku; #ifdef ALS - if (engine.status_ext & _BV(als_active)) // we don't want to knock-knock when we can do BANG-BANG! ;-) + if (engine.status_ext & _BV(als_active)) if (ku <= config.als_ignretard) ku=0; else ku -= config.als_ignretard; - else #endif // ALS -#ifdef KNOCK_8101 - { - t_11 = knock_cyl[engine.igncount].knock_adjust; - if (t_11 >= ku) - ku = 0; - else - ku -= t_11; - - } - -#endif // KNOCK_8101 - ; // needed for close the 'else' #ifdef DANGEROUS_KNOCK_TESTING t1 = ku + engine.ignadv_extra; if (t1 > 0xff) @@ -297,28 +404,37 @@ // apply adjustments from idle control ku = idle_advance_adjust(ku); - // mdp menu command can force a pulsewidth in 64 usec resolution - if (debug.forced_adv) { - ku = debug.forced_adv; - } else if (engine.rpm <= config.cranking_thres) { - ku = config.ign_crank_advance; - } - - t1 = trig2spark(ku); - t2 = calc_dwell(); - // beware of Murphy... - cli(); - engine.ignadv = ku; - engine.trig2spark = t1; - engine.dwell = t2; + // iterate over all igncount + for (igncount = 0; igncount<=config.ignchmax; igncount++) { + uint8_t adv; + adv = ku; #ifdef KNOCK_8101 -// can it be guaranteed that the correct knock_adjust is applied -// in case the main loop is heavily loaded? ve_igncount will tell: - knock_stats.ve_igncount = engine.igncount; // debug -#endif - sei(); + if (!(engine.status_ext & _BV(als_active))) { // we don't want to knock-knock when we can do BANG-BANG! ;-) + t_11 = knock_cyl[igncount].knock_adjust; + + if (t_11 >= adv) + adv = 0; + else + adv -= t_11; + } +#endif // KNOCK_8101 + + // mdp menu command can force a pulsewidth in 64 usec resolution + if (debug.forced_adv) { + adv = debug.forced_adv; + } else if (engine.rpm <= config.cranking_thres) { + adv = config.ign_crank_advance; + } + + calc_trigger(adv, igncount); + } + + t1 = calc_dwell(); + cli(); + engine.dwell = t1; + sei(); #endif // NOIGN diff -Naur firmware-20041124/vems.c firmware-20041127/vems.c --- firmware-20041124/vems.c 2004-11-03 02:48:53.000000000 +0100 +++ firmware-20041127/vems.c 2005-08-03 23:03:35.000000000 +0200 @@ -33,6 +33,7 @@ #include "benchmark.h" #include "wbo2.h" #include "boostcontrol.h" +#include "multitooth.h" #ifdef KEYBOARD #include "keyboard.h"