NefMoto

Technical => Reverse Engineering => Topic started by: TijnCU on October 11, 2016, 09:49:34 AM



Title: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 11, 2016, 09:49:34 AM
I split this thread from my own project thread to have it in the right sub forum. It might be usefull to others!

For some time I have been wanting to use kfzw1 for running more advanced timing maps. I drive on LPG, and map switching ignition is a perfect solution to gain effeciency. Since I use an AEB engine as base, I dont have VVT but the KFZW1 map is there nonetheless. Currently I run a wideband A4 ecu and customized narrowband harness.  
I came up with the idea of hacking the timing routine by replacing fnwue with a new variable that I can control. I will use the rear o2, variable ushk. For my application, just switching between 1 and 2 is enough but I thought this application of the function could be interesting for somebody that wants to do a flexfuel sensor and run E85 while making use of the Bosch designed interpolation between kfzw1 and 2 while fnwue is <1. Both fnwue and ushk are 8bit so controlling the factor with ushk would be as accurate as it is with cam switching.

I'm really stoked about this idea, but maybe it will not work without other modifications to the code. I logged fnwue on my car, and with the engine running it is 0. So to fully understand what I need to do, lets take another look at the code that I have split into 3 sections
Code:
seg010:EE22 sub_9EE22:				;ROUTINE FOR ABSOLUTE KFZW2 INPUT
seg010:EE22                 mov     [-r0], r9
seg010:EE24                 mov     [-r0], r7
seg010:EE26                 mov     [-r0], r6
seg010:EE28                 sub     r0, #2
seg010:EE2A                 extp    #0E1h, #1 ; 'ß'
seg010:EE2E                 movb    rl4, fnwue ;move fnwue to rl4 //replace with ushk to manipulate
seg010:EE32                 cmpb    rl4, #0FFh ;compare byte #0FFh to rl4 //0FFh is the maximum value of a byte.
seg010:EE36                 jmpr    cc_NZ, loc_9EE58 ;if the result is Not Zero, jump to next part of the routine. if the result is Zero, then  
seg010:EE38                 mov     r12, #kfzw2 ;move contents of kfzw2 to r12
seg010:EE3C                 mov     r13, #33A6h
seg010:EE40                 mov     r14, word_380C80
seg010:EE44                 mov     r15, word_380C92
seg010:EE48                 calls   0, sub_78B8
seg010:EE4C                 movb    rl7, rl4
seg010:EE4E                 movb    zwnws, rl4
seg010:EE52                 movb    rl6, #0
seg010:EE54                 jmpa    cc_UC, loc_9EEE6 ;bypass kfzw1 routine
seg010:EE58 ; ---------------------------------------------------------------------------
So, what I can conclude from this code is that fnwue=0 is passed in the ecu as a value of FF.
I think that because if the difference between 0FFh and the value stored in fnwue has to be zero to actually run from the kfzw2 values. So, I need to find out what exact value I am giving to the ecu when I short the lambda2 input.

Next part of the code:
Code:
seg010:EE58
seg010:EE58 loc_9EE58:                               ;ROUTINE FOR ABSOLUTE KFZW1 INPUT
seg010:EE58                 extp    #0E1h, #1 ; 'ß'
seg010:EE5C                 movb    rl4, fnwue ;move byte fnwue to rl4    // change this for ushk as well
seg010:EE60                 jmpr    cc_NZ, loc_9EE80 ;jump to interpolation part of routine if the conditionflag Not Zero is set
seg010:EE62                 mov     r12, #kfzw1 ;move contents of kfzw1 to r12
seg010:EE66                 mov     r13, #33A6h
seg010:EE6A                 mov     r14, word_380C80
seg010:EE6E                 mov     r15, word_380C92
seg010:EE72                 calls   0, sub_78B8
seg010:EE76                 movb    rl6, rl4
seg010:EE78                 movb    zwnws, rl4
seg010:EE7C                 movb    rl7, #0
seg010:EE7E                 jmpr    cc_UC, loc_9EEE6 ;bypass interpolation routine
seg010:EE80 ; ---------------------------------------------------------------------------
Now, if I understand this part correctly it means that when the byte of fnwue is at a value of 0, the conditionflag 'Not Zero' will  not be set, and the content of kfzw1 is loaded into the registry. If there is any other value than 0 in fnwue, the routine jumps to the final section of code:

Code:
seg010:EE80
seg010:EE80 loc_9EE80:                               ;ROUTINE FOR INTERPOLATION KFZW2+KFZW1
seg010:EE80                 mov     r12, #kfzw2
seg010:EE84                 mov     r13, #33A6h
seg010:EE88                 mov     r14, word_380C80
seg010:EE8C                 mov     r15, word_380C92
seg010:EE90                 calls   0, sub_78B8
seg010:EE94                 extp    #0E1h, #1 ; 'ß'
seg010:EE98                 movbz   r5, fnwue
seg010:EE9C                 mul     r4, r5
seg010:EE9E                 mov     r4, word_FE0E
seg010:EEA2                 mov     [r0], r4
seg010:EEA4                 movb    rl7, [r0+1]
seg010:EEA8                 mov     r12, #kfzw1
seg010:EEAC                 mov     r13, #33A6h
seg010:EEB0                 mov     r14, word_380C80
seg010:EEB4                 mov     r15, word_380C92
seg010:EEB8                 calls   0, sub_78B8
seg010:EEBC                 extp    #0E1h, #1 ; 'ß'
seg010:EEC0                 movbz   r5, fnwue
seg010:EEC4                 mov     r2, #100h
seg010:EEC8                 sub     r2, r5
seg010:EECA                 mul     r4, r2
seg010:EECC                 mov     r4, word_FE0E
seg010:EED0                 mov     [r0], r4
seg010:EED2                 movb    rl6, [r0+1]
seg010:EED6                 movb    rl4, rl6
seg010:EED8                 addb    rl4, rl7
seg010:EEDA                 jmpr    cc_NV, loc_9EEE2
seg010:EEDC                 movb    rl4, #7Fh ; ''
seg010:EEE0                 addcb   rl4, #0

This is the part where from my understanding the interpolation and multiplication is done from the factor in fnwue.

To hack the code and force kfzw1 I think I have 2 options:
Find out what values my ushk gives when open and when shorted, if the shorted ushk gives a byte of 0 or 255 it follows the code and runs from either kfzw1 or kfzw2. The catch is that ushk must not give any other value than 255 or 0 or else it will go into interpolation mode.
If the open or shorted ushk does not give 0, maybe I just make it jump to loc_9EE62 so it completes this part of the routine anyway. It will then run from kfzw1 and skip the interpolation part. The only problem in this situation is that I still need the 255 value or I will disable kfzw2.
 
Lets find out!  ;D Any comments or tips are welcome, I really suck at asm.

I logged the variable ushk without any conversion, and it gives a value of 125 when its open and 38 when it is shorted to the output pin. I assume that these are the actual byte values. So either I need to change the ushk conversion, or just compare to 07Dh in code section #1 and change the jump in section #2. I´ll try to compile something and test it tonight  :o  


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nubcake on October 11, 2016, 10:40:54 AM
What you're trying to achieve is pretty easy.
The "third" section is there to "blend" two maps together when the cams are in the process of switching. And two first ones are to save CPU time and avoid extra math when cams are in extreme positions.

There are multiple ways to approach this. I'd probably use one of the "filtering" functions and have smooth transition between maps, but that's fairly complicated for someone not familiar with asm.
If you just want "binary" action - just replace the "movb rl4, fnwue" with "movb rl4, ushk" and alter the comparison/jump conditions. Should be rather easy.

EDIT: check C166 instruction set manual for condition codes.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 11, 2016, 10:46:16 AM
yes, I did this "binary" coding with a little help of the C166ism and flashed it to my spare ecu. I just need to test if it works when the engine is running because on the bench I cannot see any difference if I short the rear o2 in/out. I put NOP instead of the #2 jump condition at EE60.

This hacking is a good beginner solution because I can make use of the existing code. It gives me a better understanding how to do this kind of stuff  :)


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nyet on October 11, 2016, 11:46:13 AM
This hacking is a good beginner solution because I can make use of the existing code. It gives me a better understanding how to do this kind of stuff  :)

I really like this approach. Learn from something simple, so you can try more complicated things once you've figured the simple thing out.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 12, 2016, 05:03:05 AM
I have made slight modifications to the code to ensure proper switching (changed the condition at adress EE58 to cc_ULE #070h, since the input reads either around 125 or 38 decimal).
The thing that bothers me, is that ushk is now also used as a factor and it doesnt give out the right values. I think I localized the part where ushk gets its value, but I have not succeeded in changing the values so that it will give both 00 and FF. Here is a small part of the DHLSHK routine:

*** I'm an idiot! sorry. Just after posting I thought, hey, I have a ram logger.... edited code below
Code:
DHLSHK:
seg006:0572
seg006:0572 loc_50572:                              ; CODE XREF: DHLSHK+1AAj
seg006:0572                                         ; DHLSHK+1AEj
seg006:0572                 mov     r4, word_381B1A
seg006:0576                 cmp     r4, #1B4h ;change to cmp r4, #032h (built in margin for possible fluctuations of the variable, its not super stable)
seg006:057A                 jmpr    cc_ULE, loc_50582           ;this condition is met when pin68 is open, so ushk will be set with 0 in the next part
seg006:057C                 movb    ushk, ONES
seg006:0580                 jmpr    cc_UC, loc_505A6
seg006:0582 ; ---------------------------------------------------------------------------
seg006:0582
seg006:0582 loc_50582:                              ; CODE XREF: DHLSHK+1BAj
seg006:0582                 mov     r4, word_381B1A      
seg006:0586                 cmp     r4, #0A4h                
seg006:058A                 jmpr    cc_NC, loc_50592      ; change to nop, ushk will be set to 0
seg006:058C                 movb    ushk, ZEROS
seg006:0590                 jmpr    cc_UC, loc_505A6
seg006:0592 ; ---------------------------------------------------------------------------
seg006:0592
seg006:0592 loc_50592:                              ; this part of the code will now always be skipped
seg006:0592                 mov     r4, word_381B1A
seg006:0596                 mov     r5, r4
seg006:0598                 shl     r5, #4
seg006:059A                 sub     r5, r4
seg006:059C                 sub     r5, #99Ch
seg006:05A0                 shr     r5, #4
seg006:05A2                 movb    ushk, rl5
seg006:05A6
I think that word_381B1A is the actual voltage input or output on the c166. #1B4h translates into 436 decimal and that is exactly the reading that I get when I measure the output pin 69 on the ecu (436mV). Coincidence?  After this, ushk receives either zero's or ones, which I understand to be the actual lambda monitoring (high or low). If the first 2 conditions are not met, it ends up in the last part where all sorts of magic happens with shifting bytes and stuff ;D. I have verified that this currently gives the final output of ushk, because when I swapped the last
Code:
movb  ushk,rl5
with
Code:
movb  ushk,ONES
I got a value of 255 from logging ushk.

The switching code is still untested, if my wife gets home before dark I'll wire the test ecu in.

Logging word_381B1A gives a raw value of 42 when pin68 open, and 205 when shorted to 69. So I'll test if I can do something with these values in the jumping conditions... - added above.

Still does not give out the desired/expected values on ushk. I'll try this:
Code:
mov  ushk, #0FFh 
and
mov  ushk, #000h


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: vwaudiguy on October 12, 2016, 08:54:25 AM
if my wife gets home before dark I'll wire the test ecu in.

Sorry, but I thought this was funny.

Also, flashlight?  ;D

Also, great job!  :)



Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 12, 2016, 09:17:11 AM
Haha well obviously I'm not allowed to go out tuning after sundown anymore..
I once loaded an untested flash in the car and let the wife test drive it to work the next morning at 06.15. After she woke the whole neighbourhood with a backfiring engine she made me swap the ecu on the street in my underwear  ???
Flashlight is a good idea though ;)

