Remapping the Rover MEMS3 ECU

NOTE: THIS DOCUMENTATION IS UP TO DATE AS OF VERSION 4.68 RELEASE OF THE MEMS3 TOOLS APPLICATION SUITE.

After a lot of work, here (finally) is the first release of my efforts to provide a workable remapping system for the MEMS3 ECU.

When I wrote this article: http://andrewrevill.co.uk/MEMS3Flasher.htm on “Reading/Writing/Flashing the Rover MEMS3 ECU” I said at the end that a full mapping application was in development. This is it.

I present here a freely downloadable and shareable tool which allows the ECU to be remapped and enough information about the table and scalar data structures to allow the following features to be effectively reprogrammed:

 

Throughout all of this, please bear in mind that I've had no documentation or help on this from MG Rover, anyone previously associated with MG Rover or any of the well-known remappers. So what I present here is my own "working model" of the ECU, determined through inspection and experiment; MG Rover may well have defined things in completely different terms. I have formed a working model of my own which is sufficient to allow these features to be reprogrammed but which may not be aligned exactly with the way the ECU was originally designed and described. My model of the ECU may continue to evolve and develop as I gain more understanding.

The tool was developed initially as a research tool for me, and has been slowly evolved into a mapping tool that I can release publicly. When I set out on the adventure of developing all of this I had a lot less knowledge of the workings of the ECU, and the tool has evolved in parallel with my understanding. Because of this, some things may have been done differently if I knew at the start what I know now; but I think I’ve made a pretty decent job of keeping it clean, tidy, well-structured and fairly intuitive.

Note that throughout the definitions of tables and other values in the tool, some are marked with an “®” symbol. These denote “Research” and indicate that there are still some details which need to be tied down or validated. My descriptions of these items may not be entirely accurate yet in these cases.

 

My car has spent most of the winter hooked up to breakout cable bundles, programmers, signal generators, oscilloscopes and at times two different laptops, one running my mapping application and the other listening and monitoring through other cables.

License & Warranty

As for my MEMS3 Flasher tool 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. I just want it out there as a tool that people can use if they need it; the more we can spread the knowledge about these units around the K Series community the better as far as I’m concerned. 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.

 

Unlike with the MEMS3 Flasher tool, I’ve decided to add a PayPal Donate button at the top of the screen. It’s taken me over a year of my spare time to get to this stage. If you manage to get some value out of it and feel like showing your appreciation I’d be most grateful, but there’s no element of compulsion, the tool is free to use without restriction for as long as you want to use it.

Fail Safe Read & Write

Before diving into the details, I would just like to say that since releasing the previous MEMS3 Flasher tool I’ve put a lot of work into fail-safety. I voiced some concerns over possible risks of “bricking” an ECU if a write failed when I wrote up that tool. Since then, I’m pretty sure I’ve come up with a fail-safe write procedure which on paper and in practice should not run the risk of leaving the ECU in a “bricked” condition (provided that the map and firmware you are writing to it are valid and sensible - the ECU is not particularly fault-tolerant when it comes to corrupted maps etc.). Although I wouldn’t recommend it, you can now interrupt any process at any point and the ECU will be left in a condition where it will still boot up safely ready for you to repeat the operation. I have repeatedly tried to “brick” an ECU with the latest code by doing all of the following many times, at many different points in the process, both during full firmware write and map updates, without any problems:

 

With the latest code, none of these have been able to induce any serious issues at all. In the worst case (in fact in pretty much every case) you just need to turn the ignition off and on again to reset the ECU, then make sure everything is connected up again and repeat the write operation. The ECU will be left in a state where it won’t run the engine (until you repeat the write operation) but it will drop back into its boot loader code and communicate with the mapping application, waiting for programming instructions.

I have updated the latest release of the simpler MEMS3 Flasher tool to use the same underlying code so that is now also fail-safe.

The research required to get this write cost me many “bricked” ECUs along the way, but I had modified a couple of ECUs with sockets for the EEPROM chips allowing me to remove them and recover them in a stand-alone programmer each time. I am now confident enough in the code that I have reversed all the modifications on my ECUs and put them back to standard with permanently soldered EEPROM chips. I do not anticipate “bricking” any more ECUs - and if I didn’t have the self-belief and confidence to use it on standard ECUs then how could I expect others to?

In summary then:

 

I will now use this many times on my own car whilst looking for more features without a second thought.

ECU Tables, Indexes, Scalars & Versions

Configurable data inside the ECU appears in two different forms. Tabular data is stored in a well-defined table format. There is a lot more information on 2D and 3D tables below. What I have referred to as “Scalar Data” is in the form of single number values, rather than tables. Many of the numbers and values used in calculations inside the ECU are available in the map file and can be edited. This includes things like ECU fan control temperatures and rev limits for non-VVC ECUs, but also flags for immobiliser deletes etc.

The mapping program is written in a very generic way; there is no hard-coding of special handling for particular features. The program itself understands nothing of ignition timing or target air fuel ratios for example. All of these are defined through configurations which the user is able to modify and extend. In this way I was able to write the application before I had a good understanding of the ECU and use it as a research tool. If also means that as I or others discover new features they are easily configured in the map editor without the need to change code. Apart from those described here, there are many other tables and scalars in the ECU, all of which are accessible through the tool. There is however very little information on what table or scalar value does what, so I've concentrated on identifying the tables and scalars that control identifiable features and those which would be needed in order to adjust the mapping of an ECU to suit a modified engine. There are no keys or axis labels for the tables inside the ECU, all you get is a table of numbers, so I’ve had to work out what they do by changing them and looking for the effects; or conversely, identifying an effect and then tracking down the control data in the ECU, often by a careful process of elimination and a lot of head-scratching, searching for patterns in what I see etc. The scalar numbers are even harder to identify as all you get is one number. For example the number 7000 appears many times in the scalar data, one of them is the rev limit and the others are not. I will continue to search for further identifiable tables and features.

There is considerable variation between the table and scalar structures in different ECUs. The VVC ECU differs from the MPI ECU and each of these ran a number of different firmware versions. The tables in the ECUs are not identified by names or fixed identifiers as far as I can see. Towards the end of the map memory there is an index, which contains the memory locations of each of the actual tables. The ECU appears to identify the tables purely by their position in the index, so I have used this as the identifier for each table in my application. So for a given firmware version, across multiple different maps, for example the table at index position 10 will always have the same function. It may appear at different addresses depending on the sizes of the other tables in the map, but it will always be pointed to by the same index position. Across different firmware versions, the table with the same function may appear at a different index, however they are broadly consistent; there is trend towards tables appearing at slightly later positions in the index in later ECU versions, particularly the higher indexed tables, as tables appear to have been inserted into the sequence to support new features.

