Jump to content
Click here if you are having website access problems ×

Cloning the Rover MEMS3 ECU (The Easy Way!)


revilla

Recommended Posts

A while back a wrote an article on cloning the Rover MEMS3 ECU here: https://www.lotus7.club/forum/techtalk/cloning-rover-mems3-ecu. This process was fairly involved and invasive. It involved dismantling the ECU, removing the memory chips and reprogramming.
 
Since then I’ve been working on cracking the process of flashing full maps and firmware to the MEMS3 ECU without any disassembly. I wanted to be able to copy the full firmware and maps from one ECU to another in a simple way through the OBDII port only, similar to the way that well-known mapping specialists do. This goes well beyond the map reading and writing capabilities of tools like Galletto as it allows the full operating firmware of the ECU to be cloned.
 
It’s taken me about a year of chipping away at it … but I’ve finally got something robust and useable. I’ve written a little MEMS3 Flasher application that allows ECUs to be read and written very simply. 
 
image001.png.1392c0e048b0f57b52218c45efe74a75.png
 
This allows you to clone the complete firmware and map from any MEMS3 ECU to any other with the same part number or compatible hardware. So for example you can make a backup copy of Supersport ECU by cloning it onto a standard Rover ECU cheap off eBay.
 
This works with standard tunes and modified remaps too.
 
Hardware Required
 
One objective I set myself was that no expensive hardware should be required. In order to use my flasher, the only thing you need (other than a Windows laptop with a USB port to run it on) is a VAG-COM diagnostic cable such is this: https://www.ebay.co.uk/itm/VAG-COM-USB-OBD2-II-KKL-ECU-DIAGNOSTIC-CABLE-VCDS-LITE-409-FTDI-FT232BL-Chip/330753371108?epid=23023316182&hash=item4d026febe4:g:DMEAAMXQwKdRc8J6.
 
image002.thumb.png.ae0a9c10254bb5b5963c869506f41819.png
 
Any similar FTDI-based OBDII cable with K Line support (if it mentions ISO 9191-2 or ISO14230-2 protocols it will be fine). My software talks directly to the FTDI drivers, so it is important that the cable uses the FTDI chipset - so check that the description mentions FTDI, FT232 or similar.
 
The MEMS3 Flasher Tool
 
This is a simple Windows EXE, no installation required. All you need to do is plug the cable into the laptop and the car and run the program and it’s ready to go. You can download a ZIP of the EXE file here: https://drive.google.com/open?id=1PZSxQYZe9bbrbFYVD0ih2JXs1sG9-oJy.
 
What Does It Do?
 
I’ve kept it simple from a user perspective. The temptation was to fill it with fancy features but I decided that simplicity was in order. As the user sees it, it has a simple job to do; read and write ECUs and allow the data to be saved and loaded to and from files. It needs to do that one job really well.
 
It works like a classic EPROM programmer. You click “Read” to read the data from an ECU into a memory buffer, “Write” to write the current memory buffer out to an ECU. You click “Save” to save the current memory buffer to a file and “Load” to load previously saved data. That’s about it really!
 
It specifically supports the MEMS3 family of ECUs only, so there’s no selection or configuration required. Just plug and play.
 
Some other programming tools like Galletto 1260 do allow you to do something similar with the map data. I’ll go into it in more detail below but this is of limited use as each map is built to work with a particular version of the ECU firmware, of which there are many. This tool allows the full firmware and map to be transferred between ECUs, meaning you don’t have to worry about compatibility. And Galletto doesn’t cross-check the firmware version compatibility (mine does) so lets you flash incompatible maps (mine doesn’t) … and it often doesn’t seem to be able to recover the ECU if you do, leaving it bricked.
 
Instructions
 
Basic instructions for using the software are as follows:
 
INSTALLING THE FTDI CABLE
 
1. Follow any instructions that come with the cable to install the appropriate drivers on your system.
 
READING FROM AN ECU
 
1. Connect to the ECU. WARNING: Do not turn on the ignition yet! Plug the FTDI cable into the OBDII port on the car and into a USB port on the laptop. The ECU seems to check whether there’s anything connected when it powers on and if not, after that it refuses to talk. So it’s important to get everything connected first. If not, you will need to either turn the ignition off for something like 10 minutes to allow the ECU to fully power down, briefly disconnect the smaller of the two ECU plugs to interrupt the power and force a reset, or briefly pull the 30A ECU fuse from the fuse box.
 
2. Run the MEMS3 Flasher Application
 
You should see a window like this:
 
image004.png.836d50f116fc740ff8035a0a2df58c21.png
 
In the top right hand corner there’s a combo box that should say “FTDI Device 0”. If you have more than one device plugged into your laptop that uses the FTDI chipset you may have more than one device listed here and you’ll have to find which one is your FTDI cable, but chances are there will only be one. If this box is blank and a lot of the buttons are disabled, it hasn’t found your FTDI cable - make sure you have installed it correctly.
 
3. Turn On the Ignition.
 
4. Check Your Connection. Click the About button. The application will connect to the ECU and display the VIN, Part Number, Part Variant, Firmware ID and Map ID as shown below. If it doesn’t work first time, try turning the ignition off and on again and then repeating. The ECU can be a bit temperamental sometimes!
 
image005.png.429b343d4812a9c2ebec7933a5a2572a.png
 
5. Read the ECU. Click the Read button. You should be presented with a dialog like the one shown below:
 
image006.png.6d98ceb94f7e49a0f9c1225f1bb690e5.png
 
You can choose to read the full firmware (contains the operating software of the ECU), coding (contains the VIN and Part Variant) and the map (contains the various tables with the configuration parameters for the engine) or just the map. If you only read the map, you will be able to write this back to any ECU with the same firmware version only. If you read the firmware and map, you will be able to write this back to any compatible ECU. Due to the fairly low serial data speeds used by the protocols supported by the ECU, reading the map alone takes about 22 seconds and performing a full read of the ECU takes about 4 minutes 19 seconds.
 
