TestBook T4 (Main Dealer) Level Support for MEMS3

Download Link: https://andrewrevill.co.uk/Downloads/MEMSTools.zip

My MEMS Mapper now has pretty much all of the MEMS3 functionality of a TestBook T4 system.

I was recently contacted by a gentleman called Richard Jessett, who runs one of the MG Rover owners forums. He had managed to recreate a full working Rover TestBook T4 system, through a combination of acquiring, reverse engineering and recreating parts. He was the proud owner of an immaculately restored Rover Tomcat and SD1, and was very much of the “let’s just do everything we can to keep these old cars on the road” mentality like myself, so he very kindly offered to let me spend an afternoon in his garage playing with it to see what it could do – and more to the point, how it did it.

So off to Oxfordshire I went …

MEMS3 PROXY SERVER

Before I set off, I made an application that was essentially two copies of my MEMS3 Terminal siamesed into one application, passing messages between them. The plan was that I could run two OBDII cables from my laptop, one of them going to my car and the other one going to the T4 system through a splitter cable, which also allowed me to feed 12V power to the T4 as though it was plugged directly into the car. In essence I wrote a proxy server for MEMS3 OBDII protocols, with the plan being that neither the T4 nor the car would realise that my laptop was sitting in the middle passing messages between them, listening in on the conversations, rather than having them directly connected.

It worked first time:

The T4 seemed perfectly happy with the connection. We did discover one slight hiccup, in that the T4 wasn’t just designed to be plugged into a single MEMS3 but a whole MG Rover vehicle, and it did expect a Rover VIN number to check off against the ECU to work out what options should be installed etc. It really didn’t want to talk to the Caterham ECU with a non-Rover VIN number. We fixed this by connecting it to a spare Rover 25 ECU, letting it complete all of its vehicle checks, then quickly swapping the connection across to my Caterham without it noticing. Rather surprisingly, that actually fooled it.

PROXY SERVER RULES FILE

This is where the next trick of my proxy server application came into play. If I just wanted to see the communications between the T4 and the ECU, I could just have plugged a single OBDII cable into a Y-splitter and listened in on the conversation rather than proxying it through another system, but I had written into my proxy server a rules system which allowed it to modify the messages it was forwarding. Rules were of the form “if you see a message like X, change field Y to Z”. This allowed me to edit the responses from the car to the T4 live during a session, to work out which fields in the responses were conveying which information to the T4. This was particularly important for decoding all of the live data screens in the T4 as a lot of the values were either very similar (e.g. “Coolant Temperature” and “Coolant Temperature Direct Reading” – one of which was the actual sensor value and the other was the value used by the ECU, which would only be different in the case of a failed sensor where the ECU was substituting an estimated value) or single-bit flags, which there was no other obvious way of identifying. Being able to change the responses from the ECU meant that I could play around until I found exactly which bit / bytes / words caused the T4 to display my fake data.

At the end of the session, I had a rules file which acted as documentation of exactly where each piece of information was stored in the ECU responses, which was what I needed to implement my own T4-style live data and diagnostics system:

/ DEFAULT RESPONSE FOR UNSUPPORTED IDENTIFIERS

 

      service $7f data $21 msg $61 $5b $00 $00 $00 $00 $00 $00 $00 $00

 

/ ENGINE STATE

 

/   ELECTRICAL STATUS

 

      service $61 data $10 set word 1 14300   / Battery Voltage (In mV)

      service $61 data $10 set word 3 14300   / Battery Voltage Direct Reading (In mV)

      service $61 data $0f set byte 1 bit 1 0 / Ignition Switch Status (1=On, 0=Off)

      service $61 data $15 set byte 2 bit 1 0 / Fuel Pump Relay Drive (1=On, 0=Off)

      service $61 data $15 set byte 2 bit 0 0 / Main Relay Status (1=On, 0=Off)

      service $61 data $0f set byte 1 bit 5 1 / Security Link Status (1=High, 0=Low)

 

