Feel free to use this thread for technical discussion regarding the communication interface for the Toyota/Lexus inverters, but please refer to the support thread above for any specific questions regarding the use of this controller.
Note that much of the information in this thread (especially in the earlier posts) may be outdated.
Hi all!
I originally posted this thread on the diyelectriccar forum, but was advised that it may be better suited in here.
I noticed that Damian has also recently been looking into these inverters by means of a custom control board. I'm hoping to establish communication with the factory controller to trick the inverter to thinking that it is still in the car. The hope is that I can take advantage of the work already done by Toyota in controlling this inverter.
I currently own a 2007 GS450h which I am using to source the data packets that are sent from the Hybrid ECU ("HV ECU")
I purchased a used GS450h motor drive unit ("transmission" / "gearbox") and an inverter as well at the end of last year. The inverter is sitting on my bench in pieces.
I also grabbed as much of the service data regarding these units as I could from lexustech.eu within a 1 hour subscription. Although a diyelectriccar user has also figured out the connector pins and typed it out so I don't have to:
This is useful info, when compared to the connector on the inverter unit (all pictures are click-for-big!):hilux.2sv;983945 wrote:We now have some more information after studying the wiring diagrams and DTC repair documents.
Signals from HVC-ECU to INVERTER/CONVERTER:
Pin 23/22 HTM+/- --> MOSI, differential using CAN transceiver, about 60...100 bytes (1.6ms), 120Ohm termination on both ends
Pin 21 DRN1 --> shield for HTM+/-
Pin 3/2 MTH+/- --> MISO, differential using CAN transceiver, about 60...100 bytes (~1.6ms), 120Ohm termination on both ends
Pin 1 DRN2 --> shield for MTH+/-
Pin 14/13 CLK+/- --> SCK, differential using CAN transceiver, about 500kHz, 120Ohm termination on both ends
Pin 12 DRN4 --> shield for CLK+/-
Pin 34/33 REQ+/- --> select from HV-ECU to INV/CONV, differential using CAN transceiver, about 3ms, repeated every 4ms (250Hz), 120Ohm termination on both ends
Pin 32 DRN3 --> shield for REQ+/-
Pin 25 HSDN --> emergency shutdown, from HVC-ECU (monitored for fault detection), high active, 3kOhm pull down resistor
Pin 36 DRN8 --> shield for HSDN
Pin 35 ILK1 --> interlock out to HVC-ECU, all okay --> low level, gnd
Pin 24 ILK0 --> interlock in from interlock switch, all okay --> low level, gnd
Pin 16 G1 --> petrol engine speed signal input, about 12,5Hz at idle
Pin 5 DRN5 --> shield for G1
Pin 10/11 +B/+B2 --> from IGCT2 relay (IG), fuse 10A
Pin 30/31 GND1/GND2

I pulled the unit apart to inspect the board. I drew a brief schematic for the relevant parts:

The board appears to use a proprietary transceiver, a DENSO SE617. There is no datasheet for this unit. I guessed the pin names from examination of the board.
A pair of 62R resistors with a capacitor to ground, and a common mode choke (actual part number is ZJY2401) provides the only protection and noise suppression.
The microcontroller used is a NEC 76F0080GC. Again, no datasheet or specs for this.
The 5V rail for the transceivers is shared with the microcontroller, the resolver-to-digital converters, and some other parts, here's a brief look at it, I didn't examine too far, I guess it's a buck converter from the 12v input. Not much in the way of noise suppression?

I'll likely piggyback off of this 5V supply for my own controller.
So, the control signals....
It first appeared to be SPI over LVDS. The Toyota names for the pins are likely alternate names for MOSI, MISO, CLK. However, in practice, whene examining the nature of the data stream, it does not follow the SPI standard.
- HTM = High-voltage ecu To Motor-generator ecu - since the HV ECU (the Hybrid ECU) in the car is the master, this is MOSI. This is the signal which we will need to replicate to control the inverter.
- MTH = Motor-generator ecu To High-voltage ecu - This is MISO. From this we get status updates back from the inverter.
- CLK = This is the SPI clock. The Lexus system uses a 500KHz clock. The data packets from MOSI and MISO don't generally exceed 100 bytes, and I've managed to get stable packets without overlap from as low as 250KHz. Data from MTH will output in time with this clock (on a rising edge)
- REQ = this is the status request line from the inverter. For the Lexus, this is a 1ms high pulse followed by a 3ms space, basically a 250Hz square wave at 25% duty cycle. In reality, the inverter outputs a packet of around 100 bytes whenever it detects the leading edge of a pulse, so a CS or SS line can be used to trigger this. The pulse can be half high for the duration of the packet, or as long as you like. One pulse = one packet.
When talking about high and low here, I am referring to the differential signal. Since these are normally inverting, in reality the microcontroller likely receives a low pulse to trigger a packet output.
I set up the inverter on the bench, and fed it the following:
- 12V to both 12V pins
- 0V to both 0V pins
- ILKI and ILKO both grounded (not sure this matters yet)
- HSDN to 12V (not sure this matters yet)
- Shorting wire in the interlock connector for the AC compressor (not sure this matters yet)
- 250KHz square wave to CLK+ and -
- 250Hz square wave at 25% duty cycle to REQ+ and -.
- Logic analyser to CLK, REQ and MTH. All 3 of the - line are tied together by this, they don't seem to mind (they really do mind if you do this on the car, however!)

The packet does not follows the SPI convention. Each "byte" has a start bit, 8 data bits, and a stop bit, as below:

The packet is 100 bytes wide, with many bytes being 0. A typical packet looks like below:
Code: Select all
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,11111111,11111111,
00000000,00000000,00100100,01100000,00000000,00000000,10011000,00000000,00000000,00000000,
00000001,11001000,01000000,00000000,00000000,00000000,00000000,10000000,00000000,00000100,
00000000,00000001,10000011,10111111,11111111,11111111,11111111,01101011,01010000,00000000,
00000000,00011000,10011000,00000000,00000000,00000100,01110010,11110001,00001000,00000000,
00000000,00000000,00000001,01001000,01000000,00000000,00000000,00000000,00000000,00000000,
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,
00000000,10000000,10100000,00000000,10000000,00000000,00011000,00000000,00011000,00000000,
00000000,11010111,10000000,00000000,00100000,11111111,00000000,01110011,00011011,10110000
After sampling a few hundred of these, it seems that the inverter output (for an inverter on the bench with no motor connected) is below:

I ran the same test with the inverter connected to the car. I am only able to connect to one of the 4 lines at a time, id I try multiple, the - lines ground through the logic analyser and causes the car to generate a DTC and disable the hybrid system. I tried using diodes on the grounds to allow for some separation, this worked, but the data I received was corrupt.
I'll attach an Excel file showing a few hundred packets of the inverter both on the bench and on the car. I also did the same to the HTM line, to see what the hybrid ECU sends the inverter on startup. As expected, the first few (hundred!) packets are unique, and then it seems to settle down. Again, it's in the spreadsheet.
Next up is to request torque from the motors (shift into R or D and move the car) and see how the states change.
I'm also starting to get parts together to talk to this unit with a microcontroller, rather than a signal generator and logic analyser. I purchased a TI SN65LVDT41PW LVDS Transceiver which contains 4x transmitters and 1x receiver.
I spent the next day looking into communication to this unit. From what I've seen/read online about SPI, it seems that SPI does not use start and stop bits. Also, SPI only transmits clock pulses as data is being requested. This unit accepts a "constant" clock, and outputs a 100 x 10-bit packet each time the REQ line is triggered. The clock runs constantly throughout. I also noticed that if the clock stops momentarily, the data keeps flowing without a clock pulse.
Because of this, I cannot read this as a SPI signal. My attempts to use a microcontroller set to transmit/receive SPI result in the microcontroller outputting 8 clock pulses, then a brief pause, then another 8 clock pulses, etc. This results in data being received, but the data is corrupt - the microcontroller just receives what was being sent at the time it attempted to read from the inverter. I've attached my code below.
Another interesting thing is that the inverter board waits for 39 clock pulses after receiving a REQ pulse, and starts to output on the 40th pulse.
I'm now looking at how to receive (and later transmit!) this bit stream. I can generate the clock pulses and REQ pulses easily, but to receive data synced to the clock pulses? 'm not sure how. I'm currently using a Teensy 3.2, the digital input pins are too "slow" to receive this data. Since the clock is at 500KHz, I'm currently looking to check for a 0 or 1 at my "data in" pin every 2us. The inverter sends data on a rising edge of the clock pulse.
All I really need to do is be able to grab this entire packet in a 1000-long array or similar, I can likely remove the start and stop bits and bit-shift the remainder into an array of integer variables afterwards.
Of course, I also need to be able to do the same in reverse, to talk to this unit.
Attached is the following images (click for big)
1. An overview of the data received.
2. A close-up of the start of each packet
3. A close-up of the middle of each packet, where things are more interesting than "00000000"
Note that since this is a differential signal, it is likely inverted, so the 1 11111111 0 you see in the first packet is actually "0 00000000 1". I am not using a differential transceiver right now, although I do have one on the way.



Below is the code used to attempt to read from this unit. The code does appear functional, although I'm not sure if this is the correct way to approach this! As mentioned above, the issue is:
- The inverter waits for 39 clock pulses before outputting data, following a REQ high signal.
- The inverter needs a constant clock, the code below produces 8 clock pulses, followed by a gap (presumably as the "for" loop runs)
- The inverter outputs start and stop bits, so each byte is 10 bits long, SPI expects 8, so everything gets shifted. This wouldn't worry me, I imagine this is fixable in code, but when running constantly, each 100-byte data packet is represented differently to the program - if it was consistent then things would be easier. I guess it's an issue with timing.
Code: Select all
#include <SPI.h>
#define req_pin 10
// MOSI: pin 11
// MISO: pin 12
// SCK: pin 13
//definitions
#define inverter_msg_length 100
//global variables
int inverter_msg[inverter_msg_length]={0};
void setup() {
Serial.begin(9600);
SPI.begin();
pinMode(cs_pin, OUTPUT);
//SPI.setBitOrder(MSBFIRST);
//SPI.setDataMode(SPI_MODE0);
//SPI.setClockDivider(SPI_CLOCK_DIV32);
delay(100);
}
void loop() {
digitalWrite(req_pin, 1); //send request
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
Serial.println("Start of transmission.");
for (int i=0;i<inverter_msg_length;i++) inverter_msg[i]=SPI.transfer(0);
SPI.endTransaction();
digitalWrite (req_pin, 0);
Serial.println("End of transmission.");
//print results
Serial.println("\t0\t1\t2\t3\t4\t5\t6\t7\t8\t9");
Serial.println(" ------------------------------------------------------------------------------");
for (int j=0;j<10;j++) { //print 10 rows
Serial.print(j*10);if(j==0)Serial.print("0");Serial.print(" |\t"); //row heading
for (int k=0;k<10;k++){Serial.print(inverter_msg[j*10+k]);Serial.print("\t");} //print 10 columns of data
Serial.print("\n");
}
//delay, so the serial monitor is readable for now
delay(500);
}
Of course, any knowledge on this subject would be greatly appreciated! I'm somewhat of a novice at programming, and have barely touched SPI, hopefully I'll be able to build something useable to control this unit!
Thanks
