Announcement

Collapse
No announcement yet.

Documentary - Motronic 1.7 DIY Reverse Engineering

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #76
    High speed logging output base

    I made a base high speed logging output file for M1.7. This is made from an audi M2.3.2 file that i made several months back. The RAM variables are not right for the output but the base is there. i corrected all the jumps so that everything flows correctly and keeps logic with this code. over all it still needs work but could be tested using a freeware program called coolterm. coolterm will show the raw hex code output on a serial port. the baud rate for this is 187500 which is the maximum that the processor can output.

    for hardware you will need to use a generic blue VAG cable or a BMW K+DCAN cable connected to the K-line. how it should work is when the key is on and engine in not running you have access to the factory diagnostics but when the car is running the high speed data logging protocol takes over and starts constant output.

    The suggested RAM variables along with their equations that need to be found/added to this are
    -RPM in RAM
    -Ignition angle in RAM
    -coolant temp in RAM
    -intake air temp in RAM
    -injector constant in RAM
    -Injector dead time in RAM
    -Injector on time high and low bytes in RAM
    -wheel speed in RAM
    -TPS position through ADC
    -Load (preferribly 16bit because load could be uncapped) in RAM
    -MAF voltage
    -Knock control retard degree or counts of knock in RAM

    Also a wideband input could be added for logging as well, how i did it before was i found a spare unused ADC input on the processor and wired the 0-5V output from my zeitronix wideband controller into that. also using the ZT-3 controller it will simulate the 0-1V output of the stock lambda controller too! the ZT-3 is the best bang for the buck wideband controller on the market with both 0-5V and 0-1V dual outputs!

    With something like this working it will make the job of reverse engineering the rest of the ECU a heck of a lot easier because you can just change RAM variables and see what your output is. The other end of this that will need to be setup is a tuner pro RT ADX definition and dash layout. for now though using coolterm to get the logging output working is the first step. if you can get data to flow and see the raw hex in coolterm than you have something thats working.

    in coolterm you need to add 187500 baud to the through adding baudrates.ini file to the cooltermwin folder. you can make this with a text editor. in the baudrates.ini file add this and save the ini file.
    Code:
    [baudrates]
    187500=187500
    this is all i can do because i dont own an E30 to test anything with so someone with 8051 knowledge, a moates ostrich emulator and some free time in their hands will have to develop this further.

    files attached are an IDB for IDA 7.0 that has the logging code patched in and the BIN file itself that is a direct output from the IDB.

    for those who dont have IDA 7.0 and have to run the BIN through an older version the logging code is at the addresses in the code windows below.

    Code:
    ode:000006C0
    code:000006C0          ; =============== S U B R O U T I N E =======================================
    code:000006C0
    code:000006C0
    code:000006C0          code_6C0:                               ; CODE XREF: code_809D↓j
    code:000006C0
    code:000006C0          ; FUNCTION CHUNK AT code:000080A0 SIZE 000000D1 BYTES
    code:000006C0
    code:000006C0 20 24 15                 jb      RAM_24.4, code_6D8 ; Jump if Bit is set
    code:000006C3 E5 3B                    mov     A, RAM_3B       ; Move (Op1 <- Op2)
    code:000006C5 70 0B                    jnz     code_6D2        ; Jump if Acc is not zero
    code:000006C7 90 BE 00                 mov     DPTR, #code_BE00 ; Move (Op1 <- Op2)
    code:000006CA 12 9E C2                 lcall   code_9EC2       ; Long Subroutine Call
    code:000006CD F4                       cpl     A               ; Complement Operand
    code:000006CE 60 02                    jz      code_6D2        ; Jump if Acc is zero
    code:000006D0 D2 24                    setb    RAM_24.4        ; Set Direct Bit
    code:000006D2
    code:000006D2          code_6D2:                               ; CODE XREF: code_6C0+5↑j
    code:000006D2                                                  ; code_6C0+E↑j ...
    code:000006D2 90 44 F5                 mov     DPTR, #code_44F5 ; Move (Op1 <- Op2)
    code:000006D5 02 80 A0                 ljmp    code_80A0       ; Long Jump
    code:000006D8          ; ---------------------------------------------------------------------------
    code:000006D8
    code:000006D8          code_6D8:                               ; CODE XREF: code_6C0↑j
    code:000006D8 E5 3B                    mov     A, RAM_3B       ; Move (Op1 <- Op2)
    code:000006DA B4 0A 00                 cjne    A, #0xA, code_6DD ; Compare Operands and JNE
    code:000006DD
    code:000006DD          code_6DD:                               ; CODE XREF: code_6C0+1A↑j
    code:000006DD 40 F3                    jc      code_6D2        ; Jump if Carry is set
    code:000006DF 75 87 80                 mov     PCON, #0x80     ; Power Control Register
    code:000006E2 75 98 E8                 mov     SCON, #0xE8     ; Serial Channel Control Register
    code:000006E5 75 A0 00                 mov     P2, #0          ; Port 2
    code:000006E8 30 AC 01                 jnb     ES, Logging_Variables ; Interrupt Enable Register 0
    code:000006EB 22                       ret                     ; Return from subroutine
    code:000006EC          ; ---------------------------------------------------------------------------
    code:000006EC
    code:000006EC          Logging_Variables:                      ; CODE XREF: code_6C0+28↑j
    code:000006EC 78 AF                    mov     R0, #0xAF       ; Move (Op1 <- Op2)
    code:000006EE 08                       inc     R0              ; Increment Operand
    code:000006EF 74 FD                    mov     A, #0xFD        ; Move (Op1 <- Op2)
    code:000006F1 F2                       movx    @R0, A          ; Move from/to external RAM
    code:000006F2 08                       inc     R0              ; Increment Operand
    code:000006F3 E5 3A                    mov     A, RAM_3A       ; RPM
    code:000006F5 F2                       movx    @R0, A          ; Move from/to external RAM
    code:000006F6 08                       inc     R0              ; Increment Operand
    code:000006F7 E5 3F                    mov     A, RAM_3F       ; Load
    code:000006F9 F2                       movx    @R0, A          ; Move from/to external RAM
    code:000006FA 08                       inc     R0              ; Increment Operand
    code:000006FB E5 36                    mov     A, RAM_36       ; Battery
    code:000006FD F2                       movx    @R0, A          ; Move from/to external RAM
    code:000006FE 08                       inc     R0              ; Increment Operand
    code:000006FF E5 37                    mov     A, RAM_37       ; IAT
    code:00000701 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000702 08                       inc     R0              ; Increment Operand
    code:00000703 E5 38                    mov     A, RAM_38       ; CLT
    code:00000705 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000706 08                       inc     R0              ; Increment Operand
    code:00000707 90 BE 00                 mov     DPTR, #0xBE00   ; TPS
    code:0000070A 12 9E C2                 lcall   code_9EC2       ; Long Subroutine Call
    code:0000070D F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000070E 08                       inc     R0              ; Increment Operand
    code:0000070F 79 5F                    mov     R1, #0x5F ; '_' ; Move (Op1 <- Op2)
    code:00000711 E3                       movx    A, @R1          ; Move from/to external RAM
    code:00000712 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000713 08                       inc     R0              ; Increment Operand
    code:00000714 E5 54                    mov     A, RAM_54       ; IGN angle
    code:00000716 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000717 08                       inc     R0              ; Increment Operand
    code:00000718 E5 5E                    mov     A, RAM_5E       ; Injector High byte
    code:0000071A F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000071B 08                       inc     R0              ; Increment Operand
    code:0000071C E5 5F                    mov     A, RAM_5F       ; Injector Low byte
    code:0000071E F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000071F 08                       inc     R0              ; Increment Operand
    code:00000720 75 A0 01                 mov     P2, #1          ; Wheel speed input
    code:00000723 79 70                    mov     R1, #0x70 ; 'p' ; Move (Op1 <- Op2)
    code:00000725 E3                       movx    A, @R1          ; Move from/to external RAM
    code:00000726 75 A0 00                 mov     P2, #0          ; Port 2
    code:00000729 F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000072A 08                       inc     R0              ; Increment Operand
    code:0000072B 79 E8                    mov     R1, #0xE8       ; Move (Op1 <- Op2)
    code:0000072D E7                       mov     A, @R1          ; Move (Op1 <- Op2)
    code:0000072E F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000072F 08                       inc     R0              ; Increment Operand
    code:00000730 79 EA                    mov     R1, #0xEA       ; Move (Op1 <- Op2)
    code:00000732 E7                       mov     A, @R1          ; Move (Op1 <- Op2)
    code:00000733 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000734 08                       inc     R0              ; Increment Operand
    code:00000735 90 63 72                 mov     DPTR, #0x6372   ; Injector Constant
    code:00000738 E4                       clr     A               ; Clear Operand (0)
    code:00000739 93                       movc    A, @A+DPTR      ; Move code byte relative to second op to Acc
    code:0000073A F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000073B 08                       inc     R0              ; Increment Operand
    code:0000073C E5 5A                    mov     A, RAM_5A       ; Move (Op1 <- Op2)
    code:0000073E F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000073F 08                       inc     R0              ; Increment Operand
    code:00000740 E5 5B                    mov     A, RAM_5B       ; Move (Op1 <- Op2)
    code:00000742 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000743 08                       inc     R0              ; Increment Operand
    code:00000744 E5 5C                    mov     A, RAM_5C       ; Move (Op1 <- Op2)
    code:00000746 F2                       movx    @R0, A          ; Move from/to external RAM
    code:00000747 E8                       mov     A, R0           ; Move (Op1 <- Op2)
    code:00000748 94 AF                    subb    A, #0xAF        ; Subtract Second Operand from Acc with Borrow
    code:0000074A 78 AF                    mov     R0, #0xAF       ; Move (Op1 <- Op2)
    code:0000074C F2                       movx    @R0, A          ; Move from/to external RAM
    code:0000074D D2 AC                    setb    ES              ; Interrupt Enable Register 0
    code:0000074F 75 99 FE                 mov     SBUF, #0xFE     ; Serial Channel Buffer Register
    code:00000752 22                       ret                     ; Return from subroutine
    code:00000752          ; End of function code_6C0
    code:00000752
    code:00000752          ; ---------------------------------------------------------------------------

    Code:
    ode:00000760
    code:00000760          ; =============== S U B R O U T I N E =======================================
    code:00000760
    code:00000760
    code:00000760          RI_TI_0_1:                              ; CODE XREF: RI_TI_0↓j
    code:00000760 20 24 07                 jb      RAM_24.4, code_76A ; Jump if Bit is set
    code:00000763 02 89 60                 ljmp    RI_TI_0_0       ; Long Jump
    code:00000766          ; ---------------------------------------------------------------------------
    code:00000766 20 99 01                 jb      TI, code_76A    ; Serial Channel Control Register
    code:00000769 32                       reti                    ; Return from Interrupt
    code:0000076A          ; ---------------------------------------------------------------------------
    code:0000076A
    code:0000076A          code_76A:                               ; CODE XREF: RI_TI_0_1↑j
    code:0000076A                                                  ; RI_TI_0_1+6↑j
    code:0000076A C0 83                    push    DPH             ; Data Pointer, High Byte
    code:0000076C C0 82                    push    DPL             ; Data Pointer, Low Byte
    code:0000076E C0 E0                    push    ACC             ; Accumulator
    code:00000770 C2 99                    clr     TI              ; Serial Channel Control Register
    code:00000772 90 00 AF                 mov     DPTR, #0xAF     ; Move (Op1 <- Op2)
    code:00000775 E0                       movx    A, @DPTR        ; Move from/to external RAM
    code:00000776 70 09                    jnz     code_781        ; Jump if Acc is not zero
    code:00000778 C2 AC                    clr     ES              ; Interrupt Enable Register 0
    code:0000077A D0 E0                    pop     ACC             ; Accumulator
    code:0000077C D0 82                    pop     DPL             ; Data Pointer, Low Byte
    code:0000077E D0 83                    pop     DPH             ; Data Pointer, High Byte
    code:00000780 32                       reti                    ; Return from Interrupt
    code:00000781          ; ---------------------------------------------------------------------------
    code:00000781
    code:00000781          code_781:                               ; CODE XREF: RI_TI_0_1+16↑j
    code:00000781 C0 D0                    push    PSW             ; Program Status Word Register
    code:00000783 14                       dec     A               ; Decrement Operand
    code:00000784 F0                       movx    @DPTR, A        ; Move from/to external RAM
    code:00000785 24 B0                    add     A, #0xB0        ; Add Second Operand to Acc
    code:00000787 F5 82                    mov     DPL, A          ; Data Pointer, Low Byte
    code:00000789 E0                       movx    A, @DPTR        ; Move from/to external RAM
    code:0000078A F5 99                    mov     SBUF, A         ; Serial Channel Buffer Register
    code:0000078C D0 D0                    pop     PSW             ; Program Status Word Register
    code:0000078E D0 E0                    pop     ACC             ; Accumulator
    code:00000790 D0 82                    pop     DPL             ; Data Pointer, Low Byte
    code:00000792 D0 83                    pop     DPH             ; Data Pointer, High Byte
    code:00000794 32                       reti                    ; Return from Interrupt
    code:00000794          ; End of function RI_TI_0_1
    code:00000794
    code:00000794          ; ---------------------------------------------------------------------------
    your welcome guys! remember, this is my hobby so im doing this for fun. i dont own an E30 nor a BMW anymore, its been years since i owned one and dont plan on owning another one unless its a free car to develop on.
    Attached Files
    Last edited by vwnut8392; 01-05-2019, 01:11 PM.

    Comment


      #77
      Checksum DLL for tuner pro

      If someone here knows and is willing to share how the M1.7 checksum or checksums work and are calculated i can make a plugin for tunerpro RT that will auto correct the checksum. i'll include the source code for it so others can expand on that and make checksum plugins for other DME's.

      Comment


        #78
        Hello

        bmwman91 found it:
        Originally posted by bmwman91 View Post
        Also,
        A long time ago I found a simple EXE on some random website to calculate checksums for a few different DME's. I disassembled the EXE and got the exact algorithm used for the checksum in M1.x. It is pretty simple. Again, addresses are referring to those on the 32K EPROM, not the proper 40K image.

        CSUM = MOD([SUM(0000h:1EFFh) + SUM(2000h:7FFFh) + 46367], 65536)

        This 16 bit value is then stored at address 1F00h:1F01h (MSB:LSB).


        The EXE I found (not mine, I take no credit for making it) is here. It seems to support a number of variants (run through command line):
        http://www.e30tuner.com/assist/Motro...Calculator.zip
        I think subroutine code_9016 is related to checksum.
        Racing is life. Anything that happens before or after is just waiting

        Comment


          #79
          Originally posted by biela View Post
          Hello

          bmwman91 found it:


          I think subroutine code_9016 is related to checksum.
          i have not looked into the M1.7 checksum specifically. This post does help with making an M1.3 checksum DLL for tuner pro though i would like to focus on M1.7 because its just a more superior ECU.

          Comment


            #80
            I added the M1.7 checksum to my web app a while back. I also tested it on a couple other DMEs (such as the M70) and it worked fine. Would be cool to extend it to 1.3, even if 1.7 is much improved 1.3 is far more common on the E30.
            Build thread

            Bimmerlabs

            Comment


              #81
              It's been super busy for me the last week or so, and will probably continue to be. But, there's a lot of cool stuff going on in here all of a sudden lol. I am not likely to be testing the ignition-based rev limiter since I have a WBO2 and catalytic converter on the car, but we'll get it figured out.

              The way that the tables are accessed seems nuts to me. Like, super inefficient, especially considering how badly these ECUs could use more instruction cycles in the main loop at high RPM. Anyway, I will try to take a look through instruction areas that look like what you showed and trace them into the actual table accesses. I'd really like to see how they look-up and interpolate table values since the way that axes are defined seems like it would inherently eat way more instruction cycles than necessary.

              The checksum is dead simple on these DME's. It just sums up all of the values in program memory from 0x0000 - 0x9FFF, EXCLUDING 0x3F00 - 0x3FFF in the full 40K binary dump (0x1F00:1FFF in the EPROM) and truncates them to a 16 bit value, which is stored at 0x3F00:3F01. The value of 46367 from my previous post is simply the sum of the 8K internal program memory of the SAB80C515 MCU, which is mainly just interrupt vectors and some other stuff I am unsure of. I used the constant because I had not yet dumped the internal MCU program memory. This is identical in M1.3 & M1.7, and probably others. The IDA project based on "TotalCombinedROM" uses a binary I made by dumping the MCU's internal 8K via the K-line and combining it with the 32K from the EPROM (well, actually I just tapped an Arduino directly into the MCU's UART).

              Comment


                #82
                Originally posted by bmwman91 View Post
                It's been super busy for me the last week or so, and will probably continue to be. But, there's a lot of cool stuff going on in here all of a sudden lol. I am not likely to be testing the ignition-based rev limiter since I have a WBO2 and catalytic converter on the car, but we'll get it figured out.

                The way that the tables are accessed seems nuts to me. Like, super inefficient, especially considering how badly these ECUs could use more instruction cycles in the main loop at high RPM. Anyway, I will try to take a look through instruction areas that look like what you showed and trace them into the actual table accesses. I'd really like to see how they look-up and interpolate table values since the way that axes are defined seems like it would inherently eat way more instruction cycles than necessary.

                The checksum is dead simple on these DME's. It just sums up all of the values in program memory from 0x0000 - 0x9FFF, EXCLUDING 0x3F00 - 0x3FFF in the full 40K binary dump (0x1F00:1FFF in the EPROM) and truncates them to a 16 bit value, which is stored at 0x3F00:3F01. The value of 46367 from my previous post is simply the sum of the 8K internal program memory of the SAB80C515 MCU, which is mainly just interrupt vectors and some other stuff I am unsure of. I used the constant because I had not yet dumped the internal MCU program memory. This is identical in M1.3 & M1.7, and probably others. The IDA project based on "TotalCombinedROM" uses a binary I made by dumping the MCU's internal 8K via the K-line and combining it with the 32K from the EPROM (well, actually I just tapped an Arduino directly into the MCU's UART).
                thats awesome how you got the data from the MCU! when it comes it arduino programming or anything in that area im stupid. i focused all my learning over the years to being able to just read the raw HEX from the 8051 or 68HC11 and follow it. my friends say i can see into the matrix because i can roughly follow code without IDA if i need to and make raw edits to the binary that actually work lol. tell me to make something in C or write a sketch for arduino and i'll just sit there and beat my head off a desk. im like the rain man of programming .

                i'd like to learn how to do more with arduino because i bought a freematics one+ programmable OBD logger. i wanted to see if i could get it to work with the M232 data logging protocol. this would be awesome because that device has an SD card port for standalone logging without a PC, bluetooth and wifi that could be used for wireless logging of the old motronic. i made a really good looking winlog dash for M232 recently and i'd like to make a quick mount in my car for a windows tablet and use it as a virtual multi gauge/dash. would be way cooler than having all these separate gauges mounted all over the place. but the problem is i cant write ardunio code and i have no idea where to even start with getting that rolling. why i bring this up is because this idea could also work on the BMW DME if a similar data output protocol is achieved like in my other posts ;D.

                Comment


                  #83
                  Hello, sorry to deflect the thread of the converzacion, but I have a doubt, in the motronic 1.7 the injection is simultaneous? inject the 4 cylinders at the same time? I have in my workshop a 318 1993 model with that type of injection. I am looking for manuals of that injection to verify if it is correct or is there a problem? thanks for your time


                  so I understood it injected in pairs, but here it would not be happening

                  https://youtu.be/3hABSENEzlM
                  Last edited by reloadstorino; 05-04-2019, 12:31 PM.

                  Comment


                    #84
                    Cranking is bit different than running and many ecus do that batch fire to start engine easier.

                    Comment


                      #85
                      if I understood what you are saying is to improve the cold start injected in the 4? and then goes on par? Thank you

                      Comment


                        #86
                        M1.7 has two injection modes:
                        >>> Batched - Fires all 4 injectors at once. It does this when starting, when the cam position sensor is not functioning and also under some other fault conditions.
                        >>> Banked - Fires injectors 1+3 and 2+4 separately (2 sets of 2 injectors). This is the normal operating mode used when the engine is running and there are no hardware faults with any sensors.

                        Comment

                        Working...
                        X