/   ENGINE STATUS

 

      service $61 data $14 set byte 1 bit 3 1  / Cranking Status (1=Cranking, 0=Not Cranking)

      service $61 data $14 set byte 1 bit 4 1  / Running Status (1=Running, 0=Not Running)

      service $61 data $14 set byte 1 bit 5 0  / Stopped Status (1=Stopped, 0=Not Stopped)

      service $61 data $11 set word 4 2700     / Crankshaft Rotational Position (In 0.1°)

      service $61 data $06 set word 9 2500     / Engine Speed (In RPM)

      service $61 data $51 set byte 23 bit 0 1 / Flywheel Adaptation (1=Adapted, 0=Not Adapted)

      service $61 data $15 set byte 2 bit 2 0  / Engine Warning Light Status (1=On, 0=Off)

 

/   ENGINE SYNC

 

      service $61 data $11 set byte 1 bit 1 1 / Crank Sync Fault (1=Sync Lost, 0=Sync OK)

      service $61 data $11 set byte 1 bit 0 0 / Cam Sync Fault (1=Sync Lost, 0=Sync OK)

      service $61 data $11 set byte 1 bit 2 1 / Historical Sync Loss Faults (1=Faults Logged, 0=No Faults Logged)

 

/   TORQUE

 

      service $61 data $5b set word 3 $8000    / Engine Torque ($0000-$FFFF=0-100Nm)

      service $61 data $5a set byte 15 bit 1 0 / Engine Torque Status (1=Positive, 0=Negative)

      service $61 data $5a set byte 15 bit 3 0 / Torque Transient Detected (1=Present, 0=Not Present)

 

/ ANALOG INPUTS

 

/   TEMPERATURES

 

      service $61 data $00 set word 1 3132  / Engine Coolant Temperature (In 0.1°K)

      service $61 data $00 set word 3 3132  / Engine Coolant Temperature Sensor Direct Reading (In 0.1°K)

      service $61 data $00 set word 5 3132  / Engine Oil Temperature (In 0.1°K)

      service $61 data $00 set word 7 3132  / Engine Oil Temperature Direct Reading (In 0.1°K)

      service $61 data $00 set word 9 3132  / Inlet Air Temperature (In 0.1°K)

      service $61 data $00 set word 11 3132 / Inlet Air Temperature Sensor Direct Reading (In 0.1°K)

      service $61 data $5d set word 29 3142 / Engine Bay Temperature (In 0.1°K)

 

/   PRESSURES

 

      service $61 data $06 set word 1 6000 / Inlet Manifold Pressure (In 0.01kPa)

      service $61 data $06 set word 3 6000 / Inlet Manifold Pressure Direct Reading (In 0.01kPa)

 

/ FUELLING

 

/   THROTTLE

 

      service $61 data $0f set byte 1 bit 0 1  / Throttle Status Method 1 (1=Open, 0=Closed)

      service $61 data $5d set byte 27 bit 1 1 / Throttle Status Method 2 (1=Open, 0=Closed)

      service $61 data $5d set word 9 1000     / Closed Throttle Voltage (In mV)

      service $61 data $06 set word 7 3000     / Throttle Potentiometer Voltage (In mV)

      service $61 data $08 set word 1 19000    / Throttle Angle (In 0.01°)

 

/   FUEL INJECTORS

 

      service $61 data $0c set word 5 3100  / Injector 1 Pulse Width (In μs)

      service $61 data $0c set word 9 3100  / Injector 2 Pulse Width (In μs)

      service $61 data $0c set word 13 3100 / Injector 3 Pulse Width (In μs)

      service $61 data $0c set word 17 3100 / Injector 4 Pulse Width (In μs)

      service $61 data $0c set word 19 1100 / Injector Deadtime Adaptation (In μs)

      service $61 data $3a set word 5 256   / Fuelling Service Adjustment (In μs)

 

