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