image007_0.png.f6dfc03e088d757492beacd19ddf6e52.png
 
Once the read is complete the system displays a dialog confirming the VIN, Part Variant, Firmware ID (if these were read) and Map ID for the data in the internal buffer. These should match the data originally displayed for the ECU. The messages are all protected by checksums and the protocols I have implemented include several layers of error checking and recovery so the data should match in every case. If the transfer is interrupted, you should see that the Resume button becomes enabled. This will allow you to resume and complete the read, even if the ECU has been shut down in the meantime.
 
image008.png.4e7bd26d1650068ec79a39f19dc6cdd4.png
 
After reading the ECU, the internal buffer data is displayed in hexadecimal form as show below.
 
 image009.png.55545b803eee2c8a9fef3e13421d6ac2.png
 
6. Save the Data to a File. You don't have to save it to a file before writing it back to another ECU but it makes sense to save a copy. Click the Save button. You will be prompted for a file name to save the data as a .BIN file (raw binary data). There are several file formats supported but the default "MEMS3 Flasher 192KB" file format should be fine. The different file formats are discussed further below.
 
image010.png.d6baa4e302b5fbf5f9ae44fd134a6b7c.png
 
WRITING TO AN ECU
 
1. Open a File. If you are moving straight on to writing to a new ECU, you can skip this step. However if you return to it at a later data, connect to the ECU, run the MEMS3 Flasher application, turn on the ignition and check your connection exactly as described in instruction (1) to (4) previously, then click the Open button and select the file you saved previously.
 
2. Write the ECU. This is very similar to reading an ECU. Click the Write button. You should be presented with a dialog like the one shown below. Again you can choose to write the full firmware and map or just the map alone. If you choose to write just the map, the application will check the firmware in the ECU to make sure it is the same version as the one the map is compiled for and will refuse to write an incompatible map to the ECU.
 
image011.png.a1702e6a83994d1122b9953a335c9810.png
 
There are a few extra options when writing:
 
a) Clear Adaptations. This will clear any fueling adaptations in the ECU, as they may not be appropriate with a modified map. The ECU will readapt over a couple of hundred miles of mixed driving. During this time the emissions and fuel economy may not be as good as they normally are as the fueling may be slightly incorrect.
 
b) Automatically verify ECU on successful write. This will cause the application to perform a read of the ECU once the data has been written, to confirm that the data now in the ECU matches that in the buffer. This is a bit of a "belt and braces" solution as the ECU appears to verify internally that each block is written correctly as received and the communications use checksums to allow the ECU to confirm that each message received is as it was sent, so other than for failures of the software or very unlucky corruptions that leave the checksums unchanged, the data transfer should be reliable. For peace of mind though, I normally verify after writing.
 
c) Clear diagnostic information. This option only applies when writing the firmware. Because I can't be sure that the format used for storing information in the working non-volatile memory of the ECU is identical or compatible between firmware versions, by default the application clears any diagnostic information. The ECU will then continue to log new diagnostic information for any current faults.
 
d) Learn immobiliser code. Again this only applies when writing the firmware. Again, as I cannot guarantee that the format used for storing the immobiliser code will always be compatible between firmware versions, by default the application clears the immobiliser coding and tells the ECU to re-learn it from the immobiliser. The ECU will then be free-running initially but the first time it sees the immobiliser disarmed it will learn the code and again be paired with that immobiliser.
Due to the fairly low serial data speeds used by the protocols supported by the ECU, writing the map alone takes about 24 seconds to write and 22 second to verify, so 46 seconds in total. Performing a full write of the ECU takes about 3 minutes 44 seconds to write and 4 minutes 19 seconds to verify, so just over 8 minutes in total. The ECU will reboot at the end of the write, you will hear the fuel pump priming as though the car ignition was just turned on.
 
image012.png.acae590782a510ac2444cd07a555f0fe.png
 
Try not to interrupt the process of writing the ECU as there is the possibility that the ECU may be left in a state where it cannot communicate and cannot be recovered. This is quite unlikely, but see the section on Robustness & Risks below. Once the write has started it is best not to touch anything and just allow it to complete. As for reading, if the transfer is interrupted, you should see that the Resume button becomes enabled. This will allow you to resume and complete the write in most cases.
 
License & Warranty
 
I’ve decided to release the executable into the public domain. Feel free to copy it, share it use, distribute it, give it to your mates, do what you want with it. You can even sell copies if you can find somebody daft enough to pay for something that I’m giving out free! I just want it out there as a tool that people can use if they need it. I think it’s pretty robust but it’s probably not perfect, feel free to let me know if you find anything wrong, there’s an email link in the top right hand corner. I’ll try to fix things that get found and keep it maintained but I’m not offering any kind of warranty or guaranteed service level though. This has been and will always be a side project for me.
 
Source Code
 
The application is developed in Delphi 10.3, Community Edition. At the moment I’m not releasing the full source code but if anyone really wants to know how it works and has a need for parts of the code I’ll happily share.
 
On Bench or In Car?
 
The application has been written to allow the ECU to be reflashed in the car through the OBDII port. You could also use a simple bench testing harness such as the one I described here: https://www.lotus7.club/forum/techtalk/building-key-programming-ecu-immobiliser-testing-interface-k-series. Doing it in the car is the easiest and means that you don’t need to buy or build expensive hardware. It also pretty much guarantees a reliable power supply.
 
I’ve done most of my development work on the bench then tested on my car.
 
If you do choose to reflash the ECU in the car, there are a couple of precautions I would recommend taking. Most of the time it all goes to plan first time, but if the writing process does get interrupted or fails for any reason it will leave the ECU in a non-running state. This can normally be recovered by just flashing again, but in the meantime the ECU can behave very oddly; when plugged into my harness it’s not uncommon to see a corrupted ECU permanently turn on both the fuel pump and one injector. On the car, this would be very bad as it would pump the contents of the fuel pump straight into your inlet ports and end up risking a hydraulic lock, damaging the engine.
 