A similar pattern emerges in the scalar data. The address at which a particular value appears will vary between different firmware versions, but will always be consistent between different maps for the same firmware version. There is no index to the scalar values; no index is needed as they are all of a fixed size, so always appear in the same location. So I have used the memory address as the identifier for each scalar in my application.

So tables have identifiers like 1, 2 … (up to around) 163 and scalars have identifiers like $13C014, $13C016 etc.

As I will describe below, in most cases you won’t need to worry about all of this detail. Because it varies so much between different ECUs, I’ve built in a machine learning ability in my application. In most cases, it will be able to use its knowledge of other ECUs that it has seen to correctly identify both the tables and scalars in any new ECU it comes across; and if you do have to make any changes, or if you identify any new features in one ECU, it should use these to improve its algorithms to allow it to correctly apply these changes and find these new features in ECUs it sees in the future.

So hopefully, when you hook this up to your ECU, if it has seen the firmware version before it will know where everything is and everything will show up with sensible names and configured correctly, and if it hasn’t seen the firmware version before it will offer to identify all of the tables and scalars automatically and should find them all, or at least most of them, correctly.

If you do want to go hunting for table or scalar values yourself, I’ve discovered a few “rules” that may help along the way:

Table and Scalar Classes

In order to make sense of the above, I've defined the idea of table and scalar classes. The idea is that you can set up a number if classes which remain fixed across all ECUs, and then for each individual firmware version you just need to link table indices and scalar addresses to classes. So for example I have defined an Idle Air Control Valve class. For the ECU in my car, class Idle Air Control Valve is assigned the table at table index position 108 (for brevity I will just refer to Table 108 etc. in the future). The table class defines the description used for the table, any comments, and the properties of the X, Y and Z axes.

Since a lot of tables will for example be indexed on MAP, I've defined axes through classes in the same way. So there is a Manifold Absolute Pressure axis class, and the Idle Air Control Valve table class assigns the Manifold Absolute Pressure axis class to the Y axis. The axis class defines the axis name. It defines the column width required and the prefix, suffix and decimals for display purposes and it also defines a scale and offset used to convert the numbers in the table into meaningful numbers for display. For example the Inlet Air Temperature axis class has a name of “Inlet Air Temperature”, a suffix of "°C", a scale of 0.1 and an offset of -273.2. This is because temperatures are stored internally in tenths of a degree Kelvin and I wanted to display them as degrees Celsius/Centigrade. So a table value of 2932 is multiplied by 0.1 to give 293.2 and then offset by -273.2 to give 20 - it represents 20°C. Formatting the axes in this way makes the tables a lot more readable. 20°C is a lot more meaningful than 2932.

Note that as described in more detail below, the actual body of a table is defined as an axis (always the Z axis - think of it being displayed in a chart with one or two “input” axes and a data axis). So for example the Base Ignition Timing table has an X axis with MAP values, a Y axis with RPM values and a Z axis with ignition timing values. In this way the scaling and display properties for the ignition timing numbers are handled in exactly the same way as the MAP and RPM numbers - by defining the properties of the Z axis.

All of the scaling applied to axes and table values works both ways, so for example where a temperature axis has been scaled to read in °C as above, you can edit or paste value in °C and they will automatically be scaled backwards to write the correct values into the underlying table. So you can treat the table as though it actually contains the scaled values and just forget about the scaling once it is set up.

Scalar classes also allow a single axis class to be specified. This describes the way in which the values are scaled and offset in exactly the same way as for table values. The axis class definitions are common to both tables and scalars as, for example, there are both tables and scalars which specify Coolant Temperature values.

All of the classes I have set up are just examples. You can use mine, or if you want to dig deeper into the ECU using the tool and manage to identify the meanings of some more tables, you are free to define your own classes. If you do so, please share so that I can update the definitions in copies that I distribute.

Dimensions and Axes

The tables found in an ECU are traditionally described as 2D or 3D.

Mathematically a 2D table is actually a 1 dimensional array of numbers, but you can imagine it being displayed as a 2D chart. When looking up a value in a 2D table there is only one input variable, the second "dimension" being the output variable. For example here is a 2D table:

Mathematically a 3D table is actually a 2 dimensional array of numbers, but you can imagine it being displayed as a 3D chart. When looking up a value in a 3D table there are two input variables, the third "dimension" being the output variable. For example here is a 3D table:

When the ECU wants to look up a value in the table, if a cell exists for the axes values required, the number in that cell is used. If (as will be more usual) the axis values fall between cells, the ECU will interpolate between the cells on either side to calculate an intermediate value. When the axis values lie beyond one end of an axis, I have seen evidence that in some cases the ECU just uses the closest edge value and in others it actually extrapolates from the two closest values.

In my application, tables have X, Y and Z axes. In a 2D table, either the X or Y will have just one position and there is no "value" associated with this position. In every case I've seen in MEMS3, 2D tables will have multiple values on the X axis and the Y axis is unused, but if a table is found that has multiple values on the Y axis and the X axis is unused, my application will cope with it correctly as a 2D table of the other orientation. 3D tables have multiple values on both the X and Y axes. In both cases, the Z axis describes the output value being looked up in the table. So in the examples given above, the 2D table has X axis with sensor voltages, no Y axis and a Z value giving the corresponding temperature. The 3D table has an X axis values with MAP values, a Y axis with RPM values and Z axis with air flow numbers.

In order to maximise the amount of data that can be displayed, tables in the application are always displayed with the longer axis of X and Y (i.e. the one with most defined values) going down by default. So sometimes a table will have the X axis across and the Y axis down and sometimes it will have the X axis down and the Y axis across. The top left hand cell in the display shows you the orientation, although once you have classified a table it doesn't really matter as the designations "X" and "Y" only really relate to the order in which the values are stored in memory - as a user you will work in terms of the MAP axis and the RPM axis. For ease of data visualisation, the application does allow you to transpose the orientations of the X and Y on the table and chart, and also allows you to invert (reverse the direction of) the axes on the chart individually. By default the depth axis of the chat is inverted (numbers increasing from the back towards the front) as this gives a layout of points in the chart which most closely corresponds to the layout of the numbers in the table.

Classifying Tables and Scalars

All of this means that for a firmware version not previously seen, it will be necessary to identify and assign the appropriate classes to the relevant tables and scalars. In order to make this easier, I have shown below examples of how these tables and scalars appear and their indices in various different firmware versions. In addition I have added a learning capability to the application; it is largely capable of identifying the tables automatically based on similarities with other tables seen before for other firmware versions.

I have "seeded" the application with a selection of firmware versions, in the hope that it should be able to find most of the tables in most other versions that I haven't seen automatically. What it all comes down to is selecting the appropriate class for each table of interest. I'll talk about how you do this further below.

That's enough theory for now, let's get into the application itself where it will all make a lot more sense...

MEMS3 Mapper Application