/   LAMBDA CONTROL

 

      service $61 data $51 set byte 23 bit 3 1 / Oxygen Sensor Condition (1=Degraded, 0=Normal)

      service $61 data $15 set byte 2 bit 6 0  / Oxygen Sensor Heater Drive (1=On, 0=Off)

      service $61 data $56 set word 5 9000     / Upstream Oxygen Sensor Heater Current (In mA)

      service $61 data $56 set word 1 5500     / Upstream Oxygen Sensor Heater Duty (In 0.01%)

      service $61 data $55 set byte 5 bit 1 1  / Upstream Oxygen Sensor Switch State (1=Rich, 0=Lean)

      service $61 data $55 set byte 5 bit 2 1  / Upstream Oxygen Sensor Readiness State (1=Ready, 0=Not Ready)

      service $61 data $0a set word 3 900      / Upstream Oxygen Sensor Voltage (In mV)

      service $61 data $0a set word 5 900      / Upstream Oxygen Sensor Voltage Direct Reading (In mV)

      service $61 data $55 set word 1 100      / Upstream Oxygen Sensor Switching Frequency (In 0.01Hz)

      service $61 data $55 set word 3 100      / Upstream Oxygen Sensor Switching Time (In 0.01s)

      service $61 data $55 set word 6 9000     / Downstream Oxygen Sensor Applied Current (In 0.1mA)

      service $61 data $56 set word 7 9000     / Downstream Oxygen Sensor Heater Current (In mA)

      service $61 data $56 set word 3 6000     / Downstream Oxygen Sensor Heater Duty (In 0.01%)

      service $61 data $0a set word 9 890      / Downstream Oxygen Sensor Voltage (In mV)

      service $61 data $0a set word 11 890     / Downstream Oxygen Sensor Voltage Direct Reading (In mV)

      service $61 data $13 set byte 1 bit 0 1  / Fuel Feedback Switching Status Method 1 (1=Closed Loop, 0=Open Loop)

      service $61 data $55 set byte 5 bit 0 1  / Fuel Feedback Switching Status Method 2 (1=Closed Loop, 0=Open Loop)

      service $61 data $0a set word 1 9750     / Fuelling Correction Factor (In 0.01%)

 

/   EMISSIONS

 

      service $61 data $51 set byte 2 bit 2 1 / Catalyst State (1=Degraded, 0=Normal)

      service $61 data $57 set byte 7 bit 0 1 / Catalyst Test State (1=Complete, 0=Not Complete)

      service $61 data $57 set word 3 2500    / Catalyst Test Result (In mV)

      service $61 data $57 set word 5 3000    / Catalyst Test Limit (In mV)

      service $61 data $16 set word 1 5500    / Charcoal Canister Purge Valve Duty (In 0.01%)

 

/ IGNITION

 

/   IGNITION TIMING

 

      service $61 data $62 set word 1 50   / Ignition Timing (In 0.1° BTDC)

      service $61 data $5b set word 7 1000 / Ignition Torque Reduction Retard (In 0.1°)

      service $61 data $3a set word 1 -60  / Ignition Service Adjustment (In 0.1°)

 

/   IGNITION COILS

 

      service $61 data $0b set word 1 1100 / Coil 1 Charge Time (in μs)

      service $61 data $0b set word 3 1100 / Coil 2 Charge Time (in μs)

 

/   MISFIRE

 

      service $61 data $5a set byte 15 bit 0 1 / Misfire Detection Status (1=Possible, 0=Not Possible)

      service $61 data $5a set byte 15 bit 2 1 / Misfire Sensor Fault Status (1=Faults, 0=No Faults)

      service $61 data $52 set byte 1 110      / Misfire Count Cylinder 1 (Count)

      service $61 data $52 set byte 2 110      / Misfire Count Cylinder 2 (Count)

      service $61 data $52 set byte 3 110      / Misfire Count Cylinder 3 (Count)

      service $61 data $52 set byte 4 110      / Misfire Count Cylinder 4 (Count)

      service $61 data $5a set word 5 6000     / Misfire Catalyst Percent (In 0.01%)

      service $61 data $5a set word 7 6000     / Misfire Emissions Percent (In 0.01%)

      service $61 data $5a set byte 15 bit 4 1 / Rough Road Detected (1=Detected, 0=Not Detected)

      service $61 data $5a set word 9 1100     / Rough Road Value (In 0.01%)

      service $61 data $5a set word 11 1100    / Rough Road Events Range 1 (In 0.01%)

      service $61 data $5a set word 13 1100    / Rough Road Events Range 2 (In 0.01%)

      service $61 data $5a set word 1 1100     / Engine Roughness

      service $61 data $5a set word 3 1100     / Engine Roughness Threshold

 