As a simple precaution to avoid this, I would recommend that you disable the fuel pump (e.g. by unplugging the inertia switch), disable the injectors (by unplugging the big connector to the injector sub loom under the throttle body) or probably both.
 
Having said that, I’ve not usually bothered when flashing maps onto my car and I’ve not had any problems so far!
 
File Formats
 
The MEMS3 flasher loads and saves binary files with .BIN extensions. It supports a number of different types of binary files and it recognises the type of file from the file size.
 
The following types are supported:
  • Flasher Files - 196,606 Bytes (192kB - 2 unreadable bytes) - These are the native file format for the application and contain the full firmware and map.
  • Firmware Files - 172,032 Bytes (168kB) - These contain only the firmware with no map.
  • Map Files - 16,382 Bytes (16kB - 2 unreadable bytes) - These contain only the map.
  • EEPROM Files - 262,144 Bytes - These contain the full boot loader, firmware and map. They are files obtained by reading the EEPROM chip on an EEPROM read off the board as I did in my original article. Because of the way the microcontroller addresses 16-bit memory, each pair of bytes in this kind of file is exchanged.
In normal use, you would probably only need to use the normal Flasher files. See the section on the Memory Map below for more information about the memory areas covered by these file formats.
 
Hardware Compatibility
 
There is no check on whether the firmware you are flashing is compatible with the actual ECU you’re flashing it to. The firmwares don’t seem to contain hardware part numbers to cross-check. I guess that’s something that was managed by Rover’s TestBook system originally.
 
MEMS3 is a modular architecture (that’s what the first “M” stands for). This means the basic core ECU is common across a wide range of models, but ECUs with different part numbers either do or don’t have a number of additional hardware and software modules installed. For example, looking the circuit boards, there are chips that are only present in VVC ECUs and there are other chips such as a CAN controller which are only present in ECUs for use with automatic gearboxes.
 
Each ECU has a part number starting with NNN… and a part variant starting with NNW… 
 
I think the NNN code relates to the physical hardware and the NNW to the firmware installed. From all the testing I’ve done, you should be safe to copy between ECUs with the same NNN number. In actual fact there is more flexibility than this; for example the early MGF Trophy 160 ECU NNN000100 and the later MG TF 160 ECU NNN000160 look to be identical hardware to me, and I’ve had no problems copying firmware and maps between them. But if you stick using ECUs with the same NNN part number you should be safe.
 
I’ve played with what happens if you flash incompatible firmware on an ECU. I flashed VVC 160 firmware and maps onto a Freelander ECU just to see what happened. The answer is that it worked surprisingly well! Nothing horrible happened, the engine VVC engine started and ran fairly normally, it probably wouldn’t have run the engine very well under load as the map would have been wrong and it wouldn’t have controlled the VVC solenoids, it logged a few faults with the VVC system (which was missing!) but other than that it ran the ignition and injection happily enough and more to the point, it was still happy to communicate so I was able to just flash the original Freelander firmware and map back on and it was all happy again.
 
Robustness & Risks
 
Whilst developing this, I built myself a couple of heavily modified test-mule ECUs. One of the things I did was to replace the main EEPROM memory chip with a socket, so I could plug the chip in and out easily. It was a bit fiddly and I had to carefully trim the sockets to fit around some small surface mount components close to the chip but it worked well.
 
image013.png.2362d6930cb9ed2da844a26ee2363e9c.png     image014.png.34262f1854571324ab582fb1c67582c7.png
   
This allowed me to look on the PC what I was actually doing to the memory contents, but the main idea was that if and when something went wrong and I “bricked” the ECU (i.e. got it so messed up that it would no longer communicate well enough to allow me to put it back again) I could easily reprogram it on the EEPROM programmer.
 
In the whole time I have been developing this, during which I must have flashed eight or nine different ECUs of various types a hundred times or more, I have to say I only bricked on once, and that was when I was first writing the code that allowed writing to recover after being cancelled or experiencing an error; I mistakenly carried on writing the data from where it left off but started again at the beginning of the EEPROM chip, which obviously just made a complete mess.
 
Other than this one case, every time anything has gone wrong (and I did a lot of testing of making things go wrong deliberately to test my recovery routines) I was able to just flash it again and all was well.
 
I would make sure your ECU has a good reliable power supply (if flashing it in the car through the OBDII port just make sure the battery is reasonably well charged, and the same goes for the laptop running the process) and avoid interrupting it whilst writing. Don’t cancel it, don’t disconnect it, don’t try to start the car - just leave it to do its thing and it should be fine.
 
It’s only the same principle as not powering off a mobile phone while it installs a software update and not rebooting your PC in the middle of installing Windows updates.
I wouldn’t like to absolutely guarantee you won’t mess up the ECU and I wouldn’t want to take responsibility if you did, it’s your choice if you want to use it, but I’ll happily use this on my car and I’m pretty confident that it will work reliably. As basic Rover ECUs are now quite cheap second hand, I would suggest maybe keeping your original ECU as it is and flashing a spare.
 
I’ve built multiple layers of error recovery into the software. If the ECU rejects any messages or sends inappropriate or corrupted responses (which can be caused by noise pickup on the power supply or communication lines) the software repeats the message or takes other recovery action as necessary. If the ECU stops responding altogether it attempts to reboot it and continue. Even if it gets into a state where you need to power the ECU off and on again to get it talking again, you should just be able to hit the “Resume” button and it will pick up where it left off, whether reading or writing.
 
NB: Turning off the ignition may not be enough to power off the ECU. Normally the ECU continues to run for some minutes after the ignition is turned off. In a Rover it would be monitoring engine bay temperatures and running the fans. If the ECU functionality is compromised, it may even continue to run indefinitely. If you want to be sure to power the ECU off fully, either pull the 30A ECU fuse for a couple of seconds or briefly remove the smaller of the two connectors from the ECU by sliding the lock outwards.
 