ok back on topic  ;D ECU harness wiring is done and I worked on the code a bit more.
This is the asm code that I came up with to replace the function (and hex code behind it)
Code:
seg006:0572                 mov     r4, word_381B1A					F2 F4 1A 9B
seg006:0576                 cmp     r4, #032h 46 F4 32 00
seg006:057A                 jmpr    cc_ULE, loc_50586 FD 05
seg006:057C        mov b    rl5, #0FFh E7 FA FF 00
seg006:0580                 movb    ushk, rl5 F7 FA 73 89
seg006:0584       jpmr   cc_UC, loc_505A6        0D 0A
 ; ---------------------------------------------------------------------------
seg006:0586       movb    rl5, #000h        E7 FA 00 00
seg006:058A       movb    ushk, rl5        F7 FA 73 89
seg006:058E       jmpr     cc_UC, loc 505A6 0D 0D
; --------------------------------------------
seg006:05A6
I hope I did the counting correctly for the relative jumps, I looked how it was arranged in the code and try use the same approach. Its as clean as I think I can make it with my skills.

** aaaaaand I bricked it  ;D Back to the drawing board.
I messed up with my cool ASCII code, I accidentally put it on line 058A  :-X woops. Also the relative jumps where a bit off..
Honestly I dont fully understand how the relative jumps are calculated in this processor, it seemed to me in the original code 2 bytes were equal to 1 jump (03 skips 6 bytes eg. FF FF FF AA AA AA). Could be messing up if this is wrong...
see attached image #2 for final code


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 12, 2016, 02:23:35 PM
I have succesfully hacked ushk! It worked after I flashed the corrections in the code I made in the previous post, but now the variable ushk only gave 255 (meaning the second part of the code gets skipped). The problem was that word_381B1A is 16bit. I logged it with the adjusted *ecu file and it gave 298 as the open value and 205 when I shorted the pins. So after I corrected the jump condition from #032h to #0FFh, it works!
Logger result screenshot attached  ;D

The beauty of this detour is now that I could repair the fnwue routine to its original except 4 bytes (fnwue=ushk).  Ecu still runs after 5 key cycles, do I need to worry about later unexpected checksum errors or is this coding all outside of checksum areas? I exported the final map with winols so checksums should be good...


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nubcake on October 12, 2016, 04:12:04 PM
2 bytes were equal to 1 jump (03 skips 6 bytes eg. FF FF FF AA AA AA).

This.

The problem was that word_381B1A is 16bit

That's why it's a word, not a byte. :)

Ecu still runs after 5 key cycles, do I need to worry about later unexpected checksum errors or is this coding all outside of checksum areas? I exported the final map with winols so checksums should be good...

I always double-check with me7check. Takes 5 seconds anyways.

EDIT:
Also, as a word of advice: avoid patching the "input" to existing vars like that. You could miss a write reference or two - and your code (relying on them being in specific condition) might go haywire on you at random moment of time. Besides, there could be numerous other functions that interact with said var - and they will also go nuts if they see something unexpected. I'd say you should rather patch ZWGRU like you planned initially, it's a much "cleaner" approach - you patch only what you plan to use. Change the "fnwue" reference and a couple of compare/jump conditions - it's even easier than messing with the ushk.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 13, 2016, 12:37:27 AM
Haha, duhhh. I actually knew the difference between words and bytes but in the focus on the code I totally forgot to apply anything I had learned. Total beginner  ;D