/ IDLE

 

      service $61 data $5d set byte 27 bit 7 0  / Idle Speed Control Requested (1=Requested, 0=Not Requested)

      service $61 data $14 set byte 1 bit 0 0   / Idle Speed Control Status (1=Closed Loop, 0=Open Loop)

      service $61 data $5d set byte 27 bit 0 1  / Idle Speed Control Abort Status (1=Aborted, 0=Allowed)

      service $61 data $5d set byte 27 bit 5 0  / Idle Conditions Check (1=Conditions Met, 0=Conditions Not Met)

      service $61 data $5d set byte 27 bit 2 1  / Idle Stepper Movement Allowed (1=Allowed, 0=Not Allowed)

      service $61 data $5d set byte 27 bit 4 0  / Fast Idle Status (1=Completed, 0=In Progress)

      service $61 data $5d set word 3 825       / Idle Speed Control Set Point (In RPM)

      service $61 data $21 set word 1 100       / Idle Speed Error (In RPM)

      service $61 data $12 set word 1 125       / Idle Air Control Valve Position (In Steps)

      service $61 data $5d set word 7 32        / Idle Deadband Position (In Steps)

      service $61 data $5d set word 15 3500     / Idle Alternator Loading (In 0.01%)

      service $61 data $3a set word 3 1000      / Idle Speed Service Adjustment (In RPM)

 

/ VVC

 

      service $61 data $25 set word 1 2250 / VVC Inlet Cam Duration Requested (In 0.1°)

      service $61 data $25 set word 3 2370 / VVC Inlet Cam Duration Measured (In 0.1°)

      service $61 data $25 set word 5 7200 / VVC Inlet Cam Opening Angle (In 0.1°)

      service $61 data $25 set word 7 2000 / VVC Inlet Cam Closing Angle (In 0.1°)

 

/  FANS AND AIR CONDITIONING

 

      service $61 data $15 set byte 2 bit 4 1 / Radiator / Slow Fan Drive (1=On, 0=Off)

      service $61 data $15 set byte 1 bit 1 1 / Engine Bay Fan Drive (1=On, 0=Off)

      service $61 data $0f set byte 1 bit 6 1 / Air Conditioning Switch Status (1=On, 0=Off)

      service $61 data $0f set byte 1 bit 3 1 / Air Conditioning Request Status (1=Requested, 0=Not Requested)

      service $61 data $15 set byte 2 bit 3 1 / Air Conditioning Clutch Drive (1=On, 0=Off)

      service $61 data $15 set byte 2 bit 5 1 / Air Conditioning Condenser Fan Drive (1=On, 0=Off)

      service $61 data $0f set byte 1 bit 2 1 / Air Conditioning Fan Request Status (1=Requested, 0=Not Requested)

 

/ ROAD SPEED AND GEARBOX

 

      service $61 data $0d set byte 1 75       / Vehicle Road Speed (In km/h)

      service $61 data $5d set byte 28 bit 6 0 / Vehicle Movement Status (1=Moving, 0=Stationary)

      service $61 data $0f set byte 1 bit 4 1  / Gearbox Drive Neutral Status (1=Drive, 0=Neutral)

 

I also came away armed with copies of the transcripts of communications between the T4 and ECU for all of the other operations it could perform, allowing me to replicate them in MEMS Mapper. All of these were backed up by corresponding photographs of the T4 screen so I could correlate the data exchanges with the on-screen displays. Note that the T4 software completely takes over its host laptop and you don’t get access to normal operation system features as with regular PC applications, so we weren’t able to just take screenshots – all the captures were mobile phone shots:

ECU VARIABLES

One further side-effect of all of this is that I have subsequently been able to find the table in the ECU firmware that describes all of the above data records and messages. This table tells the ECU which memory addresses (variables) to include in each record, so by correlating the findings above with the definitions in this table, I’ve been able to identify the meanings of more than 100 variables in the ECU which will be a great help in future further disassembly and investigations. A small sample of this analysis is shown below:

Service $21 "Request Data By Local ID" Record Memory Locations for Firmware ksr3p004

This table decodes the raw records into fields with lengths and addresses. In places where larger fields are accessed in code as multiple smaller fields they have been subdivided.

These are then correlated with the known contents of these records from reverse engineering of TestBook T4 to identify the addresses of the corresponding variables.

Locations with known data contents are shown in green. Location sizes are shown in blue where larger fields are subdivided as described above.

Typ

$00

Address relative to the start of RAM $000000.

$40

Address relative to the start of firmware $110000.

$80

Address relative to the map pointer A5.

$C0

Address relative to the start of boot loader $100000.

else

Address relative to the pointer A1 passed into routine.

Address

ID

Cond

Count

Bytes

Typ

Len

Address

Bytes

Typ

Len

Address

Bytes

Typ

Len

Address

Bytes

Typ

Len

Address

Bytes

Typ

Len

Address

Bytes

Typ

$13318E

$00

$06

$0007

$0A

$38

$00

$02

$000A38

$04

$7E

$00

$02

$00047E

$0A

$04

$00

$02

$000A04

$04

$8E

$00

$02

$00048E

$09

$FE

$00

$02

$0009FE

$04

$7C

$00

Engine coolant temperature.

Engine coolant temperature direct.

Engine oil temperature.

Engine oil temperature direct.

Inlet air temperature.

$1331AE

$01

$06

$0001

$0A

$38

$00

$02

$000A38

$1331B6

$02

$06

$0001

$0A

$04

$00

$02

$000A04

$1331BE

$03

$06

$0001

$09

$FE

$00

$02

$0009FE

$1331C6

$04

$06

$0001

$09

$EC

$00

$02

$0009EC

$1331CE

$05

$06

$0001

$0A

$1A

$00

$02

$000A1A

$1331D6

$06

$06

$0005

$0A

$02

$00

$02

$000A02

$04

$7A

$00

$02

$00047A

$0C

$2C

$00

$02

$000C2C

$04

$98

$00

$02

$000498

$05

$40

$00

$02

$000540

Inlet manifold pressure.

Inlet manifold pressure direct.

Throttle potentiometer voltage.

Engine speed.

$1331EE

$07

$06

$0001

$0A

$02

$00

$02

$000A02

$133476

$08

$06

$0001

$0C

$2C

$00

$02

$000C2C

Throttle angle.

 

So what are the key new features I’ve implemented as a result of all of this?

LIVE DIAGNOSTICS

This allows for live display of DTC (Diagnostic Trouble Code) and live data. Unlike the live data screens of typical OBDII scanners, which provide access to maybe 15 key parameters only, this system gives real-time access to 108 different live data measures. The screenshot below was taken connected to an otherwise disconnected ECU on the bench, hence the alarming number of fault codes displayed.

The system has built-in data logging. You can see in the bottom right hand corner that it displays the number of records it has accumulated. At the end of a session you can save these to a CSV file. You can also limit the number of data measures updated using the check boxes provided to increase the refresh rate. For a small number of measures you can record around samples per second. With all 108 measures selected this slows down to around one sample every 2 seconds. I’m currently looking into defining custom records to allow even faster data logging, although I haven’t yet seen another system that has cracked this and the ECU, although clearly supporting this feature (I’ve seen the code for it), doesn’t seem to follow the KWP2000 standards for it, so I’m left having to try to reverse-engineer all of the ECU code behind it to work out how to use it. Hopefully that will come in a future release.

ZCS CODES