For some reason the ECU is quite flaky whilst reading data, every now and again it seems to just ignore a message or respond with complete gibberish. My code works around all of this the vast majority of the time and from the user end you wouldn’t know it was happening (there’s a little red “Retry” icon at the bottom of the screen that flashes each time it has to recover from an error just to give an idea of when it’s having problems, but that’s all you see). Luckily it seems to be rock solid whilst writing. I’m not 100% sure why, I think some of it is because in a programming diagnostic session it drops back into the boot loader code and isn’t trying to run engine management at the same time (more information below). One way or another, the good news is that whilst actually making changes to the memory contents it really does seem to be robust and reliable and everything goes to plan if it isn’t externally interrupted.
 
Errors, Cancel & Resume
 
Whenever it is working on a long running process, such as reading from or writing to the ECU, there’s a “Cancel” button enabled. You can click this to cancel the operation. As mentioned above, I really wouldn’t cancel a write part way through unless there was an emergency, it will leave the ECU in a non-running state and there’s a small risk of it being too unhappy to be recoverable. Cancelling a read or verify at any time is fine. And any time you cancel a read, write or verify there’s a “Resume” button enabled which allows you to pick up where you left off. This is robust an reliable, even if the ECU has been shut down or rebooted in the meantime. The “Resume” button will also pick up an operation that stopped because of an error. So for example if the ECU just stopped responding half way through a long read, you can reset it and resume without starting again.
 
Supply Voltage
 
Sites on the Internet seem to suggest that you should never try to reflash any ECU at anything other than 13.5V. This obviously precludes flashing the ECU in the car, as you can’t do it with the engine running and the battery voltage alone will be well below that. The memory chip itself needs 12V on some pins whilst flashing, I’m not sure if this is internally generated or whether it just uses the external supply, but I’ve tested flashing ECUs with supply voltages from 10.8V to 14.0V and it was fine. If you’re flashing it in the car, so long as the battery is reasonably healthy it should be happy.
 
OK SO THAT’S ABOUT AS FAR AS YOU NEED TO GO IF YOU JUST WANT TO USE THE TOOL, THE REST IS THE GEEKY BIT ABOUT HOW IT ALL WORKS INSIDE!
 
Cracking this has been an interesting challenge for me, to say the least. It’s been a slow process of unpicking a web of connections. Usually cracking one part leads to further understanding which unlocks the next part.
 
There’s no specific documentation of MEMS3 that I could find. To some extent it does adhere to common standards, but not fully. It’s all the places where it deviates from any common standard or where there is no standard which proved most challenging.
 
I’ve had to work all of these things out from first principles and intuition. The information below is based on my own research and is correct to the best of my knowledge, but I’m just finding my own way through things so it may or may not be absolutely accurate. I've will probably have used different terminology and described things from a different perspective to that of people who may have been involved with MG Rover development. I haven’t covered all of the details or this would turn into a very long read, just some of the more interesting key points.
 
A lot of the development work has proceeded by making working hypotheses and then testing these on ECUs. I many cases they have proved to be misunderstandings and some of my current state of understanding may not be absolutely correct but it has formed the basis of a working model of the ECU which has allowed me to achieve my current objectives.
 
Some of the methods I've used include:
  • Sniffing protocols. I've used various different techniques to sniff the messages sent between other tools and the ECU.
  • Disassembling ROM code. I've disassembled code inside the ECU EEPROM and code in other tools which were able to talk to the ECU to find out how things were done. In particular this was necessary in cracking the seed-key security mechanism. See the Seed Key Algorithm section  below.
  • Modified development ECUs. I added various features into a number of ECUs including socketed EEPROM chips and multi-protocol data loggers to record the communications with the ECU under various different conditions. I used data loggers based on the SparkFun OpenLog device but I rewrote some very specific Arduino code for them to allow them to log a lot of details of the ECU communications, timing etc.

image015.thumb.png.f1aff3e01d33d6fc8563ce9bd50b67d3.png

  • MEMS3 Terminal. Along the way I developed my own terminal application which was capable of interception, logging and decoding communications with the ECU. This was also capable of reading and decoding the log files from the development ECUs described above. It also allowed me to key in messages and talk to the ECU directly.

image017.png.453095ded2ed8888783e1e9b33be9c8e.png

  • Modified FTD2XX.dll. A lot of tools which are capable of communicating with the ECU use hardware based on the FTDI chipset (as does my application). As these are always compiled Windows executables it's very hard to see what they are doing internally. But I found that the FTDI driver DLL was a convenient weak point to attack. Basically I wrote my own version of the DLL. It didn't do a lot, it just declared all of the same functions as the original DLL, loaded the original DLL in the background and passed all of the function calls straight through. But that meant that I was able to add code to any of my wrapper function to log calls and results. I was also able to add an inter-process communication pipeline to the terminal program described above, meaning that all communications with any FTDI devices system-wide would be reported to and decoded by the terminal in real time. It even allowed me to intercept specific calls and modify them. But the most interesting thing it did was to allow me to load any other tool which could communicate with the ECU in my debugger (by debugging the DLL, with the tool I wanted to debug set as the host process). This meant I could set breakpoints on calls and then work through what it was doing at the time, what it would do with the value returned etc.
Protocols
 
The communication protocols used by the ECU are very similar to a number of standard but it doesn't seem to adhere to any of the strictly. I seems to support at least three different protocols.
 