I appreciate your feedback on my approach! Sometimes when I get caught up in my work I cant really think of alternatives.

I understand that it is more work to check all references to ushk than only hacking the ZWGRU routine. My idea was (and maybe this was a false assumption) that I dont use the rear o2 anyway (its coded out) and I need no further functionality from it. I will reassess my ushk hack and doublecheck all xrefs.

I do recall a topic about logging wideband on the rear o2 input that set off all kind of fuel trims in ME7.1 so your warning might directly apply on my case. If I find any xref to ushk that leads to another function I'll redo the work. I suspect that word_381B1A1 is used for functionality beyond ushk (word_381B1A1 is the input to ushk and is not altered), but its good to check again. Even the shorting of the pins could lead to errors in other functions since that does affect the output of word_381B1A1.

It was more my fear about what would happen with my input in rl4 in the ZWGRU part, since beyond the switching that # remains in the register. That was why I would rather alter the function I (thought I) didnt use and put a logic value in the function that I do use.
Maybe this is completely paranoia though  ;D Thanks again for your feedback  :)


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nubcake on October 13, 2016, 02:36:40 AM
It was more my fear about what would happen with my input in rl4 in the ZWGRU part, since beond the switching that # remains in the register.

Check the code "downstream" of that write to confirm that it's not used. It usually is overwritten very soon with something else, but never hurts to confirm yourself.
In that particular case you just need to mod the first comparison condition and "nop" out the second one to completely bypass the "map blending" part.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 13, 2016, 03:36:12 AM
I just tested both versions (with ushk mod and with only the zwgru changes) but the car wont run properly on either of the flashes, no matter if the rear o2 pins are shorted or not. So there is probably something I missed. I'll dive back into the asm and find out what is going on  :P

* Might be that the ecu still tries to interpolate with kfzw1 (that I set to 0 over the whole map to test) while I expected it to run off kfzw2 entirely. The variable zwgru was constantly at or around 0 in the logger. If I can get it to run good when I clone the kfzw maps, I maybe just need to disable the interpolation routine.

