NefMoto

Technical => Reverse Engineering => Topic started by: Basano on December 24, 2014, 06:42:41 AM



Title: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on December 24, 2014, 06:42:41 AM
Edit. Flash. Log. Repeat.

What about a way to change the output of maps dynamically? Maybe reducing the amount of time spent flashing just very small tweaks when narrowing down towards an optimal setting?

I haven’t done any modifications for a while now. I’ve been reading a lot of books instead (which is perhaps what I should have done to begin with…). I gather certain aftermarket systems let you alter the maps dynamically which is nice if you have a load holding dyno. For ME7 I understand there are emulators as well which achieve the same thing. Although I’ve never actually seen an aftermarket ecu or emulator either :)

Now I can’t dynamically change the map values in my MED9.1 and I don’t have an emulator, but what about the output of the map? This is a variable anyway and by simply adding or subtracting a bit, it’s effectively the same as changing the map.

For example, let’s say at 3000 rpm and 190% load, KFZW is 1.5 degrees. At those conditions, this is the output of the map (1.5 degrees) and is contained in a register. I could add this register to a second register that contains a dynamic value of my choice (say 1 degree) and put the sum of the two (2.5 degrees) back in the original register. Now the ecu would carry on and faithfully process this, just as though it had looked up 2.5 degrees to start with. If torque increases, that’s good and you should add 1 degree to that cell in the bin next time you flash (for a total of 2.5 degrees) . If knock increased, that’s bad and you should leave that cell alone.

So how is this dynamic? Well, what about changing the contents of that second register by turning a dial?

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12434;image)

I used the CANBUS to implement this. I discovered that the messages received on the CANBUS by the ecu populate a table in RAM. By creating my own CANBUS message, I could change the byte values in the RAM table. I could then use those RAM addresses in some custom ASM to add two registers together as described above.

Bit of background on the CANBUS.

1)   In the flash there is a table containing the CANBUS ID’s that the ECU will actually receive. There are a lot of CANBUS messages floating around on the bus. Normally CANBUS nodes don’t listen to all messages by default since they’d spend all their time processing interrupts and discarding irrelevant message ID’s instead of getting on with the job. So there’s usually an access filter which only allows certain messages. Only if one of these permitted messages is received does the node process it. Here’s the table in flash. There are three sections (lining up with the three TouCAN modules in the MPC562 processor). This is nicely documented in the FR as well which describes exactly what each message ID is used for. Have a look at sections CAN_CONF and CANECUR. In my S3 the configuration table starts at 0xA09F4.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12436;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12438;image)

2)   So the message ID’s are contained in a table in the flash and that table also has spare entries (the ones marked 7FF). Here’s the equivalent table in an A6 MED9.1 ecu. You can see extra entries, presumably for equipment that I don’t have in my S3. I’m guessing I can add my own message ID’s that I wish to receive in the spare lines of the table.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12440;image)

3)   Ok, but where do the received messages pop out then? I used my RAM logger and took a snapshot of the ecu RAM. Lo and behold, nestled away was a table containing the CANBUS ID’s and the received CANBUS data bytes. Could it be this simple? Add my own message ID to a spare line in the flash table, transmit a message with that ID on the powertrain bus and it pops out on the corresponding line in the RAM table? Not quite :)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12442;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12444;image)




Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on December 24, 2014, 06:57:23 AM
4)   By trial and error I discovered that not only do you need to put your own CANBUS ID in a spare line in the flash table, you then need to read that table entry. I’ll try and explain the code snippet below. Basically it’s saying load #1 into a register (#1 means first row of the flash table), then call a function that does the reading 585C2C. Then load #2 into a register (#2 means the second row of the flash table) and call the same reading function 585C2C. Repeat for each row of the table. This is the important bit, you don’t need to mess about with anything else, just give the row number to the function 585C2C and it does everything else for you. The data bytes will pop out in the RAM table. I found the code that reads the table rows by searching on cross-references to the configuration table (at 0xA09F4).

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12446;image)