1. ISO 9141-2. This is mostly used for communications with OBDII scanners. It operates at a speed of 10400 baud with a specific "slow-initialisation" signal used to start communications.
2. A native protocol which uses a lot of KWP2000-type messages but a different addressing scheme. This operates at a speed of 9600 baud. It has similarities with protocols used by BMW at the time. There is no particular out-of-band initialisation signal. My guess is this is the protocol primarily used for commination with the Rover Testbook suite of internal diagnostic tools. I have referred to it as "Rover BMW 9600 Baud" in my application. When the ECU first boots up, in the absence of any special initialisation signal, this is the protocol it uses.
3. ISO 14230-2 / KWP2000. This protocol seems to adhere more closely to the standards. It operates at a speed of 10400 baud with "fast-initialisation" signal used to start communications. Once the ECU has received the initialisation signal for this protocol, there is no way to switch back to the native protocol other than resetting the ECU.
In practice I found that either the native protocol or ISO 14230-2 worked well for reading or writing. The ECU seemed to support all required operation under both protocols both when running the firmware code or when dropped back into the boot loader. The usual ISO 9141-2 however seemed less reliable and I had some difficulty generating an acceptable "slow initialisation" signal over the FTDI cable. Despite using bit-blatting techniques and confirming with an oscilloscope that the signal and start of communications seemed to be exactly the same as those generated by OBDII scanner, it seemed to be unreliable and the signal was often not recognised. Once I realised that the ECU supported everything I needed in either of the other two protocols I decided not to waste any more effort in ISO 9141-2, which is no longer supported by my tool.
 
Memory Map
 
MEMS3 uses a 29F200 EEPROM chip. Specifically it uses an AMD AM29F200BT-90SE variant. This is mapped into externally accessible address space (as seen by OBDII) at base address $100000, meaning that the different sectors of the EEPROM appear at the addresses shown below.
 
SectorSizeAddressUsed For
SA064KB$100000 - $10FFFFBoot Loader
SA164KB$110000 - $11FFFFFirmware
SA264KB$120000 - $12FFFF 
SA332KB$130000 - $137FFF 
SA48KB$138000 - $139FFF 
SA58KB$13A000 - $13BFFFCoding
SA616KB$13C000 - $13FFFFMap