complete original subroutine below
Code:
seg010:EE22 ; =============== S U B R O U T I N E =======================================
seg010:EE22
seg010:EE22
seg010:EE22
seg010:EE22 sub_9EE22:
seg010:EE22                 mov     [-r0], r9
seg010:EE24                 mov     [-r0], r7
seg010:EE26                 mov     [-r0], r6
seg010:EE28                 sub     r0, #2
seg010:EE2A                 extp    #0E1h, #1 ; 'ß'
seg010:EE2E                 movb    rl4, fnwue
seg010:EE32                 cmpb    rl4, #0FFh
seg010:EE36                 jmpr    cc_NZ, loc_9EE58
seg010:EE38                 mov     r12, #kfzw2
seg010:EE3C                 mov     r13, #33A6h
seg010:EE40                 mov     r14, word_380C80
seg010:EE44                 mov     r15, word_380C92
seg010:EE48                 calls   0, sub_78B8
seg010:EE4C                 movb    rl7, rl4
seg010:EE4E                 movb    zwnws, rl4
seg010:EE52                 movb    rl6, #0
seg010:EE54                 jmpa    cc_UC, loc_9EEE6
seg010:EE58 ; ---------------------------------------------------------------------------
seg010:EE58
seg010:EE58 loc_9EE58:                              ; CODE XREF: sub_9EE22+14j
seg010:EE58                 extp    #0E1h, #1 ; 'ß'
seg010:EE5C                 movb    rl4, fnwue
seg010:EE60                 jmpr    cc_NZ, loc_9EE80
seg010:EE62                 mov     r12, #kfzw1
seg010:EE66                 mov     r13, #33A6h
seg010:EE6A                 mov     r14, word_380C80
seg010:EE6E                 mov     r15, word_380C92
seg010:EE72                 calls   0, sub_78B8
seg010:EE76                 movb    rl6, rl4
seg010:EE78                 movb    zwnws, rl4
seg010:EE7C                 movb    rl7, #0
seg010:EE7E                 jmpr    cc_UC, loc_9EEE6
seg010:EE80 ; ---------------------------------------------------------------------------
seg010:EE80
seg010:EE80 loc_9EE80:                              ; CODE XREF: sub_9EE22+3Ej
seg010:EE80                 mov     r12, #kfzw2
seg010:EE84                 mov     r13, #33A6h
seg010:EE88                 mov     r14, word_380C80
seg010:EE8C                 mov     r15, word_380C92
seg010:EE90                 calls   0, sub_78B8
seg010:EE94                 extp    #0E1h, #1 ; 'ß'
seg010:EE98                 movbz   r5, fnwue
seg010:EE9C                 mul     r4, r5
seg010:EE9E                 mov     r4, word_FE0E
seg010:EEA2                 mov     [r0], r4
seg010:EEA4                 movb    rl7, [r0+1]
seg010:EEA8                 mov     r12, #kfzw1
seg010:EEAC                 mov     r13, #33A6h
seg010:EEB0                 mov     r14, word_380C80
seg010:EEB4                 mov     r15, word_380C92
seg010:EEB8                 calls   0, sub_78B8
seg010:EEBC                 extp    #0E1h, #1 ; 'ß'
seg010:EEC0                 movbz   r5, fnwue
seg010:EEC4                 mov     r2, #100h
seg010:EEC8                 sub     r2, r5
seg010:EECA                 mul     r4, r2
seg010:EECC                 mov     r4, word_FE0E
seg010:EED0                 mov     [r0], r4
seg010:EED2                 movb    rl6, [r0+1]
seg010:EED6                 movb    rl4, rl6
seg010:EED8                 addb    rl4, rl7
seg010:EEDA                 jmpr    cc_NV, loc_9EEE2
seg010:EEDC                 movb    rl4, #7Fh ; ''
seg010:EEE0                 addcb   rl4, #0
seg010:EEE2
seg010:EEE2 loc_9EEE2:                              ; CODE XREF: sub_9EE22+B8j
seg010:EEE2                 movb    zwnws, rl4
seg010:EEE6
seg010:EEE6 loc_9EEE6:                              ; CODE XREF: sub_9EE22+32j
seg010:EEE6                                         ; sub_9EE22+5Cj
seg010:EEE6                 movbs   r9, rl6
seg010:EEE8                 movbs   r4, rl7
seg010:EEEA                 add     r9, r4
seg010:EEEC                 movbs   r4, byte_380AED
seg010:EEF0                 add     r9, r4
seg010:EEF2                 movbs   r4, byte_380AEE
seg010:EEF6                 add     r9, r4
seg010:EEF8                 movbs   r4, byte_380B8A
seg010:EEFC                 add     r9, r4
seg010:EEFE                 cmp     r9, #7Fh ; ''
seg010:EF02                 jmpr    cc_SLT, loc_9EF0E
seg010:EF04                 movb    rl4, #7Fh ; ''
seg010:EF08                 movb    zwgru, rl4
seg010:EF0C                 jmpr    cc_UC, loc_9EF24
seg010:EF0E ; ---------------------------------------------------------------------------
seg010:EF0E
seg010:EF0E loc_9EF0E:                              ; CODE XREF: sub_9EE22+E0j
seg010:EF0E                 cmp     r9, #0FF80h
seg010:EF12                 jmpr    cc_SGE, loc_9EF1E
seg010:EF14                 movb    rl4, #80h ; 'Ç'
seg010:EF18                 movb    zwgru, rl4
seg010:EF1C                 jmpr    cc_UC, loc_9EF24
seg010:EF1E ; ---------------------------------------------------------------------------
seg010:EF1E
seg010:EF1E loc_9EF1E:                              ; CODE XREF: sub_9EE22+F0j
seg010:EF1E                 mov     r4, r9
seg010:EF20                 movb    zwgru, rl4
seg010:EF24
seg010:EF24 loc_9EF24:                              ; CODE XREF: sub_9EE22+EAj
seg010:EF24                                         ; sub_9EE22+FAj
seg010:EF24                 add     r0, #2
seg010:EF26                 mov     r6, [r0+]
seg010:EF28                 mov     r7, [r0+]
seg010:EF2A                 mov     r9, [r0+]
seg010:EF2C                 rets
seg010:EF2C ; End of function sub_9EE22


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 18, 2016, 03:57:44 AM
I've let this rest for a couple of days, but yesterday I wanted to get the function to work. I started from scratch, and I took nubcake's advice at heart so the function now only uses unmodified existing variables. fnwue is not being used in the equation in the first 2 map selection sections and r(l)4 gets overwritten with the contents of kfzw in the subroutine that gets called.
The big issue is that I cannot get the function to switch  :-\ I can hardcode kfzw1 or 2, and to verify I have nop'd the interpolation part of the routine as well but I have not yet succeeded in making the first jump dynamic based on my input.
word_381B1A1 represents ~012A (298) when untriggered and ~00CD (205) when triggered
I'm currently re-reading all of the flags that can be set in different situations to find out what I need to do to keep it compact and functional.