5)   So where is the best place to load and call this reading function? In my S3 flash, table row #7 is free and thus not called anywhere (there are no lines of assembler that refer to row #7). I compared that against the A6 bin where row #7 is actually in use. I saw that in the A6 bin, row #7 is called each time after row #1. So what I did in my S3 bin, each time row #1 is loaded and passed to the function, I added in a couple of lines that load row #7 and pass it to the function as well. I only had to add 12 lines of assembler. The OEM code calls table row #1 three times, I don’t know why but I copied it faithfully.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12448;image)

6)   There are also codewords (CW_CAN_R, CW_CAN_RA, CW_CAN_RB, CW_CAN_C) that turn on and off the monitoring and reception of CAN messages, but these messages actually need to be compiled into the flash to begin with. What I’m doing above is adding messages that never ever existed in the first place, they weren’t compiled in and there’s no lines of assembly relating to them. Thus the code words don’t really apply – it’s happening at a layer below any of that. Worth mentioning as well is that there’s no monitoring or message timeouts resulting in fault codes either – if one of my bespoke messages goes missing, well it’s gone. All I did was patch in a few lines that piggyback the reading of table row #7 on the back of another table row read. That’s why there are far more lines of assembler in the A6 bin to read row #7 than just my 12 lines. I think all the other code takes into account monitoring and timeouts and codewords, but I put in the bare minimum to populate my CANBUS RAM table. It’s very simple.

Here’s how I implemented it

I used CANBUS ID 44A. This was free (unused) in my car and as far as I can determine, is related to the automatic transmission (read the FR, sections CAN_CONF and CANECUR). I have a manual, so I think I’m fairly safe.  

To tap into the powertrain CANBUS, I wanted a way that was non-invasive and didn’t require any modifications on the stock wiring harness. I wanted to be able to unplug any modifications in a matter of minutes if I needed to revert back to 100% OEM. I also wanted the diagnostic port to be free so I could use data loggers and diagnostic tools like normal. The CAN gateway was the easiest place for me. In my S3, it’s located just behind the glove box and is pretty straightforward to get to. I made a little pass-through box. Just unplug the 20 pin wiring harness connector from the gateway and plug it into the pass-through box. The pass-through box in turn has a short length of cable that plugs back into the gateway. The pass-through box also has a DB25 connector that all the buses (powertrain, infotainment, diagnostic, cluster, convenience) are available from. You can buy the plug housings from VW/Audi, but for the sockets I got a couple of cheap eBay CAN gateways and lifted the sockets off of them. To make the little stub cable between the pass-through box and gateway, I sourced the crimp pins from Farnell and got a wiring loom shop to crimp them up for me using their Tyco/AMP hydraulic tooling.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12450;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12452;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12454;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12456;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12458;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12460;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12462;image)


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on December 24, 2014, 07:05:13 AM
To build my little CAN node that will transmit my bespoke CANBUS message ID and data bytes, I used an Arduino UNO and Sparkfun CANBUS Shield. I included an Adafruit Seven Segment I2C display and an incremental encoder from Bourns (EM14A1D-C24-L008S). I chose an optical encoder so I didn’t have to spend time troubleshooting switch debounce. I specifically used these parts as they are readily available off the shelf, all over the world. There’s no point in bespoke hardware at all. How would you share it? Use something that anyone can get a hold of and you can collaborate :) Plus it’s really cheap as well and there’s loads of user contributed stuff. Use whatever processor you like

https://www.sparkfun.com/products/10039
http://www.adafruit.com/product/879
http://www.bourns.com/pdfs/em14.pdf

https://github.com/adafruit/Adafruit-LED-Backpack-Library
https://www.pjrc.com/teensy/td_libs_Encoder.html

I’ve also attached the libraries and Arduino sketch as loaded onto the encoder box.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12464;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12466;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12468;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12470;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12472;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12474;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12476;image)

Wire to board connectors, Tyco/AMP HE14 series. So tiny :) That's a TE crimper I got of eBay. No ways I can afford that stuff new!

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12478;image)


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on December 24, 2014, 07:11:48 AM
The software is very easy, in fact I used readily available libraries for the Seven Segment display and incremental encoder. The encoder has a detent, so when you twist it there’s click to provide some tactile feedback. When you turn the encoder dial, the first data byte of the transmitted CANBUS message changes. One click clockwise -> 01, another click clockwise -> 02. Turn it in the other direction and it decrements. One click anticlockwise -> 01, another click anticlockwise -> 00, another click anticlockwise -> FF, another click anticlockwise -> FE (two’s complement representation of negative numbers). The Seven Segment display shows the scaled value of what’s being sent in that first data byte. I’m transmitting eight data bytes, but only the first has a value and the remaining seven are zero

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12480;image)