Each sector of the EEPROM can only be erased as a whole. Without erase a sector (which sets every byte to $FF or binary 11111111, logical 1's can only be programmed to logical 0's and not the other way around, so it is not really possible to write arbitrary data to a sector without erasing the data in the area to be written first, and this means erasing the whole sector. Interestingly the "BT" in the chip designation means "Boot Block at Top" - so the small 16KB sector SA6 at the top of memory is intended to hold boot loader code, which would be a small application whose sole job is to communicate with some external tool to allow the contents of the rest of the EEPROM to be loaded. In MEMS3, this sector SA6 is used for the map data which it relatively small and the bottom 64KB sector SA0 is used to the boot loader code. The next 4 sectors SA-SA4, 64KB + 64KB + 32KB + 8KB = 168KB are used for the firmware code. The next 8KB sector SA5 is used for what I have called Coding - this basically includes the VIN code and the Part Variant. Of the 8KB available this sector, only 14 bytes (VIN) plus 6 bytes (Part Variant) appear to be used.

As far as I can tell the ECU only provides routines to erase the firmware and map sectors. So the boot loader code is permanent and cannot be changed without corrupting it. This makes sense as the boot loader code is what is executing when loading firmware or map data; overwriting the boot loader while it was running would not make sense. The same is true of the Coding data, so it is not possible to write a new VIN code or Part Variant code to the ECU. This is probably for security, the original VIN number being indelibly written to the ECU. The other possibility of course is just that I haven't been able to track down the routines to erase the coding data. This doesn't seem to be a significant restriction, as any version of the boot loader seems to work happily with my tool and will load any firmware version. The boot loader code isn't involved in running the engine at all, so once the firmware has been loaded and is running the older boot loader is irrelevant, and the VIN and Part Variant code are informational only.
 
The boot loader version on an ECU seems to be consistent across ECUs with the same part number. So for example an early VVC ECU NNN000100 will always have boot loader version BOOTP030 and a later VVC ECU NNN000160 will always have boot loader version BOOTP033.
 
Runtime & Adaptations
 
Runtime data such as DTCs, adaptations and immobiliser coding are stored in a separate 93C66 serial EEPROM chip. This doesn't appear to be externally addressable; it doesn't appear as memory addresses mapped into the memory space accessible to OBDII commands. I believe data here will be read and written using higher level OBDII commands used to request diagnostic information, or to request or set data by local identifiers. I haven't been able to track all of these down, but I have managed to provide workarounds which seem to be perfectly adequate. So for example when writing a new map I clear the existing adaptation and when writing new firmware I clear the immobiliser coding and allow the ECU to re-learn the code from the immobiliser. I haven't had any issues using these workarounds in testing.
 
Checksums
 
The firmware and map areas of the EEPROM are protected by checksums. This allows the ECU to verify that any data loaded has not been corrupted during transfer. It also prevents anyone who doesn’t know the checksum algorithm from being able to modify the data.
 
The idea is that some mathematical operation is performed across all the bytes in the area covered by the checksum to give a number, which is then stored in the data. The ECU is then able to perform the same mathematical operation on the data in its memory and compare the number it gets to the number stored. If they are the same, the data is assumed to be unmodified. If they ae not the same, the data must have been modified and is rejected.
 
Checksums are traditionally added to the end of a data block, so the first place I looked was the last two bytes of each block, but in each case these just contained $FF, $FF indicating unused space at the end of the block.
 
I tried various different checksum algorithms but nothing matched; the main issue I had was working out which bytes in the data were the checksum. Then I tried just adding up all of the numbers in the block, first as 8-bit bytes and then as 16-bit words, and a pattern emerged across the ECUs. For any given block (i.e. firmware or map), the answer was the same in every ECU I looked at.
 
So far example, for the firmware area, the 16-bit sum of the 86,016 16-bit words (high byte first) at hexadecimal addresses $110000/1 to $139FFE/F is always equal to $04FB. 
 
This gave me the checksum algorithm. Somewhere in the block there are two checksum bytes which get to $04FB minus the sum of all of the other pairs of bytes. There’s no way to work out which two bytes, as if you think about it EVERY pair of bytes will be equal to $04FB minus the sum of all of the others. But it doesn’t matter, because I’m also free to adjust any two bytes I chose. At the end of each block there is a large amount of unused space as the contents of the blocks are quite a lot smaller than the EEPROM segments allocated to them. So I can rely on the fact that the last few bytes of the block will be unused and safely replace two of the with $04FB minus the sum of all of the others and the rule will be satisfied.
 
I’ve tried modifying data and correcting the checksums in this way and the ECU happily accepts the new firmwares and maps.
My application now checks the checksums for the firmware and map on loading a file, saving a file or writing to the ECU and offers to correct them automatically if they are incorrect. On writing to the ECU it checks them, offers to correct them and refuses to write to the ECU if they are not corrected, as the ECU would not run with incorrect checksums.
 
Seed Key Algorithm
 
The ECU is protected by a seed key security system. When you want to gain security access, the ECU gives you a 16-bit number called the seed. You have to perform a (secret) operation on this to work out the corresponding key, and give that back to the ECU. The idea is that only Rover know the details of the operation to be performed and, like a good hash function, the output numbers give very little clue as to the calculation. So you can’t for example record a programming session and make a note of the key used, because next time the seed will be different and an entirely different key will be required.
 
To work this out I had to reverse engineer it by disassembling machine code routines in the ROM and in other programming tools.
 
As MG Rover are now long gone, I don’t have any moral qualms about publishing the seed key algorithm that I discovered, without which you cannot unlock and maintain our ECUs. Here it is in full, written in Pascal (I used Delphi for the development of the application which is Pascal based). You could code it in any language you like. It takes a 16-bit seed and returns the corresponding  16-bit key:
 
 
 
 
Boot Mode, Diagnostic Sessions
 
One thing which originally puzzled me was how to get the ECU into boot mode to allow the firmware to be overwritten. I was originally assuming that there was some combination of voltages applied to pins when booting which caused the ECU to enter boot mode and run the boot loader code rather than the main firmware, but in the end the answer was a lot more simple and convenient; there are a number of different "Diagnostic Session" types that you can request, and combined with the right security privileges, requesting a programming diagnostic session exits the firmware and runs the ECU in the boot loader code. You can recognise that the ECU is in boot mode because although communications with the ECU remain normal, none of the engine management functions are running. the fuel pump doesn’t prime, the IACV doesn't chatter as it usually does and the engine will not run.
 
Routines
 
The ECU has number of pre-defined routines in EEPROM that you can execute with a command to "start routine by local ID". Some of these routines execute quickly and return a positive or negative result almost immediately. Some of them however execute for several seconds, such as the main firmware EEPROM erase routine. These return a pending result immediately and a further positive or negative result on completion. Figuring out the IDs and parameters required for these routines was one of the challenges of cracking this.
 
Maps
 
The upper 16KB sector of the EEPROM contains the tune file or map. This consists largely of a number of tables. These are generally referred to as 2D or 3D tables, although more correctly these are 1D or 2D arrays of numbers (the third dimension being the axis on which the actual table numbers are plotted on a 2D line or 3D surface chart). Even for the same firmware version, the addresses of the maps in memory vary between different ECUs and map files. The main firmware locates each table by looking up the address in a master table index. This master table index varies in address in different firmware versions and I can't find any kind of "index of indexes" that points to it, so my guess is the index address is just a constant baked into the firmware code at compile time. The index however easily located as it sits alone above everything else towards the top of the map file address space, so any block of valid table addresses which follows an unused block of $FF space will be the master table index.
 
Most of the rest of the map space consists of tables in the same format, stacked one after another with no gaps between them. Oddly however not all of these tables are pointed to by the master index. Most of the unindexed tables seem to contain junk data such all zeros. My guess is that these tables are not used by the firmware as it has no way to address them directly (it could be that there are a number of tables used as a set, which always follow each other in memory, and so the ECU only needs to be able to index the first one and then walk along them as there are no gaps, but I doubt it looking at the contents of the unindexed tables. Quite why the unused tables are still there but not indexed I have no idea, it must be a quirk of the original map compiler used by Rover.
 
Future Plans
 
I'd like to build up a library of Caterham maps, especially the "special editions" such as Supersport ECUs. This would allow any of these ECUs to be recreated using stock cheap MEMS3 ECUs off eBay. I would backup complete firmwares in the library as I believe this would also cover any special cases where the firmware may have been specifically modified, such as they code in a Supersport ECU which repurposes the air conditioning clutch output as a shift light.
 
My ultimate goal is to make the MEMS3 ECU properly remappable. To be honest, by the time I've got round to writing this up I've pretty much already done it. I've already got full control of the target AFRs, open/closed loop control, fueling adjustments, ignition timing, overrun pop and crackly, idle air control valve and rev limiter. On VVC engines I've also got control of the VVC mechanism sorted. I think I've pretty much covered all of the key parameters you would want to adjust when remapping the ECU for a modified engine.
 
I've already been able to adjust all of these parameters consistently and flash the modified maps back to my car with the expected results (rev limited to 3K it did feel a bit sad!).
 
The mapping application is a lot more comprehensive, complicated and flexible but is built on top of the flasher tool described in this post. I'm still working on tracking down more parameters and I need to put some finishing polishing touches to my remap application and there will be another write-up soon, but here's a teaser ...
 
image018.thumb.png.043f871c02d7cfad260ce16c6039ef3d.png
Link to comment
Share on other sites

Yes the EU2 ECU is quite different, certainly in at least two key aspects as far as I understand: 1) It doesn't support OBDII protocols, only Rover proprietary protocols. 2) The internal memory chip used is non-reprogrammable. Not sure if it's just one time programmable or mask programmed at the factory but it can't be erased and re-written. I saw recently that SAWS Tuning (you can find them on Google) are offering remaps for EU2 ECUs. My understanding is that their methods are more akin to what I did in my first article, link to in this post - removing the chip from the board and replacing it with one programmed with a different map. I think that's the only way to go with those ECUs.
Link to comment
Share on other sites

Great piece of work.

Does this mean a soft tune up could be fairly easily applied by a DIYer? A sort of Kmaps lite that disabled anything to do with aircon, power steering etc. and improved things a bit but without screwing up the emissions. I'm not meaning a full Kmaps copy just a few easy wins.

Link to comment
Share on other sites

Yes, that's the idea. 

To be honest, things like aircon and power steering tables would be pretty hard to track down. You don't get any kind of key to the tables, just the numbers. There are a lot of clues as to what a lot of the axes and data values are, for example:

  • Temperatures all look like 2732, 2932, 3132 (they're actually round numbers in tenths of a degree Kelvin! - 0C, 20C, 40C).
  • MAPs are usually scaled to 10,000 at the top (divide the numbers by 100 and you've got kPA).
  • RPMs are usually scaled to around 7000 at the top and there's nearly always an axis point for 825, standard hot idle.

etc.

I've track most of the tables down by looking at them and thinking what they can be, then I've been ruthlessly experimenting on my own car changing things and watching the effects. I've flashed maps that were completely screwy just to prove points, for example changing the idle speed to 2000rpm in a very narrow RPM band and watching the engine as it warmed up, sure enough the revs jumped up and dropped back at the temperatures I'd set.

For the aircon and power steering effects I think you would struggle to know what to look for and how to see if you had found them.

To be honest I think they are a very small part of sharpening it up overall. The biggest effect I've found it what seems to be a deliberate attempt to limit the throttle response, to smooth out the drive. When you open the throttle rapidly the ignition retards way beyond the correct timing for the new throttle position, then slowly advances back again. Taking this effect out makes a world of difference. I've found the tables that control it and you can just fill them with zeros.

To track that one down I used the crank and cam sensor simulator that I developed and wrote up on here for use with immobiliser matching - it was originally designed to provide a steady 960rpm simulation to test immobilisation. With that plugged into the engine harness instead of the real sensors I can fool the ECU into running the engine without the engine actually turning (I also disconnected the fuel pump!). So that allowed me to play with the throttle and watch the engine response without revving it to bits. Even at 960rpm the effect is clearly visible. I used a dual channel oscilloscope triggered off the cam signal to get a stable timing point and also showing the ignition pulses so I could watch the advance and retard.

This is what it looked like just ticking over. The green line is the cam signal. The yellow line is the ignition with the sharp vertical being the start of the spark. The noise pulses on the cam signal were just pickup from a cheap and nasty switch-mode power supply I was using:

SteadyClosedThrottle(Rover).thumb.png.7321741938030eccf87dbfcf09558a83.png

This is what happened as I advanced the throttle rapidly. As you can see a big retard on the ignition here:

RapidRateThrottleOpening(Rover).thumb.png.4ab0a4399193e031e480b070de2af166.png

And this is what happened when I held the throttle open steadily. You can see that throttle advanced back to the correct value for the point in the map (which is still fairly retarded because I'm giving it full throttle at only 960rpm here):

SteadyOpenThrottle(Rover).thumb.png.b8e91c68d433e3ca54e8cb9330d201d8.png

That's an extra 1.4ms of retard which at 960rpm is an extra 8 degrees of ignition retard. With those tables zeroed out, the ignition just snapped straight to the correct mapped point with no additional retard.

This effect seems to be present in MPi and VVC ECUs across the board, but there's more variation than I expected between the way many of these things are controlled between different ECUs and even different firmware releases of say the VVC 160 ECU, so I want to spend some more time understanding other ECUs before I publish the full mapping software.

It is up and running and working very nicely already though.

Here are the tables that control the above effect in my VVC 160 NNN000160 ECU (firmware KSR3P004):

This one modulates the effect by MAP and RPM:

Map1.thumb.png.db2dc8f038915a80a08d6c2309b96e70.png

And this one modulates the effect by coolant temperature:

Map2.thumb.png.d6c0fe3f9dc32a0e56dca5ef95031695.png

 

 

Link to comment
Share on other sites

I'm still working on polishing off the mapping tool. In the process I've rewritten the low level link to the ECU so that all of the suite of tools I've developed are no longer dependent upon the FTDI chipset.

All of the tools will now work with any FTDI device and with any OBDII K-Line cable that installs into Windows as a serial port (such as COM9). All of tools now have an extra combo box at the top to select the connection type:

ComPort.png.7e47089f136c1511597860777ab89bad.png

I purchased one of these https://www.ebay.co.uk/itm/USB-VAG-COM-Cable-OBD2-II-OBD-Diagnostic-Scanner-KKL-409-1-Audi-VW-Skoda-Seat-UK/264586876655?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

s-l1600.jpg

It turned out not to be FTDI based, but installs as COM9 on my laptop. The driver shows it as a QinHeng chipset. The new version now works fine with it. If I plug in my original FTDI cable, it shows up as both "FTDI Device 0" and "COM3" and allows me to talk to it as either.

Anything advertised as a VAG-COM, KKL or 409.1 cable should be fine.

Cables to avoid are those that claim to contain an ELM327 (or more likely a Chinese clone). The ELM327 chip is a completely different animal, it's a full high level OBDII interface that speaks many OBDII protocols to the car and a simple standard protocol to OBDII tools on the other side. What we need here is basically just a straight-through serial port operating at 12V levels.

Link to comment
Share on other sites

  • 2 weeks later...

I am absolutely speechless and deeply impressed by this outstanding work!

This is another motivation for me to upgrade my 1999 MEMS2 VVC to a MEMS3 :-)

Thanks a lot for sharing!

 

Regards

Dirk

Link to comment
Share on other sites

I will get my full mapping application written up and published in here as soon as I can. I'm just adding in some better support for some of the scalar (non-table) data that covers things like fan control and rev limit in MPI ECUs at the moment.
Link to comment
Share on other sites

No at the moment I haven't built that into it, it's just for manipulating the firmware and map. Once that's all working and done and I need another project I may build OBDII scanner features into it to make an "all-in-one" MEMS3 tool. I have put in the feature to clear existing DTCs and diagnostic info just in case the format used for storing them differs between firmware versions, but it doesn't seem like it does much.

a.thumb.png.87a21474e19a351372054ab28ccccbf2.png

b_0.thumb.png.0be94bd47fd30b507c67716e337a9831.png

c_0.thumb.png.bb3c3f9a0471c3bcf6926e6b4d35a5ca.png

d_0.thumb.png.4abe8fa3eb2816ecadc43e25d993ef79.png

Link to comment
Share on other sites

  • 2 weeks later...

While working towards the release of the full mapping suite, one thing that has been particularly bothering me was the small but still significant chance of somebody "bricking" their ECU with my software.

What could happen was this: When it started writing firmware or map to the ECU, it first had to erase the full EEPROM sector. If the write then got interrupted (by losing power, a bad connection, communications glitch or whatever), the ECU would be left in state where it would not communicate normally. The only solution would be to turn the ignition off and on again, at which point the ECU would try to execute the partially written firmware and would crash; this would lead to a reboot and it would got round and round in a loop, with the fuel pump switching on and off rapidly and no possibility to rescue.

The first thing I looked into extensively was a way of resurrecting a bricked ECU stuck in a boot loop. Because of the way in which Rover separated out and protected the boot loader firmware, I guessed that there was some signal to force the ECU to boot straight into the boot loader on startup and not try to execute the firmware. I tried every combination of sensible voltages applied to pins at boot up but I'm afraid I drew a blank. A good search of the internet didn't provide any hints that a bricked ECU could be forced into boot mode either. The general consensus on the internet is that once it is bricked, it's a big soldering job.

My next plan of attack was to connect TWO computers to my OBDII port, with a Y-splitter cable. You can do this with OBDII as its a passive pull-up line which each device pulling actively to ground, so if two devices talk at the same time you just get garbled data but no damage.

One computer was running my MEMS3 Flasher tool. The other was running my MEMS3 Terminal tool. This allowed me to watch the communications, and in particular it allowed me to pull the plug on the flashing tool and see from the ECU's perspective what this looked like. From this I could analyse what states it was possible for it to end up in, and my MEMS3 Terminal tool also allowed me to key in commands to the ECU (in hex) directly, so I could manually try out strategies to escape from the state it was in.

This had some success. The usual case was that the ECU had received a messages saying "here are 248 bytes of data" and so interpreted the next upt-to-248 bytes received as data to be written to EEPROM. So any commands you sent it were treated as data and swallowed until it has received the (unknown) number of bytes it was expecting. Once it had eaten as much data as it required, it would then only respond to a "Transfer Exit" command and nothing else. So one strategy was to continuously send Transfer Exit commands (6 bytes) until the requirement for data was satisfied we got some sort of response (up to 42 times), positive or negative, at which point the ECU was out of transfer mode and ready to respond again. However I discovered a bug in the ECU firmware; it seems to internally count commands requesting transfers and commands ending transfers, and that count seemed to be able to go below 0; so if you send one more Transfer Exit command than necessary, the next request to start a transfer got a positive response and you could got right through the transfer process, but at the end of it no data was written to EEPROM and the firmware or map was completely blank. It was all very hit-and-miss and still a loss of power to the ECU would leave it bricked; this escape relied on executing the escape commands successfully after initially losing connection.

All of this was done with an EEPROM programmer at the ready so I could resurrect my "socketed EEPROM" research ECU each time I bricked it.

However ... it did lead to a breakthrough. I noticed that when the firmware or map was completely blank, the ECU was not bricked; it seemed to understand this situation, knew that it had no firmware or map and didn't try to execute it, instead it booted into the boot loader and awaited programming commands. It appears to recognise this as a "factory new" condition in which it was ready for programming.

Now it made very little sense that the ECU would ready every byte in the firmware or map to determine whether it was preset and correct, this would just be a pointless exercise, so I set about working out what the ECU considered to be "firmware present" or "map present" and what it considered to be blank. And the answer was that it was only the first few bytes of each sector that it checked. So this gave me an idea ...

What if, when writing the data, one block (usually 248 bytes) at a time, I started with the SECOND block, skipping the first block, and only returned to write the FIRST block LAST? The idea being that if the transfer was interrupted before I returned to write the first block, the ECU would still consider itself to be blank and would be safe to restart, ready for writing again. If the transfer was interrupted during transmitting the first block, the ECU wouldn't get the full message and valid checksum so wouldn't commit the data to EEPROM and the same situation would exist. If the transfer was interrupted after transmitting the first block ... well flashing would already be complete so no problem. Each block was sent with a single message, so it was all-or-nothing.

I rewrote the writing code today and ... IT WORKS!

I've spent the whole afternoon deliberately trying to brick an ECU with code and I CAN'T!

It seems to be totally bomb-proof, both in theory and in practice. I've tried switching off the ignition, rebooting the laptop, pulling the USB plug out, pulling the OBDII plug out, disconnecting the battery etc. etc. in the middle of full firmware flashes and map flashes, and the in the worst case, all it needs is the ignition switching off and on again and it's ready to flash again.

I'm much happier with that. I wouldn't like to stake my life on its being absolutely impossible, but I really think it would take some special talent to brick or damage an ECU with my code now!

I've updated the link in the original post, but Release 3.66 with the new code is available here: https://drive.google.com/open?id=1PZSxQYZe9bbrbFYVD0ih2JXs1sG9-oJy

I'll keep working on the mapper and release it when I'm fully happy that all the wrinkles have been ironed out.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...