You can download the full suite of MEMS3 Tools as a ZIP file here: http://andrewrevill.co.uk/Downloads/MEMS3Tools.zip. You need to download the ZIP file and unzip all files into a single folder. This includes the simpler MEMS3 Flasher application which is described here: https://andrewrevill.co.uk/MEMS3Flasher.htm. It also includes the MEMS3 Terminal and modified FTDI DLLs that I talked about in the earlier write-up. To run the application, double click the "MEMS3 Mapper.exe" file. You should see a window similar to those below. The application may appear slightly differently on different versions of Windows, but it should work in the same way. Here it is on Windows 7:

And Windows 10:

Hardware requirements are similar to those I described for the MEMS3 Flasher tool. I have however since rewritten the low level interface to the ECU to remove all dependencies on the FTDI chipset, so any OBDII cable described as a VAG COM KKL 409.1 cable or similar should work fine. These are widely available very cheaply on eBay, e.g. https://www.ebay.co.uk/itm/USB-Cable-VAG-COM-KKL-409-1-Auto-Scanner-Scan-For-Car-Seat-Diagnostic-Tools-BT/223941245849?hash=item3423f03b99:g:ddcAAOSwnT5eYeD5.

https://i.ebayimg.com/images/g/ddcAAOSwnT5eYeD5/s-l1600.jpg

Depending on the drivers that come with the cable it will either install into your system as an FTDI Direct device, a Windows COM serial port or both. Avoid cables that claim to have an ELM327 chip as these are a completely different interface, and Galletto flasher cables as these seem to have the FTDI chips programmed differently.

The whole suite of applications now works with both FTDI Direct devices and any Windows COM serial ports.

Connecting to the car, opening, saving, reading and writing of files works almost identically to the way I described for the MEMS3 Flasher. Exactly the same options are provided for reading and writing firmware and/or maps to and from the ECU. The tool will prevent you from writing a map to an ECU with a different firmware version. It will also prevent you from writing a firmware or map with an incorrect checksum and will offer to correct checksums automatically as necessary.

The main difference is that MEMS3 Flasher only allowed you to open one file at a time. MEMS3 Mapper allows you to open multiple files. You can move between the open files with Ctrl-Tab and Shift-Ctrl-Tab, by selecting them from the combo box or by using the up and down arrow buttons. This makes it very easy to compare tables between map files as it remembers which table is selected in each file, so you can just tab between them looking for changes.

There are additional buttons to create a new file (which will create a new blank buffer into which you can read a map) or to close the current file. If you close the only file open, the buffer will be cleared and you will be left with a new blank file.

OBDII Protocols

The application supports two different protocols for communicating with the ECU. I identified at least three protocols supported by the ECU, but one of them (ISO9141-2 with Slow Initialisation Sequence) was hard to support over standard Windows COM serial ports (due to the special slow pulse used as an initialisation signal) and required the FTDI chipset or similar, and seemed to be more appropriate to OBDII scanner tools, offering no particular benefits here, so I dropped support for it. The other two protocols seem to be largely interchangeable but it’s worth noting a couple of details here:

In practice it makes very little difference which protocol you choose. I’ve worked around all of the differences and fully implemented everything that I need to use on both protocols. I’ve successfully flashed firmware and maps over both protocols without issues, however there is one “gotcha” to bear in mind:

I believe the “professionals” generally program it using the Rover BMW protocol. Despite initially recommending this protocol (for reasons which were mainly due to the risks of “bricking” the ECU if ISO14320-2 protocol timeouts occurred during write failures, which have now been completely eliminated) I would now suggest using the ISO14320-2 protocol for all mapping and flashing operations. This generally leads to more reliable establishment of communications with the ECU and better interoperability with other tools such as OBDII scanners. I have been using ISO14320-2 protocol for most of my research activities for some time now without any issues and the overall experience is definitely better.

As of Version 4.51 Release of the application I have made ISO14320-2 the default protocol.

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.

 Sector                Size        Address Range  Used For                 

SA0        64KB      $100000 - $10FFFF            Boot Loader         
SA1        64KB      $110000 - $11FFFF            Firmware               
SA2        64KB      $120000 - $12FFFF                              
SA3        32KB      $130000 - $137FFF                            
SA4        8KB        $138000 - $139FFF                            
SA5        8KB        $13A000 - $13BFFF           Coding    
SA6        16KB      $13C000 - $13FFFF           Map      

Each sector of the EEPROM can only be erased as a whole. Without erasing 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 for 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.

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. 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 same is true of the Coding data, so it is not possible to edit coding records written to this area; it is however possible to add new coding records with new VIN code or Part Variant code to the ECU and the application supports this. This is probably for security, the original VIN number being indelibly written to the ECU.

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 adaptations 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.

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: http://andrewrevill.co.uk/KeyProgrammer.htm. Doing it in the car is the easiest way 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 flash the ECU in the car then as a safety precaution it's a very good idea to disconnect the fuel pump (just unplug the inertia switch) and/or injector sub loom. If a write fails or is interrupted, very occasionally after turning the ignition off and on again the ECU will sit with one injector turned on until it flashed again. If your fuel rail is pressurised, that could go quite badly, pumping a lot of fuel into one inlet and risking a hydraulic lock. It's very rare that it decides to do that but I've seen it before so worth taking simple precautions.

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. I’ve tested flashing ECUs with this application with supply voltages from 10.8V to 14.0V and everything worked correctly, although I wouldn’t recommend flashing with a poor power supply. If you’re flashing it in the car, so long as the battery is reasonably healthy it should be happy.

Connecting To The Vehicle

In a nutshell, connect to the vehicle as follows:

Reading The ECU

Once connected you can read the existing map, with or without the firmware from the ECU.

Click the Read button. You should be presented with a dialog like the one shown below:

You can choose to read the full firmware (contains the operating software of the ECU), coding (holds permanent records contains the VIN and Part Variant plus other information) and the map (contains the various tables and scalars 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.

As I mentioned before, unlike the MEMS3 Flasher tool, this application allows you to have multiple files open at any one time. If you choose to read the Map Only in the dialog, the map data from the ECU is read into the current file. If you choose to read the full Firmware, Coding & Map, it creates a new file (unless an open file is already completely blank, in which case it uses that).

Once the read is complete the system displays a dialog confirming the Firmware ID, VIN, Date Code and Part Variant, (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.

The pictures below show the dialog after read the Firmware, Coding & Map (left) and Map Only (right).

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.

 

After reading the ECU, the tool will display the tables and scalars in the map both in tabular form and graphically. In the picture below you can see that there are tabs at the top left for Tables and Scalars.

This is the Tables tab:

And this is the Scalars tab:

If the firmware version in the ECU is one already known to the application, you will see the known tables and scalars classified and listed at the top in black as shown above (all of the unclassified tables and scalars are listed below in grey). If not the system will prompt you to confirm that you want it to attempt to identify tables and scalars automatically. Click Yes and the system will compare each table loaded from the ECU with all tables seen previously and attempt to assign the best matching table to each class. Depending on how closely the tables resemble those previously seen in other firmwares, it may be able to identify the correct table for every known class or it may not. Unfortunately it only has the numerical data in the table and its position in the index to go on as there is no unique identifier assigned to the tables in the map. It compares the tables based on the extent to which the numeric ranges on the axes overlap (i.e. to what extent is the table answering the same question), the extent to which the values in the table agree (as the number of axis points may vary it constructs a 100 by 100 mesh over the intersecting axis range between the tables and interpolates values from each table at every point looking at the extent to which they appear similar) and the closeness of the table indices. For scalars, comparing a single number does not give enough for the application to identify classes automatically. For example the number 7000 appears many times in the scalar data, one of them is the rev limit and the others are not. Instead it looks for patterns in the surrounding scalars and uses these to find the best match. In most cases it should get most of them right, but you may have to manually correct it.

The system continues to learn from any table and scalar classifications you assign. Each time you classify a table or scalar or correct what it did, the information is added to its library for use in classifying tables and scalars in the future.

The system automatically adds any tables and scalars found in any files read or opened to its reference library, but only provided that it detects that the map is a virgin MG Rover map and not modified (this is to prevent any experimentally modified tables from being added to the library leading to false matches in the future). The system is able to distinguish between virgin and modified maps due to the algorithm used for correcting map checksums when it has made modifications. It applies a two byte signature ($4D, $4D hexadecimal which is “MM” for “MEMS3 Mapper” in ASCII code) immediately after this; in a virgin Rover ECU these bytes would always contain $FF. So any map where the checksum is incorrect must have been modified (and not yet checksum corrected) as the ECU would not have accepted a map with an incorrect checksum, any map with the signature must have been modified (and the checksum corrected) and anything else must be a virgin MG Rover map.

Bear in mind that the index of a table with a given function tended to remain largely consistent across multiple versions of the ECU firmware. The indices tended to increase occasionally as additional table got inserted into the map, but when looking for a table for a given function you should expect to find it in a very similar position to that which it occupies in other ECU. Addresses of scalars follow the same basic principle but are more subject to variation. The table below shows the table indices for the tables and scalars I have identified so far for a range of firmware versions for both MPI and VVC ECUs (some features are only available on VVC ECUs).

Note that as of 15/04/2020 I have decided to focus my research entirely on MG Rover or Caterham non-Turbo ECUs only. Although the application works equally well with Land Rover and Turbo ECUs, the maps are sufficiently differently structured to make it difficult to correlate tables and features between them, although they are occasionally useful for reference (for example to convince myself that the Est. Manifold Absolute Pressure table was what I thought it was interesting to see that the Turbo ECUs had this table going well above 100kPa into boost). As these ECUs are of significantly less interest to us as Caterham owners I have left them out of my analysis of the maps for now to allow me to focus on the features which are more of interest.

Tables by Feature by Firmware ID for MEMS3 ECUs - Common Features

Feature

MPI Firmware

VVC Firmware

Status

Feature

Detail

KLR3P002

KLR3P005

KLR3P009

KLRHP002

CS73P001

KSR3P002

KSR3P004

KSR3P006

KSR3P007

KSR3P008

Function Conf. by Experiment

Accel. Enrich.

(Temp. & RPM) ®

155

155

155

153

159

159

159

162

162

162

Confirmed

(TPS Range)

77

77

77

77

78

78

78

80

80

80

Confirmed

Accel. Ign. Retard

(MAP & RPM)

119

119

119

117

122

122

122

125

125

125

Confirmed

(Temp.)

40

40

40

40

40

40

40

42

42

42

Confirmed

Catalyst Heating Ign. Retard ®

-

112

112

112

-

115

115

115

118

118

118

Confirmed

Est. Inlet Air Temperature ®

-

148

148

148

146

152

152

152

155

155

155

Confirmed

Est. Manifold Absolute Pressure

-

136

136

136

134

139

139

139

142

142

142

Confirmed

Fuelling

(Air Flow Adjust.) ®

150

150

150

148

154

154

154

157

157

157

Confirmed

(Base Scale Factor)

146

146

146

144

150

150

150

153

153

153

Confirmed

(Target AFR)

147

147

147

145

151

151

151

154

154

154

Confirmed

Idle Air Control Valve

-

105

105

105

104

108

108

108

111

111

111

Confirmed

Idle Stabilisation

(Long Term) ®

36

36

36

36

36

36

36

38

38

38

Confirmed

(Short Term)

106

106

106

105

109

109

109

112

112

112

Confirmed

Ignition Timing

-

109

109

109

108

112

112

112

115

115

115

Confirmed

Ignition Dwell Time ®

-

123

123

123

121

126

126

126

129

129

129

Confirmed

Injection Timing

-

139

139

139

137

142

142

142

145

145

145

Confirmed

Injector Dead Time ®

-

66

66

66

66

66

66

66

68

68

68

Confirmed

Injector Flow Rate ®

-

71

71

71

71

71

71

71

73

73

73

Confirmed

Overrun Pop & Crackle ®

 

135

135

135

133

138

138

138

141

141

141

Partial

Sensor Calibration

(CTS)

4

4

4

4

4

4

4

4

4

4

Confirmed

(EBT)

5

5

5

5

5

5

5

5

5

5

Confirmed

(IAT)

6

6

6

6

6

6

6

6

6

6

Confirmed

(OTS) ®

8

8

8

8

8

8

8

8

8

8

 

Target Idle Speed

-

18

19

18

16

16

16

16

18

18

18

Confirmed

Unident. Ign. Trim

(007.116) ®

110

110

110

109

113

113

113

116

116

116

 

(007.117) ®

111

111

111

-

114

114

114

117

117

117

 

(007.119) ®

113

113

113

111

116

116

116

119

119

119

 

(007.120) ®

114

114

114

112

117

117

117

120

120

120

 

(007.121) ®

115

115

115

113

118

118

118

121

121

121

 

(007.122) ®

116

116

116

114

119

119

119

122

122

122

 

(007.123) ®

117

117

117

115

120

120

120

123

123

123

 

(007.124) ®

118

118

118

116

121

121

121

124

124

124

 

(007.126) ®

120

120

120

118

123

123

123

126

126

126

 

Warm-Up Enrichment

-

143

143

143

141

147

147

147

150

150

150

Confirmed

Tables by Feature by Firmware ID for MEMS3 ECUs - VVC Features

Feature

MPI Firmware

VVC Firmware

Status

Feature

Detail

KLR3P002

KLR3P005

KLR3P009

KLRHP002

CS73P001

KSR3P002

KSR3P004

KSR3P006

KSR3P007

KSR3P008

Function Conf. by Experiment

VVC Inlet Cam Duration

-

-

-

-

-

161

161

161

164

164

164

Confirmed

VVC Response Time ®

-

-

-

-

-

80

80

80

82

82

82

Confirmed

VVC Rev Limit

-

-

-

-

-

72

72

72

74

74

74

Confirmed

Scalars by Feature by Firmware ID for MEMS3 ECUs

Feature

MPI Firmware

VVC Firmware

Status

Feature

Detail

KLR3P002

KLR3P005

KLR3P009

KLRHP002

CS73P001

KSR3P002

KSR3P004

KSR3P006

KSR3P007

KSR3P008

Function Conf. by Experiment

Idle Speed Increase (Cam/VVC Fault)

-

$13C390

$13C3AE

$13C3B0

$13C2E2

$13C396

$13C390

$13C3AE

$13C3BC

$13C3B8

$13C3BC

Confirmed

Immobiliser Delete Flag

-

$13CA44

$13CA6C

$13CA6E

$13C98A

$13CA78

$13CA72

$13CA9A

$13CAA8

$13CAA4

$13CAA8

Confirmed

MPI Rev Limit

-

$13C6C0

$13C6DE

$13C6E0

$13C604

$13C6C8

$13C6C2

$13C6E0

$13C6EE

$13C6EA

$13C6EE

Confirmed

Radiator Fan Off Below

-

$13C29E

$13C2BC

$13C2BE

$13C1E2

£13C296

$13C290

$13C2AE

$13C2BC

$13C2B8

$13C2BC

Confirmed

Radiator Fan On Above

-

$13C2A0

$13C2BE

$13C2C0

$13C1E4

$13C298

$13C292

$13C2B0

$13C2BE

$13C2BA

$13C2BE

Confirmed

® Overrun Fuel Cut Min. Coolant Temp.

1

$13C4F8

$13C516

$13C518

$13C440

$13C4FE

$13C4F8

$13C516

$13C524

$13C520

$13C524

 

2

$13C5AC

$13C5CA

$13C5CC

$13C4F2

$13C5B2

$13C5AC

$13C5CA

$13C5D8

$13C5D4

$13C5D8

 

TABLES AND SCALARS MARKED "®" ARE STILL THE SUBJECT OF RESEARCH

Saving & Opening

At this point you may want to save the file read from the ECU to disk.

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. Note that of you choose to save a full EEPROM file, a boot loader will be required (the application only normally handles the firmware, coding and map areas). In order to ensure that the saved file can safely be flashed to a 29F200 EEPROM and then soldered into an ECU, the application will insert a standard bootp033 (later VVC160 NNN000160) boot loader in the lower address range. This boot loader works fine with any other firmware, MPI or VVC.

In normal use, you would probably only need to use the normal Flasher files.

As I mentioned before, unlike the MEMS3 Flasher tool, this application allows you to have multiple files open at any one time. If you later choose to open a file which contains only partial EEPROM contents (i.e. a Firmware File or a Map File as described above), the data from the file is read into the current file. If you choose to open a file which contains the full firmware, coding & map (i.e. a Flasher File or EEPROM file as described above), it creates a new file (unless an open file is already completely blank, in which case it uses that).

Writing To The ECU

Once you have made modifications to the map, you will need to write it back to the ECU. There is no “live updates” mode supported, the ignition must be turned on but the engine must not be running in order to write a modified map back to the ECU. The writing process initially erases the firmware or map being written; to do this it runs in a protected boot loader in the ECU and all normal engine management features are suspended.

The process of writing to the ECU is very similar to the process of 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.

There are a few extra options when writing:

Clear adaptations. This will clear any 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 fuelling may be slightly incorrect.

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.

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.

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 up to about 24 seconds to write and up to about 22 seconds to verify, so up to 46 seconds in total. Performing a full write of the ECU takes up to about 3 minutes 44 seconds to write and up to about 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.

Try not to interrupt the process of writing to the ECU as the ECU will not run the engine with only a partial firmware or map. If the process is interrupted, you will see an error message like this (in this case I pulled the USB connector out of the back of my laptop mid-write):

The writing process is now fail-safe. The ECU will be left in a non-running state and will in all likelihood fail to communicate with the application, but this is only because it will be in the middle of a data transfer and will not be expecting other commands. All you will need to do to restore normal communications is to turn the ignition off and on again. You will notice that the fuel pump will not prime as normal as the ECU will continue to run the boot loader only and will not run normal engine management operations. Once you have cycled the ignition and made sure that the issue with the connection to the ECU has been rectified (e.g. any cable that got pulled out has been plugged back in again), you can simply repeat the write operation. See the section on Fail Safe Read & Write at the top of this write-up for further information.

Views & Filters

The application is a bit of hybrid between a remapping tool and a research tool for use by me in decoding the maps. As such, it shows you all of the tables and scalars found in the ECU and provides the tools to allow you to filter them down to find ones that are relevant. The filters provided for tables and scalars are slightly different.

For tables, in addition to viewing only 2D or 3D tables and limiting the maximum and minimum table size with sliders, you can choose one of the following basic views:

For scalars, the basic view options are the same but the filter options allow you to list only those which lie between minimum and maximum values. You can specify either a minimum value, a maximum value or both. Unclassified scalars are sorted by address.

As the values of scalars are often stored using a scale factor and an offset (e.g. temperature a value of 20°C is stored in tenths of a degree Kelvin as (20+273.2)*10 = 2932), you also have the option of viewing all unclassified scalars as any axis class you choose (classified scalars are always displayed using the axis class assigned to them). The minimum and maximum value filters are then applied to the correctly scaled values.

Search

I’ve implemented a Search facility that will search the EEPROM data for any of the following:

You don’t need to specify what kind of item you area searching for, just type what you want to search for in the box and press ENTER or click the Search button. It will find the first address that matches the text you typed as any one of the above. F3 will repeat the last search provided that it was successful, finding the next instance which matches.

You can also search for any of the following pre-defined items from the drop down list:

Go To

In addition to the Search facility, I’ve implemented a Go To feature. This allows you to go to the memory address for any table (in fact any cell in any table) or any scalar. It works both ways; highlight a cell or scalar and click Go To and it takes you to the corresponding memory address in the Hex tab, highlight a memory address in the Hex tab that is associated with a table or scalar and click Go To and it takes you to the view of the corresponding table or scalar. Go To is found on the main menu, on right click popup menus throughout the application and as a button on the button bar. See the section on the Hex Tab below for more information.

The Hex Tab

The Hex tab shows you the raw contents of the EEPROM memory in a hexadecimal grid format.

This is an extension of the hexadecimal data display in the MEMS3 Flasher application. It shows the memory contents, 32 bytes per row, in both hexadecimal and ASCII character format.

You can edit the memory contents directly in the Hex tab or you can edit tables and scalars in the other tabs. Either way is equivalent; if you edit a table you will see the memory changes immediately in the Hex tab and if you edit the memory contents in the Hex tab you will see the changes immediately in the corresponding table or scalar.

You will see that every memory address with an identified meaning is highlighted in an appropriate colour. For tables, the colours reflect the shading of the cells in the table display. If you hover the mouse over any memory cell, you will see a hint window which tells you exactly what that memory address is used for:

With any byte selected you will also see a decode at the bottom of the page showing the corresponding 16-bit value. Note that the microcontroller in the ECU appears to use 16-bit aligned values exclusively; this is to say that any number stored in the EEPROM data will always consist of two bytes, the first being the high order 8 bits in an even numbered byte and second being the low order 8 bits in the odd numbered byte following it. So you will see the same 16-bit number for each pair of consecutive even and odd numbered addresses. The value is shown decoded from hexadecimal as both signed and unsigned 16-bit integers, and you can edit the values in either of these forms; any changes you edit here are written back to the memory using the appropriate convention and you will immediately see that changes in any tables or scalars affected.

The Go To button will take you to the table or scalar associated with the selected memory address, in the same way that it will take you to the memory address for a given table cell or scalar.

If you apply filters to the tables or scalars as described above, then only those which meet the filter criteria are highlighted within the memory grid.

You can highlight contiguous ranges of memory addresses by dragging with the mouse, or using Shift and Ctrl on the keyboard in the usual way. You can click Select All to select all memory addresses. The Copy, Paste, Cut and Clear buttons work on the selected range of addresses. Select All, Copy, Paste, Cut and Clear are found on the main menu, on right click popup menus throughout the application and as buttons on the button bar. Memory cells are copied to the clipboard as address, value pairs in hexadecimal:

$13CC0B               $3E

$13CC0C               $00

$13CC0D              $4E

$13CC0E               $00

When cutting or clearing cells, they are set to $FF. This is the state of memory cells in a new EEPROM chip or after erasing a sector and is the value stored in every unused memory address in the EEPROM.

Note that the clipboard formats used are all plain text formats, you can for example Copy Table Data and paste the copied table into an email; the recipient can then copy the data from the email and paste it into a table.

The Tables Tab

The Tables tab gives you both a tabular view and a graphical view of each table in the map.

On the left hand side you will see the list of tables found in the index. This is sorted and highlighted according to the rules described previously. See the section on Views & Filters for more information.

In the centre you will see the table displayed as a grid. You can edit values in the grid and changes are written back to memory immediately.

You can highlight rectangular ranges of cells by dragging with the mouse, or using Shift and Ctrl on the keyboard in the usual way. You can click Select All to select all cells in the table. The Copy, Paste, Cut and Clear buttons work on the selected range of addresses. Select All, Copy, Paste, Cut and Clear are found on the main menu, on right click popup menus throughout the application and as buttons on the button bar.

Note that there two Copy options which do different things:

In order to maximise the amount of data that can be displayed, tables in the application are always displayed with the longer axis of X and Y (i.e. the one with most defined values) going down by default. So sometimes a table will have the X axis across and the Y axis down and sometimes it will have the X axis down and the Y axis across. The top left hand cell in the display shows you the orientation, although once you have classified a table it doesn't really matter as the designations "X" and "Y" only really relate to the order in which the values are stored in memory - as a user you will work in terms of the MAP axis and the RPM axis. For ease of data visualisation, the application does allow you to transpose the orientations of the X and Y on the table and chart, and also allows you to invert (reverse the direction of) the axes on the chart. By default the depth axis of the chat is inverted (numbers increasing from the back towards the front) as this gives a layout of points in the chart which most closely corresponds to the layout of the numbers in the table. Transpose is found on the main menu, on the right-click popup menu on the table grid and on the drop down menu on the Table button.

By default the axis cells in the grid are locked and you cannot change the axis values. If you want to be able to edit the axes, select Edit Axes, which is found on the main menu, on the right-click popup menu on the table grid and on the drop down menu on the Table button. This will unlock the axis cells for both the horizontal and vertical axes and allow you to edit the values. In addition, once the axes are unlocked for editing, if you click on a cell in either axis you will then see options on the main, popup and drop down menus for Insert Axis Value and Delete Axis Value. These allow you to change the size of the table by inserting and deleting values on the axes - the application takes care of moving everything else around in memory to accommodate the new table size and then updates the table index to point to the new table addresses. I have tested this on a number of ECUs and they seem quite happy to accept tables of different sizes and apply them correctly. There are a few points to note though:

You can see that the new axis value 85kPa has sensible ignition timings associated with it and that despite a new column of values appearing, the new grid line on the chart follows the original profile and the shape of the ignition curve is unaltered:


You can then edit the values for the new 85kPa axis value as required.

You also have the option of displaying Raw Values. When displaying raw values, none of the axis formatting (scaling, offsetting or number formatting) is applied. Values are displayed as 16-bit signed integers, exactly as they appear in the table memory. When raw values are displayed, you also edit and enter numbers in raw format too. For example here is injector scaling table displayed normally with formatting on the left and as raw values on the right. Raw Values is found on the main menu, on the right-click popup menu on the table grid and on the drop down menu on the Table button.

               

On the right you will see the table displayed as a chart. In the case of a 3D table and chart, you can rotate the chart in three dimensions by dragging with the mouse to help you visualise the shape of the curved surface. You can reset the view of the chart to the default view at any time by double-clicking it, or by selecting Reset View, which is found on the main menu and on the right-click popup menu on the table chart.

You will see that both 2D and 3D charts include a small red dot indicator labelled with a value which identifies the point on the chart corresponding to the selected cell in the table grid. In 3D view this is drawn both in front of and behind the actual surface plot to ensure that it always remains visible as you rotate the chart - sometimes this means that the actual point on the curve may become obscured but the indicator remains visible.

The indicator moves as you move the selection around the table grid. For ease of data visualisation, the application does allow you to transpose the orientations of the X and Y on the table and chart, and also allows you to invert (reverse the direction of) the axes on the chart. By default the depth axis of the chat is inverted (numbers increasing from the back towards the front) as this gives a layout of points in the chart which most closely corresponds to the layout of the numbers in the table. The options to Invert Bottom Axis, Invert Left Axis and Invert Depth Axis are found on the main menu and the right-click popup menu on the table chart.

Both 2D and 3D charts also allow you to Copy As Bitmap and Copy As Metafile. These copy the chart image to the clipboard in the specified format, allowing you to paste the chart image into an image editor, Word document, email or whatever. The image is copied exactly as displayed on the screen, so if you want to resize it, resize the MEMS3 Mapper window appropriately before copying for best results. For example this image was copied:

Finally you have the ability to edit the table definition. Definition is found on the main menu, on the right-click popup menu on the table grid and on the drop down menu on the Table button, and also by double-clicking a table in the list on the left hand side of the screen. See the notes on Table Definitions below for more information.

Table Definitions

This is the Table Definition dialog. Definition is found on the main menu, on the right-click popup menu on the table grid and on the drop down menu on the Table button, and also by double-clicking a table in the list on the left hand side of the screen. This allows you to change the definition of identified, classified tables or add new definitions for tables not previously identified.

Note that table, scalar and axis class definitions are shared across all firmware versions and are saved in a single definition file. So if you change the definition of a table class, you are changing the definition of that class in all maps and all firmware versions - you are reconfiguring the application, not modifying the map. If you change table, scalar or axis definitions you will be prompted whether you wish to save the changes on exiting the application. The entire definition file is saved on exit, or when clicking the Save button in either the Table Definition or Scalar Definition dialog.

The various fields which you can edit in this dialog are as follows:

The Scalars Tab

The Scalars tab allows you to view and edit the scalars in the map.

On the left hand side you will see the list of scalars in the map. This is sorted and highlighted according to the rules described previously. See the section on Views & Filters for more information. As scalars are single valued by definition, there is usually no separate grid for editing scalar values. Instead there is a second column in the list of scalars allowing you to edit the values. You can edit values in the list and changes are written back to memory immediately.

In addition, for scalars which are defined to be in hexadecimal format (see the section on Scalar Definitions below for more information), you will also see an additional grid showing the equivalent decimal value and the individual binary bits, as shown below:

This is useful where the individual binary bits are used as switches to turn particular features on and off. For example in the Immobiliser Delete Flag scalar shown above, bit 8 disables the immobiliser function when set to a 1 and enables it when cleared to a 0. The function of the other bits is unknown; in most cases they are all 0 but I have seen ECUs with other bits set so they must do something, and when updating the Immobiliser Delete Flag you would probably want to leave the other bits untouched, so a bit-by-bit edit facility comes in handy.

On the right hand side, below the decimals and binary numbers if displayed, you will see the comments for the selected scalar.

The Copy, Paste, Cut and Clear buttons work on the selected scalar. Copy, Paste, Cut and Clear are found on the main menu, on right click popup menus throughout the application and as buttons on the button bar.

Just as for tables, you have the option of displaying Raw Values. When displaying raw values, none of the axis formatting (scaling, offsetting or number formatting) is applied. Values are displayed as 16-bit signed integers, exactly as they appear in the scalar memory. When raw values are displayed, you also edit and enter numbers in raw format too. For example here are the identified scalars in a map displayed normally with formatting on the left and as raw values on the right. Raw Values is found on the main menu, on the right-click popup menus on the Scalars tab and on the drop down menu on the Scalar button.

       

Finally you have the ability to edit the scalar definition. Definition is found on the main menu, on the right-click popup menus on the Scalars tab and on the drop down menu on the Scalar button, and also by double-clicking a scalar in the list on the left hand side of the screen. See the notes on Scalar Definitions below for more information.

Scalar Definitions

This is the Scalar Definition dialog. Definition is found on the main menu, on the right-click popup menus on the Scalar tab and on the drop down menu on the Scalar button, and also by double-clicking a scalar in the list on the left hand side of the screen. This allows you to change the definition of identified, classified scalars or add new definitions for scalars not previously identified.

Note that table, scalar and axis class definitions are shared across all firmware versions and are saved in a single definition file. So if you change the definition of a scalar class, you are changing the definition of that class in all maps and all firmware versions - you are reconfiguring the application, not modifying the map. If you change table, scalar or axis definitions you will be prompted whether you wish to save the changes on exiting the application. The entire definition file is saved on exit, or when clicking the Save button in either the Table Definition or Scalar Definition dialog.

The various fields which you can edit in this dialog are as follows:

Tables Identified

I will now go through the various tables which I have been able to identify in the maps of various MPI and VVC ECUs with some comments on exactly how they appear to work and how I went about identifying them and proving their functions where appropriate.

After all of the head flow work, exhaust cam changes and cam timing changes I have done to my engine, when I had it on the rolling road we found that the mixture was going a too lean for comfort and a couple of points in the rev range at WOT. Now I can see why; if I’ve increased the actual air flow through modifications but not increased the numbers in the air flow table, at any given RPM and MAP the ECU is likely to underestimating the fuel requirement. For the time being I fixed this by slightly increasing the fuel pressure, but now I should be able to adjust the fuelling just at the point where an increase is required rather than applying a blanket 5% increase.

So now for the three tables I actually found…

Scalars Identified

I will now go through the various scalars which I have been able to identify in the maps of various MPI and VVC ECUs.

The Log Tab

On the Log tab you can a detailed transcript of communications between the application and the ECU. This includes a millisecond time stamp, a direction (Write / Echo / Read), the Baud rate used (which should be 9600 for Rover BMW protocol, 10400 for ISO14230-2 protocol and 360 for the ISO14230-2 Fast Initialisation pulse). This is followed by a description of the message content and the actual message bytes.

You can Copy or Clear the log using the buttons or the menus and you can Save the log to a text file.

You should see that a successful communication with the ECU will consist of a Write, then an Echo, then a Read.

OBDII communications with the ECU take place on a single wire (the K Line) which transmits messages in both directions. Messages usually have “addresses” which say what device is transmitting and what device the message is intended for. All devices attached to the K Line see all messages transmitted. This means that the receive section within the electronics in the OBDII cable sees the messages sent by its own transmit section as well as messages sent by the ECU.

So any message sent by the application (Write) should immediately be read back identically (Echo), followed by any response from the ECU (Read).

The important thing to realise is that the Echo data comes from the electronics of the OBDII cable (reading its own transmission as described above) but the Read data comes from the ECU. Looking at these two therefore gives some important clues for diagnosing communications issues:

Difference Mode

This allows you to compare two maps and only display the tables or scalars with differences. You can only compare two maps for the same firmware version as the table and scalar structures will not correspond between maps for different firmware versions.

Once you have opened two or more files, go to the file which you want to compare and click Difference. Difference is found on the main menu and as a button on the button bar. You will see a drop down menu which allows you to choose which other file you with to compare it with.

Choose the file you wish to compare to and you will then see that both tables and scalars are filtered down to show only those with differences (in this case the only differences were the pop and crackle settings in the Ignition Timing and Overrun Pop & Crackle tables and the increase in the overrun fuel cut temperature scalars). You can then use Ctrl-Tab to switch between the files and eyeball the differences which will stand out as you switch between them.



To exit Difference mode, simply click the Difference button again.

ECU Tools

The ECU Tools menu gives access to a few useful actions you may wish to perform on the ECU.

Write Coding Record

This option allows you to write a new lower coding record to the ECU. The coding records look like they were written to the ECU whenever it was reprogrammed by Rover. Most ECUs only have a single lower coding record, although some have two which suggest that these ECUs were reprogrammed with updated maps or firmware at some point. The lower coding records contain (amongst other unidentified information) the date on which the record was programmed and the VIN and Part Variant codes (a part number usually starting with NNW, which identifies the combination of hardware and software builds, whereas the Part Number starting with NNN identifies the hardware build only). As far as I can tell, the coding area cannot be erased (i.e. the ECU doesn’t provide a routine to erase it, the only way to erase to it would be to crack the ECU open and desolder the memory chip and reprogram it on a PC). I think the idea is that the coding records form a permanent, indelible record of the ECUs history. You can only add new records after the existing records, you cannot erase or update (without corrupting, as you can only reprogram binary 1s to 0s and not the other way around without erasing) existing records.

The MEMS3 Mapper application allows you to add lower coding records to the ECU with your own VIN and your own Part Variant codes if you wish. I have coded modified ECUs to my car’s VIN number and used the Part Variant ADR999999. The first 3 characters can be alphabetical or numeric, the last 6 characters must be numeric digits (they are stored as 2 digits per byte in BCD coding).

Remember that once written, you cannot edit or erase the coding record.

To write a new coding record, click Write Coding Record. Write Coding Record is found on the main menu and the drop down menu on the ECU Tools button. The application will download the existing coding records from the ECU and display a dialog as shown below:

Enter your VIN (which will default to the VIN taken from the last current coding record), the date (which will default to today’s date) and Part Variant code (which will default to the Part Variant code taken from the last current coding record. The first 11 characters of the VIN can be alphabetical or numeric, the last 6 characters must be numeric digits (they are stored as 2 digits per byte in BCD coding). The first 3 characters of the Part Variant can be alphabetical or numeric, the last 6 characters must be numeric digits (they are stored as 2 digits per byte in BCD coding).

The coding records don’t seem to affect the operation of the ECU in any way, they are effectively documentation. In order to try to ensure that the ECU will still read back correctly on Rover equipment, the new coding record is copied from the last current coding record and the three fields above are then updated. This means that any other fields which are not understood are left unchanged.

Click Write to write the new coding record to the ECU.

Options

The Options menu allows you to change a few configuration options for the application. In addition it provides links to contact me. Some other configuration options are saved by the application automatically between sessions. These include:

Options which you can configure through the Options menu include:

All of these settings are stored in a file called MEMS3Mapper.set in the same folder as the application executable file when the application is closed. You can revert everything back to standard settings by deleting this file. You will also see files named MEMS3Mapper.def and MEMS3Mapper.dat which contain the table, scalar and axis definitions and the data used for matching classes in new firmware versions respectively.

ECU 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 and production systems originally.

Whilst experimenting with all of this I’ve flashed a lot of maps onto quite a number of different ECUs. This includes a lot of invalid combinations such as flashing a VVC firmware and map onto a non-VVC ECU which doesn’t have all the electronics necessary to drive the VVC system. In all cases the ECUs still ran the engine, and surprisingly well too. It certainly doesn’t seem to cause any major problems flashing a firmware for a different kind of MEMS3 ECU - I’m not saying it will run the engine properly as for example all of the VVC control would be missing in the above case, but what I am saying is that it looks unlikely that you will break anything trying, and you can always reflash the ECU more appropriate afterwards.

As far as I can determine (and this may or may not be absolutely correct), at least as far as the systems we run in our Caterhams are concerned, due to the modular nature of the ECU design there effectively only three different categories of ECUs:

The automatic ECUs include additional electronics including a CANbus controller to talk to the gearbox. However, when flashed with firmware and map from a manual ECU they just seem to happily ignore the extra peripheral electronics and run quite happily. As we don’t run automatic gearboxes this means that the first two of the above appear to be interchangeable for our purposes.

The VVC ECUs include additional electronics associated with processing of the VVC cam signals and drive of the VVC mechanism solenoids. However, when flashed with firmware and map from a non-VVC ECU they again seem to happily ignore the extra peripheral electronics and run quite happily as manual ECUs.

Non-VVC MEMS3 ECUs of various different types are readily available at very cheap prices on eBay (from about £7.00 - I’ve bought quite a few for experimentation whilst working on this project). As far as I can see from the experiments I’ve done, any one of these can be flashed with a full firmware and map copied from any non-VVC ECU we use, whether it has a standard Rover map, Caterham Supersport modifications or a custom modified mapping to give a fully functional cloned ECU. This means that the pool of spares available is quite large and it becomes economical to flash a spare copy just in case it is needed in the future, especially if you have something modified, rare and potentially expensive to replace.

VVC ECUs tend to be more expensive. You can though still pick up used ones for around £50 and there are some brand new ones up for sale at the moment for £99.95. The most common VVC ECU part numbers are NNN000100 (MGF Trophy) and NNN000160 (MG TF and ZR). I have flashed firmware and maps between these two without any problems at all and have run both in my car.

Future Plans

I’ve got the application to a usable condition. So far I’ve focused mainly on the technical aspects of communicating with the ECU, safely reprogramming it, decoding the memory map, decoding and interpreting the map and presenting it to the use for display and modification. I’m aware that it may still be lacking an extra layer of tools on top which would make it more usable in a live mapping situation. I have to confess at this point (maybe a bit late in the write-up!) that I have very little direct experience of actually remapping engines, so I would welcome comments and suggestions on features which might make it more usable. I’m thinking of facilities for bulk increasing or decreasing regions of tables, interpolation, smoothing etc. All of these things could easily be layered on top of the foundation I have built so far.

One feature that I think will be very hard to add is a “live adjustments” capability of the kind the Emerald software has. This would allow you to adjust map values while engine was running, but I just don’t think the ECU supports this feature - or if it does I don’t think I’d be likely to be able to find a way to discover it unless I had access to another tool which provided this feature and was able to “sniff” the communications to see how it was done. As far as I can see from the data sheet the 29F200 EEPROM chip only supports block erase of whole sectors at a time, and you can’t reprogram a 0 to 1 without erasing, so the only way to sensibly write any changes to the EEPROM is to bulk erase and rewrite, which would require the engine management functions to be shut down (they couldn’t continue to execute whilst erased).

I’d also like to continue to track down more ECU features. In order to be able to find something, I really need to know:

Given those I think I would stand a reasonable chance of tracking down the control of a particular feature in the ECU. I don’t think I’ll have much more success just staring at tables and thinking about what they could be as I think I’ve got all of the obvious ones. There are still many more tables in the ECU for which I haven’t yet been able to identify a function.

If anyone has access to a Testbook T4 or other system that allows other features to be updated I’d love to spend some time logging the communications so I can decode how it’s done but I don’t really expect many of the “usual suspects” to take me up on that!

If anyone is able to spot any additional feature control in an ECU, I’d love to receive feedback so I can incorporate them into the definition files I’m supplying with the application.

I’m aware that this write-up is already a very long post. Even then I’ve not gone into full detail and I haven’t documented all features. Hopefully the rest of it is intuitive enough for you to find your way around once you start using it.

Enjoy!