Pulling it all together then, I wanted to use this to change the output of KFZW and KFZW2. I added a bit of bespoke assembly that combines the output of the timing map with the correction value received over the CANBUS. This combined value is then used by the subsequent ecu assembly code, effectively as though the map value itself had been changed. There are five chunks of assembly – the original code has x1 reference to KFZW and x4 references to KFZW2. All I did was add code that takes the output value whenever KFZW/KFZW2 is read and combines it as described above.

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12482;image)

Looking at an extract from a log of the memory locations, you can see the original output of KFZW, the value received via CANBUS and the new value (sum of original value and CANBUS value). I was storing the register values in RAM so I could log and check my workings, especially since the firing angle can be both positive and negative (BTDC and ATDC) and negative numbers means two’s complement maths. I didn’t want to mess it up, but all it needed was sign extension 

You’d log rpm and load and CF’s, turn the dial (which  increases the amount being added to the original map output) which increase the firing angle advance. Check CF’s or torque. If the CF’s are good then you can permanently add this much timing to the cell (next time you flash), else back the dial off a bit until things look better (new map entry = original map entry + correction).

In summary, this was a neat way of changing variables inside the ecu without too much hardware effort (extra wires or pins on the ecu). I used KFZW / KFZW2 as an example, but I’ve subsequently discovered there are many more timing maps than just those two. The same principles could be applied to other things, like LDRXN or even having a little toggle switch on the CAN node. Flicking the toggle switch could result in a RAM location being set to zero or one and activating or deactivating a function (ALS/NLS) or even hardware like cooling fans. Use your imagination 

IDA project attached, plus before and after versions of the bin so you can see what I changed.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on December 24, 2014, 07:24:40 AM
IDA project


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on December 24, 2014, 07:31:44 AM
Installed in the car

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12490;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12492;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12494;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12496;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12498;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12500;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12502;image)

(http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=7470.0;attach=12504;image)


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: terminator on December 24, 2014, 07:45:49 AM
You are a genius! Thanks for sharing. By the way I solved my problem)


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: adam- on December 24, 2014, 10:13:42 AM
This is so awesome!

A lovely, detailed write up too, well done sir!


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: dream3R on December 25, 2014, 03:32:00 PM
Well done Sir!



Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: technic on December 25, 2014, 03:51:48 PM
You know, I just love these kind of things! Well done David!
I will try this approach using my NXP setup.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Aurélien on December 26, 2014, 04:16:51 AM
Good job.

This method enable tuning up to 8 bytes of data. So 8 parameters with 8bit value or 4 with 16bit ( _w ) .

The implementation is easier than what I'm currently doing ( writing ram via TP20 ) and keep the OBD2 port free. Cool !

I will try porting this to my rom but I think I will start lacking space for code !  :D


Title: Re: Sv: MED9.1 – Changing the effective values in maps in real-time
Post by: technic on December 26, 2014, 06:08:18 AM
What is TP20? For me beeing an old hw designer, that is a testpoint :P


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: daniel2345 on December 26, 2014, 11:52:01 AM
Transport Protocol 2.0, some VAG CAN Stuff...


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: technic on December 26, 2014, 12:53:37 PM
Ahhh...of course...


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: AngelPowy on January 14, 2015, 08:01:24 AM
Dude I want you to know that  you are a HERO for this community. I've read all your post on MED 9.1. I've learn so much thing here in 1 week than in 2 month at school. Your job was just excellent. I am actually trying to adapt NLS and multimap on my uncle's golf. They is some things that I don't understand actually but I keep reading and searching then I will finally understand.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: majorahole on January 16, 2015, 11:55:59 AM
awesome write-up!! a bit over my head, as i cant figure out the ida well enough to change logging variables yet, but for those that get it, this is cool little tool to have!


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: AngelPowy on January 17, 2015, 12:02:11 PM
I appologize if my question is maybe noob, but As we change asm code (wich is not in the tuning area if I can say it like this), Ols don't cover change is this region of the flash. So do we have to worry about checksum? Or does the Region storing those code work without checksum ?


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: nyet on January 17, 2015, 12:09:56 PM
I appologize if my question is maybe noob, but As we change asm code (wich is not in the tuning area if I can say it like this), Ols don't cover change is this region of the flash. So do we have to worry about checksum? Or does the Region storing those code work without checksum ?

