Of ECU's and Electronics

Welcome to DiscoTd5.com, a site dedicated to the Land Rover Td5 Engine. The DiscoTd5.com website springs from the interests and experiences of my ownership of a Td5 Discovery which I purchased in May 2011. Since I first set up the site, my interests have become heavily focused on reverse engineering the Td5 ECU firmware, and I'd expect this focus to remain for the foreseeable future.

To thank site donors for their ongoing support, I've decided to give donor account holders "early access" privileges for new tuning and map related content. The content will eventually appear on the site, but there will be delay of around three months. You'll need to be logged in with a donor account to see this "early access" material.

Donated and didn't get an account?

It appears that a couple of webmail services - hotmail.com in particular - are quietly filtering emails from the discotd5.com domain to spam.

Donors will always get a "Thank you for your donation email" from the site within a few minutes of the donation being made, and I try to get donor accounts setup same day, but it can take up to 2-3 days if I'm away, and have limited internet access.

When the account is created an email advising the account has been setup is sent. This contains a one-time login link.

If you have donated and didn't get a "Thank you email", first thing is to check your spam folder.
If 3+ days have passed, and you haven't got an account creation email, first thing to do is check your spam folder.

In particular if you have used a Hotmail account to donate - just check your spam folder for email from @discotd5.com.

EU2 System Demand Flowchart

Thursday, June 20, 2019 - 12:30

This is the first of what should be a series of posts which provide a little more detail about how the maps fit together.

The individual flowcharts are too large to embed while maintaining any kind of legibility so the full content is attached as a pdf at the end of the post.

EU2 System Demand Flowchart

The current flowchart covers the operation of the EU2 "System Demand" (aka Driver Demand) map and Smoke limiter.
"Driver Demand" is used in Land Rover docs to refer to the throttle position - not the maps. Another reason for describing these maps as System Demand is that the Cruise Control controls speed by using a calculated throttle % that substitutes for the "driver demanded" throttle % as the input to the System Demand maps.

The flow chart includes mention of a "new" Braking IQ map - this is currently marked as Map010 for D2, and Map011 for Defender in the NNN XDFs. Note that these maps are effectively disabled in all tunes - the "limit" is set to 100mg/fire so has no effect - but I have included as they are "active" in the sense that if you modify to a point where the values are lower than the smoke limiter the map will alter engine behavior.

Also note that the Manual maps include Autobox code and vice versa, so the Auto Torque reduce checks are used in Defenders and D2 Manuals.
The maps will have no effect, but the checks are there.

There is a scalar which selects between IAT and ECT as the temperature input to the Smoke air density adjust map. I believe this is set to IAT for all tunes so this hasn't been included to keep things simple.

The calculated airflow is discussed in the Airmass post, as MAP Airmass. As discussed in that post the MAF Airmass is calculated but not used as input into the System Demand, Smoke Limiter, or Torque Limiters in EU2 maps.

Cranking IQ, Autobox Torque Reduce IQ and Idle governor IQ calculations are quite complex so are treated a "black boxes" for clarity.

The three final boxes at lower left are parameters that are used in the Torque Limiting routines.

The EU2 Torque Limiter operation will be covered in the next post.

Attached PDF updated 7 April 2019

MSB XDF updates

Saturday, April 27, 2019 - 22:15

I've uploaded a long overdue update to the MSB XDF's which bring them into line with the EU2 NNN versions.

The archive now includes additional D2 Auto XDF's (MSB101260, MSB101261 and MSB101350).
Thanks to Nicky at Rovertech providing bins for these ECUs.

Currently these XDF are only correct for the first map in the .bin.
The layout of second map is usually sufficiently different to require a different XDF.
I'll look at including definitions for the second map in a future release.

Donors can access the archive after logging in.

On Td5 map tables

Tuesday, April 23, 2019 - 08:45

How map tables work…

It’s not entirely obvious how the individual tables are used in the Td5 ECU, and I don’t think I’ve explained this anywhere else.

The Basics

All tables are looked up using linear interpolation. This is done by searching along an axis to find the values on each side of the target value.

If the target value is lower than the minimum or higher than the maximum the nearest “edge” is used.