I have tried various cmp and cmpb variations from both word_381B1A1 or ushk (8bit) but it looks like it never makes the jump unless I make the jump unconditional. I cant get my head wrapped around why it will not become dynamic. sigh... this easy map switching is still damn hard for a beginner in asm  :(

To me it seems that
Code:
mov r3, word_381b1a
cmp r3, #0FFh
will set the V(underflow) flag when word_381b1a<FF, right? I cant do any Z flags because the variable is not completely stable.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: prj on October 18, 2016, 05:50:08 AM
Much easier - substitute R12 write before map lookup with a call to this (obviously edit the variable addresses):

;Constants
failsafe_status         EQU 0x0F26 + 0x8000 ;B1S2 ADC
voltage_threshold         EQU 0x200 ; 2.5 volts
;0x811F71
kfzw_norm_start_addr      EQU   #0x1EB1
;0x8171E6
kfzw_meth_start_addr      EQU   #0x71E6

switch_kfzw proc far
MOV R12, failsafe_status
CMP R12, #voltage_threshold
JMPR cc_c, not_ok2
MOV R12, #kfzw_meth_start_addr
RETS
not_ok2:
MOV R12, #kfzw_norm_start_addr
RETS
switch_kfzw endp



Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 18, 2016, 06:11:07 AM
Thanks for your contribution prj, I see this is clearly the best approach to switch both kfzw maps for substitutes when you have the variable cam in place. I thought I found a shortcut (and in theory it should work ???) to do without a call to a new subroutine when you have a fixed cam, but I'll do this when the last attempt fails too. Its still nice that I have messed with the code because I learned new stuff  ;D
Btw, do you use the o2 signal in/out of the ecu or the heater pins? I found that the ecu reboots when I put another voltage on the o2 input...


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nubcake on October 18, 2016, 07:30:51 AM
To me it seems that
Code:
mov r3, word_381b1a
cmp r3, #0FFh
will set the V(underflow) flag when word_381b1a<FF, right?

Try using the carry (cc_C) flag.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: prj on October 18, 2016, 07:38:38 AM
Thanks for your contribution prj, I see this is clearly the best approach to switch both kfzw maps for substitutes when you have the variable cam in place. I thought I found a shortcut (and in theory it should work ???) to do without a call to a new subroutine when you have a fixed cam, but I'll do this when the last attempt fails too. Its still nice that I have messed with the code because I learned new stuff  ;D
Btw, do you use the o2 signal in/out of the ecu or the heater pins? I found that the ecu reboots when I put another voltage on the o2 input...
If your ECU reboots you have errors in the code. I've always used rear o2 for map switch... never ever had any issues with it.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 18, 2016, 07:48:14 AM
Could be I am running in circles because I am trying this on the bench... but if I use cc_V I start with zwnws=kfzw2 and if I use cc_C it starts with zwnws=kfzw1. But neither will switch. I am going to code in the new subroutine now to verify this :)

prj, I tested that pin without code modifications. Maybe there is a built in safety for overvoltage, but I assumed I'd better not short pins that cause the ecu to reboot. Then I found shorting the in/out pin worked without reboots.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nubcake on October 18, 2016, 08:33:24 AM
Could be I am running in circles because I am trying this on the bench...

You most likely are. :)
That code is not executed until the ignition is on at the very least.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 18, 2016, 08:40:27 AM
But still its weird that the map does not change while the variables that set the kfzw map in my code do change? I mean it should still select the input regardless of engine running because it follows the code... If it had a startup setting I would not be able to force one of the maps to read in the first place (at least that was my attempt to verify if I could actually change this). I put super odd values in kfzw2 and kfzw1 to verify and I get exactly that output in zwnws when I log it....

I wrote the following code, hex is included to visualize the differences in operands:
Code:
calls (DA) #81h (81), 8100 (00 81) ; calls sub_818100

sub_818100
<unswitched>
mov (F2) r12 (FC), word_381B1A (1A 9B)    
cmp (46) r12 (FC), #03E8h (E8 03)  <threshold 10v
cc_C (8D) <switched> (03)
mov (E6) r12 (FC), #kfzw1 (90 23)
rets (DB)

<switched>
mov (E6) r12 (FC), #kfzw2 (50 24)
rets (DB)


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 18, 2016, 11:20:36 AM
It works! I placed a nop at the first original jump and inserted the new code at (8)18100. I can now switch on the bench. Only funny thing I see is when switched to kfzw2 sometimes it jumps from -3 to 1.5 degree but maybe that is due to interpolation inside of the kfzw2 field combined with unstable power supply or something. Who cares, first asm victory  ;D

Tomorrow I will test this in the car, I have removed the nops and only replaced the 2 kfzw2 adresses with the call to the new routine. I think I get a bit funky results because on the bench fnwue is not 1 (0.8 something) but while the engine is running it is always 1 with a non vvt camshaft.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 21, 2016, 02:06:20 AM
Funny spikes in the csv are from logging at 50hz it seems. On 20hz I can not see any strange fluctuations in the ignition output.
I have tested my ecu in the car this morning, but it still will not run good. Idle is fine, but as soon as I touch the pedal it almost stalls and has a hard time to get back to a stable rpm. Ignition is all over the place, I logged and found that fnwue is swinging around 0.1-0.9 badly ??? I need to do another baseline log with the original file to doublecheck how it behaves, but from what I remember it was steady at 1 before. Super weird, I did not alter the fnwue function in this file. I could hardcode fnwue to 1 in this routine, but I'd rather understand why it fluctuates while my cam is fixed.

I verified that the ecu is okay, on the normal tune it runs without problems.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: prj on October 21, 2016, 03:31:54 AM
Why not just use my code...


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 21, 2016, 04:25:18 AM
It basically is, just edited it to suit my ecu.. The switch itself works perfectly on the bench so the code is functional.

I have removed the nops and only replaced the 2 kfzw2 adresses with the call to the new routine.

This is the call at the kfzw2 lookup adress
calls #81h, 8100

and this is the subroutine that you posted, only with my adresses and input.
sub_818100
<pins open>
mov r12, word_381B1A    
cmp r12, #0FFh
cc_C <pins shorted>
mov r12, #kfzw1
rets

<pins shorted>
mov r12, #kfzw2
rets

