Announcement

Collapse
No announcement yet.

Modifying Motronic 2.3.2 ECU hardware and software.

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hi,

    im trying to understand the obd subroutines

    We know that the ECU responds with 0x55h after the "wake up" part. The UART is configured to 9600 Baud. SCON 0E8h and SMOD in PCON = 1. The two following bytes sent by the ecu aren't hardcoded (i dont know them, because i haven't logged the serial communication with a running ecu yet). The ecu waits now for an acknowledge (ff-last byte sent)

    In this code area (around 0x5548) the typical vagcom strings are loaded (4a0...). There is one adress called very often after loading such data: 0x59f2. Am i right to say it's a kind of uart_send_char procedure? I think finally it sends contents of 35h.

    I searching for the part where it loads the block data which are demanded by vag com. I guess there must be a sort of switch case structure which selects the data to send.

    Grettings

    Comment


    • Originally posted by -ice- View Post
      Hi,

      im trying to understand the obd subroutines

      We know that the ECU responds with 0x55h after the "wake up" part. The UART is configured to 9600 Baud. SCON 0E8h and SMOD in PCON = 1. The two following bytes sent by the ecu aren't hardcoded (i dont know them, because i haven't logged the serial communication with a running ecu yet). The ecu waits now for an acknowledge (ff-last byte sent)

      In this code area (around 0x5548) the typical vagcom strings are loaded (4a0...). There is one adress called very often after loading such data: 0x59f2. Am i right to say it's a kind of uart_send_char procedure? I think finally it sends contents of 35h.

      I searching for the part where it loads the block data which are demanded by vag com. I guess there must be a sort of switch case structure which selects the data to send.

      Grettings
      Look for JMP @A+DPTR, you will find the jumps one after another to the 30 measuring blocks. Look at KWP1281 protocol docs on blafusel.de to understand how measuring block data is converted to real world values.
      To know which block is in which group and what it represents, look just before the jump instruction and you will see two offsets. One for Group 000, one for the rest. Each group, including the 10 values in Group 000 are mapped in the binary one after another.

      After this you should be able to figure out the scaling of most variables inside the ECU...

      Of course it does not write directly to the port, it writes to a buffer in XRAM and then transmits this buffer over protocol. Well, you will see...
      http://tuner.ee - http://www.facebook.com/tuner.ee

      Comment


      • Hi,

        Thank you for your reply.

        I saw this block of long jumps yesterday. I didn't know they point to the measuring block routines. It depends on the accu, which of the 31 adresses is selected. The accu value itself depends on the multiplication of the accu and B. B seems to be fixed to 03h. So possible accu values for the multiplication are 01h to 1Eh to get a valid adress. In the code before the jmp seem to be two cases where the accu is loaded with help of dptr (8BA8h and 8BCCh). Maybe these are the offsets you are talking about?

        I'm not sure how this data is aligned in the binary. I tried to calculate the accu-value by reading the code, but didn't find out anything useful.

        For group 000 i expect ten bytes in the binary which select (after the calculation...) the coresponding ljmp adress? Is it like that?

        Greetings

        Comment


        • 02 03 09 08
          02 07 10 11
          02 06 12 04
          02 06 13 1D
          01 17 14 1E

          02 leads to engine speed, 06 to engine load?

          Comment


          • Originally posted by -ice- View Post
            Hi,
            In the code before the jmp seem to be two cases where the accu is loaded with help of dptr (8BA8h and 8BCCh). Maybe these are the offsets you are talking about?
            Correct, these map blocks to groups.
            Now look a bit more and you will see how everything works.
            http://tuner.ee - http://www.facebook.com/tuner.ee

            Comment


            • I'm tired of staring at the screen

              I think 8BA8 is for the 4 block groups (because of the repetive pattern of single blocks in the binary; f.e. Many groups have engine rpm in them)

              And 8bcc should be group 000. But i can't find a description or label file for this group on the net. It doesn't seem to be the same with aby.

              Comment


              • Originally posted by -ice- View Post
                And 8bcc should be group 000. But i can't find a description or label file for this group on the net. It doesn't seem to be the same with aby.
                It is exactly the same on all 2.2T.
                Don't believe everything you read online - there is only one truth, and this truth is in the code. Not what someone writes online...

                Why do you need this anyway? It's like 4 times/sec and unstable. If you want data from the ECU, just kill the entire diagnostic routine and write your own. 187500 baud works well.

                If you want to identify the scaling and memory locations in the ECU, then surely looking at 001 groups and up is MUCH more interesting, as this is standardised in KWP1281 and you can get exact formulas.
                http://tuner.ee - http://www.facebook.com/tuner.ee

                Comment


                • Step by Step, i dont't have the asm skills that you have Im not able to replace whole code parts yet, because I dont't know how the whole program works together...


                  Basicly I want to learn about the variables usesd, that's why i analyze the measurement routines.
                  I will connect my Vagcom tomorrow and then I will see which channels are the same in different Groups.

                  ByeBye

                  Comment


                  • How to replace code? You can replace the entire diagnostics routine.
                    All of it. Right from where it calls into it.

                    You can use the same buffer in xram as it does to fill it, then you have to send the data.
                    The diagnostics routine is called with a limit of 100 times per second at RPM below 5000, above that it starts to slow down a little, still gets about 60-70 times per second.

                    If you want good data - say 15 bytes and minimum 10 times per second (better is a bit more), then you need something that is executed more often. So you have to think where you do the sending of your buffer...

                    The map lookup routine is a good place to put your buffer sending logic for example, as that gets called very often - much more than 100 times per second.
                    It's just a bog standard 80C535 chip. There's no magic about it. Everything that works on a standard 8052, works here, you just have to take care not to trash the stack or overload the processor with naively written code.
                    http://tuner.ee - http://www.facebook.com/tuner.ee

                    Comment


                    • My vagcom Demo can't read Group 000

                      As I looked closer to the measurement block-routines, there seems to be a pattern. I think MOVX @R0 pushes a char into the uart-buffer. For every block the buffer is filled with three bytes. The first seems to be fixed an special for a block. Second an third byte seem to be parameters.
                      f.e. in Block 02 variable 0x3a is pushed into the buffer as last value. Previous byte is also fixed. Maybe theses are a and b in blafusels table?!

                      prt, dou jou have a typical 0x3a value for me with engine running at idle rpm? Then i can check the formula and if it makes sense..

                      Thank you

                      Comment


                      • Originally posted by -ice- View Post
                        My vagcom Demo can't read Block 000

                        As I looked closer to the measurement block-routines, there seems to be a pattern. I think MOVX @R0 pushes a char into the uart-buffer. For every block the buffer is filled with three bytes. The first seems to be fixed an special for a block. Second an third byte seem to be parameters.
                        f.e. in Block 02 variable 0x3a is pushed into the buffer as last value. Previous byte is also fixed. Maybe theses are a and b in blafusels table?!

                        prt, dou jou have a typical 0x3a value for me running at idle rpm? Then i can check the formula and if it makes sense..

                        Thank you
                        Come on man...
                        Die folgende Tabelle (basierend auf der Datei Value-calculation.txt aus der Yahoo! Gruppe opendiag) zeigt die Kennzahlen für die Sensordaten (1. Byte) und deren Umrechnung, wobei a für das erste Meßwert-Byte (2. Byte) steht und b für das zweite Byte (3. Byte).
                        It's written right there exactly how it is. ID, A, B. Refer to that table for formulas.

                        There is also no magic "UART buffer". There's just an array in XRAM. If you look closely you see it increments the buffer length as well. It's just a structure of length and then a sequence of bytes.
                        http://tuner.ee - http://www.facebook.com/tuner.ee

                        Comment


                        • Ok, the harcoded first byte ist the "Kennzahl". So vagcom uses the Kennzahl to know how to calculate the result and give it a unit.


                          So 3A = 0x14 should be 800 rpm.


                          That's a simple buffer for me... first i thought it would put data directly into sbuf

                          Sorry... for you this is boring, because you already know everything. Thanks alot for your hints...

                          Greetings

                          Comment


                          • You can put data directly into sbuf too.
                            If you write your own logic it is possible to just have 1 byte that tracks the current packet and then use the JMP @A+DPTR system to jump through them sequentially...

                            It's enough to do something like this:

                            RAM_PTR equ 0xXX

                            JBC TI, bitset
                            RET

                            bitset:
                            MOV A, RAM_PTR
                            MOV B, #003h
                            MUL AB
                            JMP @A+DPTR
                            LJMP byte1
                            LJMP byte2
                            ...
                            LJMP end

                            byte1:
                            MOV SBUF, xxx
                            LJMP end
                            byte2:
                            MOV SBUF, yyy
                            LJMP end

                            end:
                            INC RAM_PTR
                            RET

                            And you can start sending by just doing:
                            CJNE RAM_PTR, <packet length>, getout
                            MOV SCON, xxx
                            MOV PCON, xxx
                            MOV RAM_PTR, #00h
                            CLR TI
                            MOV SBUF, zzz
                            getout:
                            RET

                            And then make sure the first block is called often enough... Maybe use some magic combination of 2 or 3 bytes so that you can see where the packet starts, and just stream the data nonstop.

                            Quite simple really... you can easily just replace the diag routine with this.
                            Stuff gets fun when you want to read data from the other uC as well and you have to sync them to each other so they don't talk over each other.
                            http://tuner.ee - http://www.facebook.com/tuner.ee

                            Comment


                            • Nice I need to get an emulator working to try out the modifications. I tried to buy an Ostrich 2.0, but they can't deliver it to germany

                              I have a question concerning the rev-limit: Does the aan engine really have a 0xB0 limiter-value? Thought the rev limit would be later around 7200rpm...
                              0xA5 for automatic transmission seems conclusive...

                              Greetings

                              Comment


                              • Another thing i worry about...

                                We discussed the map access routine, which uses 75/76 and 77/78 + registers as "parameters"

                                I don't understand how and when these variables are assigned. There are code parts, where it writes to them directly

                                f.e:

                                4CB5 : 75 75 88 MOV 75H,#88H
                                4CB8 : 75 76 00 MOV 76H,#00H
                                4CBB : 75 77 80 MOV 77H,#80H
                                4CBE : 75 78 00 MOV 78H,#00H
                                4CC1 : 22 RET

                                Ok, but these don't access the interessting maps of the map adress-table (f.e. rpm-load-fuel @8dc6)

                                So i think, this adresses will be assigned indirectly (perhaps the offsets are also mapped anywhere an loaded with dptr).
                                I can't find code where it assignes 75h/76h (except some code, in which it does something with the carry flag)

                                Comment

                                Working...
                                X