Using a EU3 torque limiter table as an example this would mean an engine speed value of 500 rpm (which would only occur when cranking) would be clamped to the 600 rpm column, while a value of 5500 rpm (possible but unlikely) would be clamped to the 5000 rpm column.

EU3 Torque Limiter

If the target value was within the bounds of the table, say 2400 rpm, the value would determined by finding the axis values immediately above and below - 2200 rpm and 2500 rpm.

The interpolation between column values is done by finding the fraction of the difference between the column values at which the target value falls.

$$\frac{2400 - 2200}{2500 - 2200} = \frac{200}{300} = 0.66666$$

Then the difference between the table value for 2200rpm and 2500rpm is multiplied by the fraction to determine the value off the fraction.

$$(44.25 - 42.53)0.6666 = 1.15$$

And finally the lower column value is added to the fractional value to give the limter value at 2400rpm.

$$42.53 + 1.15 = 43.68$$

Essentially the method assumes there is a straight line (hence the linear) joining the points represented by the x-axis and table values.

Higher Dimensions

The same basic principles are applied to 2 and 3 dimensional tables. With 2 dimensional tables the ECU interpolates on both the x and y axis, with the column and row values representing the four corners of a cell. If you look at the graph view of a 2d table the intersections of grid lines represent cell corners and the flat surfaces that fill the cells are all the possible interpolated values that occur between the corner values.

Two sets of tables are actually 3d tables. These are the fuel temp compensation tables, and the inject duration tables.

With these tables there is a hidden third dimension - rpm in the case of fuel temp, and advance in the case of inject duration.

Using the inject duration table as an example, the ECU first determines which tables are above or below the current advance/retard value in the same was as described above. Then the inject duration interpolated from inject quantity and rpm for the maps on either side of the adv/ret value, and the inject duration values are interpolated to find the fractional duration amount.

duration tables as a cube

In effect the duration table is a cube with inject quantity, rpm and advance/retard as the three axes (please excuse the wonky illustration!). The first and last duration tables are sides of the cube, and the remaining table(s) divides the space between the sides equally.

MSB map switching

Wednesday, April 17, 2019 - 07:00

I was having a look at the MSB diagnostics a couple of days ago and came across the request for switching between maps.
Some MSB ECU's - most often the Auto versions - come with tunes former than one market and the switching function provides a method for selecting the correct tune.


The NOSELECT tune is default on a new spare ECU. The tune provides just enough functionality to start an engine.
The duration maps are 2 x 2 tables that have rows for 0 and 750 rpm, so should allow the engine to idle.

The remaining tunes are full market specific fuel maps.
In this case the ECU is an MSB1011191 and has tunes for European and Japanese Auto D2s.

European Auto Tune

Japanese Auto Tune

With some minor modifications to the .bin this ECU should support at least one additional fuel map.
The NOSELECT "tune" seems to be referenced in several places during startup so possibly needs to be retained as is.

Even so this opens up the possibility of software switching between two or three maps without resorting to additional hardware to perform address line switching hacks.

Data tracing in Tuner Pro...

Tuesday, April 9, 2019 - 08:00

As I posted recently the data logger project has been taking up a lot of my time over the past few months.

The main intention of the logger is to enable faster, configurable data logging which can be saved into either CSV or Tuner Pro XDL formats.

Over the past few weeks I've been doing a bit of work on reverse engineering Tuner Pro's XDL data log format. I got about 95% worked out before I got in touch with Tuner Pro developer Mark Mansur who very kindly pointed out with the parts I'd got wrong and filled in the bits I couldn't figure out.

As a way of developing and testing the ADX writer code on the desktop, I've written a bunch of code that reads in an ADX file and Nanocom log file (from an Nanocom running current firmware) and uses that information to create an XDL log file.

There are some issues like the lack of Throttle % in the EVO logs that makes the convertor less useful than it should be.

As a teaser to show the possibilities ADX logging opens up this screen capture shows TP data tracing a converted Nanocom EVO log.
The MAF airflow calculation is being done in Tuner Pro RT, and a simple monitor setup shows AAP and MAP.


Monday, March 18, 2019 - 18:45

