ECU Coding: Ports v2

The engine control unit supports uploading code into RAM because that’s part of standard engine management software (ROM reflash) update procedure. I also use the transfer via CAN method as it is quite fast.
Actually, the ECUs stock firmware does not care about the uploaded bytes as long as generic conditions are met (max 12 KiB total size on diesels, checksum, …). That way you can abuse the system and do what you want. Did some relay/actuator testing lately, confirming some ports…

Tested ports

Valid for MY 2009/2010 Impreza Diesel Euro 4 only. Euro 5 models differ!

Port Type Function Comment
Port E
PE02 Out Radiator Fans both, low power
PE03 Out Radiator Fan left one only, high power
PE02 & PE03 Out Radiator Fans both, high power
PE11 Out Sub Fuel Pump noise originating from fuel tank area
PE12 Out A/C Compressor Clutch loud click noise, looking at pulley one can see clutch part move
Port L
PL06 In Brake SW Almost same trigger point (pedal position) as stop light switch.
PL07 In Stop Light SW

I already knew those output ports from ROM analysis so it was rather safe for me to try them. Just reading any port is supposed to be safe.
Many are reversed, then bit ‘0‘ means ON and ‘1‘ is OFF.
The MIL is what I often use for debugging ECU code – e.g. flashing it to indicate some condition. Unlike most dashboard indications you don’t operate it using CAN messages (much more complicated).
However, ports can be model specific so one must be careful – i.e. might hit the starter with transmission not in neutral.

C/C++ Code snippet to test and operate a port

// Port E Data Register, from Renesas manual
#define PE_DR_w (uword*)0xFFFFF754
// Port L Data Register
#define PL_DR_w (uword*)0xFFFFF75E

// port bitmasks
const uword PE14_MIL = 1 << 14; // 0x4000
const uword PL06_BrakeSW = 1 << 6; // 0x40

void OperatePorts()
  for(;;)  // infinite loop
    ToggleBits(PE_DR_w, PE14_MIL);  // toggle MIL
    uword pldr = *PL_DR_w;  // read Port L Data Register
    if ((pldr & PL06_BrakeSW) == 0)  // test bit
      Wait(100);  // Brake ON -> fast flashing of MIL
      Wait(1000); // Brake OFF -> slow flashing, 1000 ms delay

    /* alternative, set (true) or clear bits (false):
    AdjustBits(PE_DR_w, PE14_MIL, true); // OFF
    AdjustBits(PE_DR_w, PE14_MIL, false); // ON

void ToggleBits(uword* address, uword bitmask)
  *address ^= bitmask; // XOR


Questions: What software can I use to compile SuperH code? How much $$$?
Answer: Linux and utilities, all open source and free!

Free open source GNU compiler collection (GCC) can generate binaries for Renesas SH-2E, the microcontroller’s (e.g. SH7058S) CPU inside the engine control unit.
The beauty of GNU binutils plus GCC is, you can use the same toolchain to produce code for tons of different platforms1.
So same stuff I use for producing Intel/AMD PC x86/x64 software plus some platform specific command line options will do it. GCC is very powerful, supports multiple source code languages. (Personally, I even compile small Windows tools directly on Linux using winelib.)
Uploading a binary via CAN is another story but once it is automated, you don’t have to think about it, e.g. just run a make command…

1) Compiling binutils and GCC from source with target platform support enabled might be necessary. Default Linux packages usually have not been compiled with such special platform support enabled.

Display a list showing all architectures and object formats available for specification with -b or -m:
objdump --info


4 responses to “ECU Coding: Ports v2

  1. Hey …bit confused. What are you doing with this code snippet? How are you directly writing to ROM addresses through CAN?

    btw, been following your project for awhile — just wanted to say you’ve been doing awesome work! I have an ’08 NA Petrol Impreza. I developed a small test program in Linux (primarily using Qt though, so it may be x platform) to log SSM parameters over CAN using a cheap ELM327 cable, and its always good to see people working on similar things 🙂

    I saw the GUI in an earlier post as well — what library are you using for it?



    • There’s no easy way to write to ROM (reflash) and for those things I’m glad it’s not required.
      The ROM logic accepts uploading a binary into RAM and executes it there. My code is designed/compiled to work at required RAM target address. After ignition off + on cycle or reset via code, the uploaded stuff in RAM is gone/overwritten as the ECU executes its ROM code again. Now you could repeat the whole process if you wanted to.

      I am using GTK+ UI toolkit for most of the apps. There’s a wrapper called Gtk#, making it relatively easy to use Gtk+ in .NET languages. Could also use a Qt wrapper but these aren’t supported so well. Very few .NET apps seem to use Qt, no integrated UI designer in MonoDevelop IDE etc. I know Qt is great, might have more features but with .NET/Mono so far, Gtk makes more sense, I think. Needless to say I like Mono a lot.

      ELM327 specs from sure sound very interesting.
      Does your device come with J2534 drivers? Windows support only as usual?
      Guys like you could write a J2534 compliant lib (just the necessary stuff at least, like we did for OP20), then all kinds of apps (RomRaider, FreeSSM, …) could use it.
      We’d like to help in order to support more interface hardware. All of our software makes use of the J2534 API level, that way it does not depend on a specific cable.


  2. I absolutely love reading your posts, they are incredibly informative and the fact that you share your findings is very generous (and somewhat uncommon.)

    I had actually started to look for a way to turn the MIL on and off so that I could test my per-gear wastegate logic as well as indicate when FBKC/FLKC is incremented.

    Very interesting, keep up the great work!


    • THX, me and my fellows appreciate it, especially from people knowing how much work this all means.
      Obviously we don’t share everything (immediatly).
      First of all, publishing means additional work.
      Secondly, commercial guys should do their own homework – they make money, we don’t. Nothing against business, we’d cooperate, it’s a matter of ethics – just taking without giving back won’t work.

      Do you know MIL port for your model?
      On diesel MY08/09/10 MIL is PE14, pretty sure – same sub.
      Don’t know much about gas ROMs I’m afraid. Taking a glimpse at 2011 STi ROM, much of the code and the compiler itself look different compared to those diesel ROMs. Some struct defs look the same (table records for example), others do not.
      Diesel JZ2F401A: OperateMIL_PE14 sub @ 3494C
      Another way: if you have schematics you can look up ECU pin. On ECU PCB you might be able to trace this ECU pin to MCU pin = port (via amplifier and protection circuit I guess), then search for code that operates that port register …


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s