AHA! The flash is fd up. I just tested the base version where I put the code in and it behaves exactly the same. I think because I did a revision to get rid of my rough road controller fault code I must have set a wrong bit somewhere... It behaves exactly the same (going nuts as soon as I touch the pedal). I test my old version with new code now..

Yup, now it works  :o damn, I have lost so much time on this stupid troubleshooting, but its my own fault (thinking that setting 2 ASR CAN configs to 00 could not possibly be the cause...). Learn from my mistake, readers! :-*
I'll first get to work on calibrating the kfzw maps and then maybe test my own idea later on for people that don't want to get into asm.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on October 22, 2016, 02:44:56 AM
I've just tested my rear o2 output on the bench again, and I have made a mistake when I configured this. I was manipulating pin 68 (Ro2 INPUT) while the variable that I use is actually pin 69 (Ro2 OUTPUT). That one directly correlates to the voltage that is fed. In my head I had to do something with the input wire to manipulate the ecu, so my plan was to short the 2 pins with a 12v powered relay (my automatic switch trigger is 12v) but now I see that I can just feed the 12v in pin 69 and it will read 1228 raw on the bench (12.28v).
So just a little change in the subroutine and I can remove 1 wire from the ecu connector again  ;D

I want to thank nubcake and prj that have been helping me with this asm starting adventure, and I will soon try to make a "patch" version for anybody that only wants to make changes in the hex binary like I initially was planning to. I'll update the opening post when I do so.
Next adventure is writing code for the SAI 12v output to trigger my soon-to-be exhaust cutout ;D