I've been working on a disassembly of a K-Series engine map that runs on an NNN petrol MEMS ECU for last day or so.

While there is a basic level of commonality with the Td5 this is very much restricted to low level drivers and some utility functions, like map lookup and interpolation, basic kline drivers, CANBUS drivers, etc, etc.

It's this type of functionality that accounts for the similar appearance of the ECU fuel maps. The lookup for sensor scaling is pretty much identical, even though the actual processing has significant differences, for example.

Once you move beyond this "housekeeping" code, you are firmly into the realm of engine specifics.

So yes, MEMS are similar up to a point - but this also hides a lot of difference in the actual engine code.

In other words "MEMS ain't MEMS"

Datalogger - the rebooted reboot...

Tuesday, March 12, 2019 - 15:45

While things have been fairly quiet on the site recently, that hasn't really been a reflection of the level of work that has been going on at the DiscoTd5 Lab for last three or four months...

The datalogger had pretty much been dumped in parts bin as the level of work required to get it up to a useful state seemed to be overwhelming. Conversation with an enthusiastic D2 tuner convinced me to take another look - on the basis of build it or bin it for good.

Three months later, and hundreds of hours rewriting the code, it's slowly starting to come together.

The biggest chunk of effort - which has basically eaten the last 4 weeks - has gone into writing a SDCard // FAT32 library from the ground up. This was the obstacle that had resulted in the project being shelved previously so it's been a significant hurdle to overcome. There is still work to do but there is now light at the end of the tunnel.

It might seem a bit bizarre to be writing a FAT32 library from scratch when there are well established products like the ELM Chan FATFs available.
The main issue has been that the logger code is written in a way that requires components to be non-blocking. Blocking code will prevent any other code running while the blocking waits in a loop for something to happen - it literally blocks progress.
ELM Chan's FATFs is blocking in that it waits for SDCards to come out of busy state before proceeding. The issue here is that at times cards can be busy for extended periods - 50ms is not unusual even with a good quality card like a SanDisk Ultra. With poor quality cards wait times of 200ms+ are not uncommon.

Where this becomes a problem for a Td5 data logger is that the default time between an ECU response and the next "tester" request is 25ms.
The Nanocom Evo solves the problem by making a series of requests - one log line of data - then writing that line to file. There is a 600ms+ pause between the end of one block of data, and the start of the next which is plenty of time for even the slowest junk SDCard to finish writing and return to idle state. But this also means that the Nanocom is writing one line of log data every 1.25 seconds. Fine for some purposes but a lot of dynamic behavior "falls through the cracks" - the torque reduction of an auto shift completes in under 300ms for example, so is effectively invisible.

The approach I'm taking here is to use non-blocking code with DMA (direct memory access) transfers of data to the card. The DMA transfers effectively run in the background without processor intervention, so the combination means that the processor only needs to setup the write to the SDCard, and then can resume more important tasks like reading data from the ECU, or other sensors. The issue of wait times is dealt with by buffering the data waiting to be written to card. In theory all this will allow data rates 10-15 times faster than the Nanocom to be written to card without delays caused by slow card writes.

An excuse for new toys

One of the issues I'd have was that my old Saleae Logic - an original and now much cloned 8 channel 24Mhz job - is starting to show it's limitations when trying to capture communication with the SDCard at 20Mhz bus speed. To capture a signal you need at least twice the frequency of the signal - so 40Mhz at least - ideally you oversample at x4 so 80Mhz. With the old Logic I was flying blind.
As much as I love the Saleae and the software, a new Logic 8 Pro which has sufficient speed for this task was prohibitively expensive - 700-800USD.

So I've ended up with an open source design analyser that does either buffered or streaming captures. The buffered captures are made to internal memory, and have fairly limited length of capture. around 1 second @100MHz using 4 channels, and 300ms @ 400Mhz using 4 channels. Streaming captures are sent over usb to an open source, cross platform application based on Sigrok. The buffered captures are limited to 100Mhz with 3 channels, or 50MHz when using 6 channels. For the SDCard work I need 4 channels and long captures so need to use the 50MHz/6 Channel option. So not perfect but it's flexible enough to be quite useful. Best thing was that it's far more affordable at $150USD.