These are not much use on a Caterham, but on something like a Rover 75 or MG ZT they are critical. They are a set of alphanumeric codes, using BMW standards, which are programmed into every major electronic module on the vehicle and which describe in detail all of the options installed and configurations applied. They must match across the different ECUs for systems to function normally, so when putting a replacement ECU into a vehicle it’s important to able to recode it to the car. There was one area of the ECU’s EEPROM that I had previously decoded and which contained coding records for the VIN, Part Variant, programming date etc. but there was another similar looking area which I suspected worked in the same way (i.e. you can only add updated records and it records a permanent history of the vehicle’s coding) but I had no idea what it represented. Now I do! My tools now lets you enter the ZCS codes for your vehicle which are added as a new coding record. Note that all MG Rover vehicle ECUs have at least one set of ZCS codes, even on vehicles which do not actually make use of them. They may have more than one set if the vehicle has been upgraded at a dealer. ECUs originally supplied to Caterham do not have any ZCS codes at all, so that’s a sure-fire way of telling whether you have an original Caterham ECU or a Rover donor unit.

Again this screenshot is from a test ECU that I’ve been playing with, so it has rather an unusual number of previous codes.

As with the VIN coding records, you can clone the record from a file read from your old ECU when installing a new ECU.

93C66 PATCH

Not directly from the T4 session, and again not so much use on Caterham, but I’ve built into my Live Mapping patch the ability to read and write the 93C66 configuration serial EEPROM chip in the ECU. This holds all of the setting that the ECU can change during normal running, so things like adaptations, fault codes, immobiliser coding etc. For Freelander owners with the BMW EWS 3.D immobiliser system, which uses a complex rolling code, pairing an ECU with an immobiliser is difficult. This function allows you to truly clone an ECU, complete with all of its settings and configuration data. This means that the new ECU is already matched to your immobiliser and adapted to your engine.

IMMOBILISER STATUS

A while back I described a bench test rig, complete with cam and crank signal simulators, which I used when matching ECUs to immobilisers for people. One of the main drivers behind this was that it wasn’t possible to tell for sure if the pairing had worked (sometimes it doesn’t) without effectively running up the ECU and seeing whether it ran the injectors. MEMS Mapper now has a function to query the immobiliser status of the ECU directly. The immobiliser status is reported as one of the following:

·        Line high. The line from the immobiliser to the ECU is in a continuous high state. Either no immobiliser is installed or there is problem with the connection between the immobiliser and the ECU.  The engine is immobilised.

·        No code received. The ECU has not received a valid code from the immobiliser, or is in learning mode and has not yet learned an immobiliser code. The immobiliser may be armed. If the ECU is not in learning mode, the engine is immobilised.

·        Correct code received. The ECU has received the correct previously learned code from the immobiliser. The engine is cleared to start.

·        Incorrect code received. The ECU has received a valid code from the immobiliser, but it not the code previously learned by the ECU. The ECU is not paired with this immobiliser. The engine is immobilised.

·        Immobiliser status unknown. The ECU immobiliser status returned is not recognised by this application.

The last one is a catch-all in case there are other states that the ECU can report that I haven’t found yet.

FORCE OUTPUTS

This feature provides a proper way to test a lot of the engine actuators by telling the ECU to drive them. The ECU does place restrictions on what actuators you are allowed to force under different conditions, for example it won’t allow you to turn off the fuel pump with the engine running, but it will allow you to force the fuel pump to turn on when the engine is stopped for testing purposes:

For safety, although you can drive most actuators on or off continuously, the fuel injectors are just driven for a brief pulse each time they are selected.

SERVICE ADJUSTMENTS

The ECU allows you to apply blanket adjustments to the ignition timing and idle speed. In theory it supports the facility to apply a blanket injector duration adjustment too, although this is disabled on all ECUs designed for cars designed to run in unleaded petrol, so my application only allows you to update the ignition and idle speed service adjustments:

The ignition timing adjustments could be useful on an engine that was prone to detonation and pinking, either due to wear and tear and carbon build-up or where forced to operate on poorer quality fuel, in which case a small retard of the ignition timing may alleviate problem. You are limited to -6° (retard) to +3° (advanced). There shouldn’t be any need to advance the timing using this feature and doing so may lead to damage by causing detonation, rather than curing it, so be careful. The idle speed adjustment may be of use on Caterhams with lightened flywheels, or to reduce the Type 9 gearbox rattle at idle. The dialog does display any fuelling adjustment that has been applied to the ECU, but doesn’t let you change it.