1) checksums cover both asm and the maps
2) ols covers both asm and the maps
3) live checksumming must be disabled for live changes to not cause faults.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: AngelPowy on January 17, 2015, 09:08:52 PM
Ok so my ols version is uncorrect. When I try to modify the flash file in ASM region Winols tell that this area is not covered by checksum. So I think that WInols can't do this checksum but maybe flash tool is able to.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Aurélien on January 18, 2015, 04:36:34 AM
If you use original winols with original winols checksumm plugin, it does correct checksumm for every single area.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: AngelPowy on January 19, 2015, 12:11:08 AM
Ok, I don't have the original version of winols I only tune for pleasure. And I use a V12 MPPS c*** so do the tool checksum when write or should I not try?


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: prj on January 20, 2015, 05:32:21 PM
I would go about this differently.
Not to talk down on your effort or anything.

A much simpler way is to map tables to memory.
In the flash, locate where tables are read, and redirect the reads to RAM.
Build in a check that populates the RAM addresses on startup or on first read.

After that use WriteMemoryByAddress service (if it does not exist, create it) to write RAM directly.
That way you can offload whole tables in to RAM. If you want to attach fancy dials to that, no problem.
It is just a lot more universal... and this is how real time mapping is done on aftermarket ROM's for Evo ecu's.

The easiest way of course is to solder in a BDM header permanently, then overadvance the timing in the whole map, and record average CF at each operating point.
Then subtract it from the map... That's what I did recently on a dual ECU setup. Only works in areas where it is knock limited though, does not work in areas where MBT is below knock limit, there you actually need something to change stuff in real time.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: Basano on January 21, 2015, 04:49:37 AM
Hi prj,

When I looked at data-logging ages ago, I couldn’t get #3D WriteMemoryByAddress to work in MED9.1. I always got a negative reply – #7F and in the end I gave up on that route.

I think Aurélien has got WriteMemoryByAddress working via KWP & TP2.0, but I don’t know if he discovered a way to enable the service on MED9.1 or had to write an implementation in ASM. If he did that – impressive!

RAM-based tables would be a very neat feature



Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: prj on January 21, 2015, 08:55:25 AM
Well you are adding monitoring of CAN ID's, it is no different to adding some logic into the ECU diagnostics routines.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: technic on February 01, 2015, 03:14:02 AM
The easiest way of course is to solder in a BDM header permanently, then overadvance the timing in the whole map, and record average CF at each operating point.
Then subtract it from the map...
This is how I do it aswell.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: ozzy_rp on February 01, 2015, 01:44:55 PM
My small contribution in this thread.
PCB for can-bus splitter.


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: marrakech on June 15, 2015, 05:09:12 AM
greate!


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: tobygolf66 on September 01, 2015, 11:35:00 AM
Great Job Basano ;-) Thank you ! 8)

Rgds Toby


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: dream3R on September 11, 2015, 01:04:09 PM
Hi prj,

When I looked at data-logging ages ago, I couldn’t get #3D WriteMemoryByAddress to work in MED9.1. I always got a negative reply – #7F and in the end I gave up on that route.

I think Aurélien has got WriteMemoryByAddress working via KWP & TP2.0, but I don’t know if he discovered a way to enable the service on MED9.1 or had to write an implementation in ASM. If he did that – impressive!

RAM-based tables would be a very neat feature



It's got to be there!  Possibly a security feature?




UDS surely lol


Title: Re: MED9.1 – Changing the effective values in maps in real-time
Post by: tobygolf66 on September 25, 2015, 01:44:33 AM
great stuff, thank you ;-)

rgds