There is also another thing that I would like to do, I want to write code that adds or subtracts a value to or from zwgru with the clutch, set and reset button of the cruisecontrol (maybe with a max of #Ah, that value needs to be stored in RAM obviously) to make a quick tool for realtime correcting timing for MBT on the dyno. When you are logging load and rpm its easy to make notes about how much timing is added or subtracted and you dont need to reflash all the time. Need to figure out a couple of things before I get started on that. The result is basically a lemmiwinks function but without cycling the ignition.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: Tim on October 22, 2016, 07:41:51 AM
There is also another thing that I would like to do, I want to write code that adds or subtracts a value to or from zwgru with the clutch, set and reset button of the cruisecontrol (maybe with a max of #Ah, that value needs to be stored in RAM obviously) to make a quick tool for realtime correcting timing for MBT on the dyno. When you are logging load and rpm its easy to make notes about how much timing is added or subtracted and you dont need to reflash all the time. Need to figure out a couple of things before I get started on that. The result is basically a lemmiwinks function but without cycling the ignition.

Great work TijnCU, thanks for sharing your work as its progressed.
Interesting stuff about realtime correction, I've been having a look at that myself on EDC15 changing SOI, pilot and main etc. without going down the whole checksum delete or countless reflashings.
If it's anything similar it may be possible to use the existing ASCET-Bypass hooks in the functions and change the RAM variables to suit.
Maybe it could be of help to you


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: nubcake on October 22, 2016, 09:24:04 AM
There is also another thing that I would like to do, I want to write code that adds or subtracts a value to or from zwgru with the clutch, set and reset button of the cruisecontrol (maybe with a max of #Ah, that value needs to be stored in RAM obviously) to make a quick tool for realtime correcting timing for MBT on the dyno. When you are logging load and rpm its easy to make notes about how much timing is added or subtracted and you dont need to reflash all the time. Need to figure out a couple of things before I get started on that. The result is basically a lemmiwinks function but without cycling the ignition.

dzwoag and dzwkg are sometimes not used (maps for them are flat), but the code is there anyways. You could use that code (modify input to said maps or something like that). Just a pointer. :)


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on November 01, 2016, 01:04:00 PM
Thanks for the suggestions, I'll look into it!
Here is my result from the auto-mapswitching in daily driving:
Acceleration on petrol (1) and lpg (2)
(http://i284.photobucket.com/albums/ll32/tijnvanesch/engine%20conversion/log1_zpsu5gwoopg.jpg) (http://s284.photobucket.com/user/tijnvanesch/media/engine%20conversion/log1_zpsu5gwoopg.jpg.html)
On the cruisecontrol switching from lpg to petrol to lpg.
(http://i284.photobucket.com/albums/ll32/tijnvanesch/engine%20conversion/log2_zpslcnkkely.jpg) (http://s284.photobucket.com/user/tijnvanesch/media/engine%20conversion/log2_zpslcnkkely.jpg.html)
Very happy with the result  :) Now its time for adding more timing on lpg under load! (was always very conservative to ensure no excessive retard when driving on petrol in case of lpg failure or empty tank)


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: prj on November 02, 2016, 12:57:40 AM
You will find that you will be able to add 6+ degrees.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on November 02, 2016, 01:10:13 AM
Yes, I expect somewhere between 5 and 8 degrees. How is your experience with lpg timing above 4000rpm? From the research I have done it seems that the flamespeed relatively increases with higher rpm causing the mixture to need less timing at higher rpm (about the same as petrol or even a bit less). Haven't done real world testing with this since my engine currently doesn't make any power at high rpm anyways :P
Quote
The Variations of brake thermal efficiency for gasoline and LPG fuels at WOT operating condition is
shown in Figure 6. The characteristics of these curves shows that the brake thermal efficiency is more for
gasoline at lower speeds and in the speed range of 3000 RPM to 4000 RPM both fuels have nearly same
efficiencies. LPG combustion exhibits higher thermal efficiency than gasoline after 3500 RPM. Since the
ignition temperature of LPG is higher than that of gasoline, ignition delay and thus combustion duration
is more for LPG [1]. This decreases the average burning rate. To accommodate this effect, engine
consumes more fuel which in turn decreases its efficiency. Hence LPG has lower efficiency at lower
engine speeds. At higher engine speeds, the higher flame propagation speed of LPG negates the effect of
ignition temperature. Here the time duration for each cycle is very low which demands more rate of
combustion to get the complete combustion of the fuel. The lower propagation speeds of gasoline flames
cannot afford the requisite combustion rate; instead the engine takes more fuel to generate the required
torque. The collective outcome of these factors lowers brake thermal efficiency of the engine for gasoline
at higher engine speeds
(http://i284.photobucket.com/albums/ll32/tijnvanesch/BTE_zpso7dhdn2o.png)


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: prj on November 02, 2016, 04:36:39 AM
Add timing until it knocks, LPG has higher octane so add lots.


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on December 03, 2016, 01:12:25 PM
Here is my current code, maybe someone likes some inspiration.
I relocated the function and maps since I needed more space. After moving the code I realized I needed the extp command when calling from different sections of code  :)

Code:
	;krkte1
extp #0E1h, #1 ;D7 40 E1 00
mov r5, word_381B1A ;F2 F5 1A 9B
cmp r5, #1C2h ;46 F5 C2 01
jmpr cc_c switched ;8D 05
extp #207h, #1 ;D7 40 07 02
mov r5, #0D80h ;F2 F5 80 0D
rets ;DB 00
;switched
extp #229h, #1 ;D7 40 29 02
mov r5, #0DC4h ;F2 F5 C4 0D
rets ;DB 00

;krkte2
extp #0E1h, #1 ;D7 40 E1 00
mov r4, word_381B1A ;F2 F4 1A 9B
cmp r4, #1C2h ;46 F4 C2 01
jmpr cc_c switched ;8D 05
extp #207h, #1 ;D7 40 07 02
mov r4, #0D80h ;F2 F4 80 0D
rets ;DB 00
;switched
extp #229h, #1 ;D7 40 29 02
mov r4, #0DC4h ;F2 F4 C4 0D
rets ;DB 00

;krkte3
extp #0E1h, #1 ;D7 40 E1 00
mov r2, word_381B1A ;F2 F2 1A 9B
cmp r2, #1C2h ;46 F2 C2 01
jmpr cc_c switched ;8D 05
extp #207h, #1 ;D7 40 07 02
mov r2, #0D80h ;F2 F2 80 0D
rets ;DB 00
;switched
extp #229h, #1 ;D7 40 29 02
mov r2, #0DC4h ;F2 F2 C4 0D
rets ;DB 00

;fkkvs
extp #0E1h, #1 ;D7 40 E1 00
mov r5, word_381B1A ;F2 F5 1A 9B
cmp r5, #1C2h ;46 F5 C2 01
jmpr cc_c switched ;8D 03
mov r5, #207h ;E6 F5 07 02
rets ;DB 00
;switched
mov r4, #0B32h ;E6 F4 32 0B
mov r5, #229h ;E6 F5 29 02
rets ;DB 00

;kflbts
extp #0E1h, #1 ;D7 40 E1 00
mov r13, word_81B1A ;F2 FD 1A 9B
cmp r13, #1C2h ;46 FD C2 01
jmpr cc_c switched ;8D 03
mov r13, #206h ;E6 FD 06 02
rets ;DB 00
;switched
mov r12, #0B00h ;E6 FC 00 0B
mov r13, #229h ;E6 FD 29 02
rets ;DB 00

;kfzw1
extp #0E1h, #1 ;D7 40 E1 00
mov r12, word_81B1A ;F2 FC 1A 9B
cmp r12, #1C2h ;46 FC C2 01
jmpr cc_c switched ;8D 03
mov r12, #2390h ;E6 FC 90 23
rets ;DB 00
;switched
mov r12, #2450h ;E6 FC 50 24
rets ;DB 00


Title: Re: Utilizing kfzw1 as switchable map for non-VVT engine
Post by: TijnCU on December 09, 2016, 06:24:14 AM
Here is an experimental section for switching LALIUS conditional:
Basically it looks for the lpg switch input first, and then checks if rl_w is in between of 50 and 120. If so, it uses an alternative map.
Code:
	    ;LALIUS call from 0x51ED0 
extp #0E1h, #1
mov r12, word_81B1A
cmp r12, #1C2h
jmpr cc_c switched
mov r12, #382Ah
rets      

switched:
mov r13, rl_w
cmp r13, #855h          
cc_ULE, not_set
cmp r13, #1400h
cc_UGT, not_set
mov r12, #E550h              ;lalius lpg map
rets        

not_set:
mov r12, #382Ah
rets