DSLogic Plus vs Saleae Logic original
The Logic is the small black square on the left, the DSLogic Plus on the right is significantly bigger but still fairly compact.

And the DSLogic proved it's worth within an 30 minutes of unboxing. I'd had an issue where the code would run perfectly with the Saleae connected but would then fail as soon as I disconnected.
It's a real catch22 - the bug occurs only when your debugging gear isn't connected... makes troubleshooting fun. The DSLogic has coaxial probe leads which significantly reduce the effect on the signal being monitored compared with the Saleae's flying leads. There is a great comparison of a Saleae clone and DSLogic on the OpenTechLab channel on YouTube - the sims of the effect of flying leads is quite an eye opener.

The video above mentions the probe clip quality. The ones that came with mine seem to be cheap knock-offs of ez-hooks. Not quite as clunky as those seen in the video, but hook wire is pretty flimsy compared with ez-hooks.

The upshot was that even with the DSLogic connected the "undebugable" bug was occurring every time a card was inserted, and it was straight forward to isolate where and why the code was failing.


The software is fairly good but a bit rough around the edges at least under macOS. I have a bit of trouble with zooming using the trackpad - it's clearly designed for left and right buttons plus scroll wheel. Protocol decoding seems accurate but is slow compared with the Saleae app, although to be fair10 second captures at 20Mhz were regularly bringing that program to the point where a force quit was required, and in one instance a full reboot.

For the money it is pretty decent, and the cross platform software is a big plus in my book.
Worth noting that the DSLogics sold on eBay are not covered by a manufacturers warranty.
I opted to purchase direct.

EU3 MAF timeout disable

Tuesday, January 8, 2019 - 10:45

I've had a few requests for details on how to disable the timeout on EU3 maps when the MAF sensor is disconnected.
Without this mod the throttle on EU3 maps is unresponsive for 20-30 seconds when the engine is first started.

It's quite simple to do by altering the MAF "out of range" timeout check from a conditional "if timeout branch" to an unconditional "branch".

You'll need to use a HEX editor for this.

First open up you .map file in your favorite hex editor - I use Hex Fiend on macOS for stuff like this.

With the .map open search for a sequence of hex bytes: 66 30 31

Unmodified .map

There should be only one occurrence of this sequence in the .map file at an offset of somewhere around 0xD100 - 0xD400.

Next, change the 66 to 60 - this alters the conditional branch instruction to an unconditional branch, meaning the ECU always executes the "no MAF" code.

Modifed .map file

Save the modified .map file and you are done.

Be aware that this mod “lobotomizes" the EU3 maps to a EU2 style single smoke map configuration.
The ECU will only use the main high range smoke map (map 60).

This should work for all EU3 variants.
If you can't locate the byte sequence let me know which variant you are working with.

Note: The checksum needs to be updated if you are loading the .map using the Nanocom. This can be done by loading the .map file into Tuner Pro with the appropriate XDF and then saving the "bin". The checksum is updated on save. Td5 Map Editor will also update the checksum. If you are using Td5 ME you'll have to either make and the reverse a change to the map so the file is marked as "dirty" then save, or "save as". Thanks to Neil for mentioning this omission.

File under Nanocom Bugs

Monday, December 24, 2018 - 11:00

Is Front Left the new Right Rear?

Getting id of sensor values correct is just so last season...

I've had the 4 amigo's hanging about for a while and finally decided I better fit the replacement sensor that has been kicking around for the last month or two this morning.

Fault codes have been showing an intermittent fault in the right rear sensor.
Usual problem is knowing whether that is right facing the front of the vehicle or right facing the rear.
I'd been assuming right facing the front, but thought I'd double check before replacing.

Logical thing to do is pull the sensor connector and check the voltages with the Nanocom.

So I disconnect the sensor in the rear right wheel arch.
All good - unplugging the sensor is mechanical so Nanocom can't screw this up for us!!

Then check the sensor voltages...

Something doesn't look quite right!

Cyprus, We have a problem..

Fortunately the fault codes are correct, and a quick drive revealed a rear right electrical failure.