Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

Tesla Wall Connector load sharing protocol

This site may earn commission on affiliate links.
So... OpenOCD tells me nothing:
Code:
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
   http://openocd.org/doc/doxygen/bugs.html
adapter speed: 2000 kHz
none separate
RCLK - adaptive
Info : RCLK (adaptive clock speed)
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!

From what I've read, I should see some IDs of available TAPs (Test Access Ports) at this point, but I've waited an hour, soft reset TWC, hard reset TWC, re-plugged Shikra board, etc.

Using Shikra board with openocd.cfg:
Code:
source shikra.cfg
transport select jtag
jtag_rclk 8

I can't find an openOCD config for 'TMS320' or 'piccolo'. In this thread, someone is asking for an OpenOCD config for a
TMS320vc5502 chip which may be similar to the TMS320F28034 chip in the TWC - at least they both start with TMS320 though I'm not sure if that implies they're in the same family. Anyway, at the end of the thread he says:
Now I found a hint, that the used JTAG protocol is called IceMaker (a next generation after a "classic" one, but before ICEpick) and it appears it doesn't use DR at all. Thus I'd need to see the data scanned out on IR.

I need to research what DR and IR are but my overall impression is that Texas Instruments has developed their own protocol that doesn't respond to standard JTAG queries. Even if that's not the case, I don't think anyone has written an OpenOCD configuration for any of the TMS320 chips which makes OpenOCD useless even if I can get it to display some TAP info.

I think the reason OpenOCD doesn't support these chips is that Texas Instruments released their own tool called Code Composer Studio (CCS) which knows how to interface with their chips using proprietary signals as well as how to talk standard JTAG to other chips on the board. CCS works with certain hardware like the XDS100V2 board mentioned earlier. I don't think it works with the hardware I bought. :mad::(:mad:

It sounds like CCS used to require a subscription but went free in 2015. The TMS320F2803x chip in the TWC is mentioned as being supported for flash writing here.
 
At least we now know for sure that the car can update the firmware of the UMC, likely also the TWC ?
Although it doesn't say if this is also possible with older models.
upload_2018-4-25_16-16-0-png.296630
 
  • Informative
Reactions: Ulmo
I'm new to this thread, was looking to load balance 2 HPWC's so they don't overload my house grid service (keep the average at 80% of max), and when running on a generator still allow some charging with leftover capacity. I wish I had the time to reverse engineer (I used to in the past) but unfortunately my time is very limited. That said, I thought I might share some thoughts/advice:

Since TWC 2's behavior is very similar to TWC 1, I don't think it's a hardware problem. My best guess is it's a factory or debug mode. Or just an unstable, bugged state caused by erasing something important in NVRAM.
Have you considered that you may have erased the TWC firmware (whole or partially) and it's expecting a new firmware to be loaded. Devices with upgradable firmware often have an erase command after which when rebooted you can only check the device hardware versions and write a new firmware (often protected by a checksum, sometimes cryptographically signed).

Each TWC has a two BYTE id ranging from 1 to 0xFFFF. Although the manual says only 4 TWCs can be linked together, there's nothing about the protocol that implies such a limit. I've never tried simulating 4 or more TWCs on a network so I'm not sure what would happen. I suspect normally the master TWC would show an error light when it detects more than 3 other unique ids, but if TWCManager is playing master, maybe there would be no limit? Slaves could also detect the presence of more than 3 other TWCs and show an error but I'm not sure if they do or not.
If all you need is many slaves, even if there is some limit enforced by slaves detecting each other, the simple solution seems to be multiple RS485 buses. The 3 slave limit may come from maximum allowed bus loading by the way, if you put more you are running at your own risk (since each slave independently terminates, too many slaves may just make the bus unreliable).

People keep suggesting JTAG, but according to this, posted in 2013:

Given all that, it seems really unlikely that Delta (maker of the boards in the TWC) left the chip containing the firmware unlocked. Unless, since TWC is designed to have upgradable firmware, maybe it's more likely to be unlocked?
I don't have specific information but you'd be surprised how much stuff like that in the industry ships unlocked.

From the spec sheet for the TMS320F28034 chip, it includes:

Even if, by some miracle, the chip is unlocked, accessing it without breaking something requires very careful use of JTAG commands and complete understanding of what you're doing:

Given all that, I consider JTAG to be a tool of last resort. One mistake and things may be unfixable. I wouldn't want to try to use OpenOCD on a Raspberry Pi because the pi is not designed to send signals at a reliable rate.
If you're going to access the microcontroller via JTAG, I would strongly suggest to use TI's development software. If it is unlocked, then you could read the image out, and if I was right above that you simply erased the other other TWC's firmware, you could fix it by writing the image you read to the broken TWC microcontroller via JTAG. TI software is probably free, you'd just need to get a supported JTAG interface (or a dev kit for that microcontroller that has one built in).

Hope this helps.
 
Last edited:
@whitex any idea what has changed in the charging protocols with the recent firmware update ?
Unfortunately I can only guess that is has something to do with temperature management. My Dec 2015 Gen1 HPWC has been working great up to full 80A on Model S as late as 2017, but throws an intermittent, undocumented (8 flashes) error when connected to a post March 2018 car (verified with 2 different new cars). The frequency of this intermittent error strongly correlates to car temperature (so outside temp, whether it has been driven recently, and how long it has been charging) - the hotter the car, the more it throws this error. The 2018 car works great with recent HPWC and even a 2017 Gen1 UMC.
 
Hi guys, I think I found kind of a "checksum", there is a sum of all bytes at the end (bits>7 cut off) e.g.:

c0 fb e2 03 5d 5f 00 00 00 00 00 00 00 00 a1 c0 fe
e2+03+5d+5f=1(a1)

c0 fc e1 03 5d 39 00 00 00 00 00 00 00 00 7a c0 fe
e1+03+5d+39=1(7a)

These are two reset messages from my EU 3-phase wall connector (also saw that the reset messages end with c0 fe instad only c0).
Also found out that every four hours there are idle message repeated three times from the master, e.g.:

c0 fc 1d 00 00 00 00 00 00 00 00 00 00 00 1d c0
("checksum" is 1d because all zeros in between)

Greetings,
TheNoOne

I realize this is an older thread, but I wanted to mention in the HEX decoding of the 9600 baud data that there is a ham radio protocol for communicating with a modem called KISS. The kiss frames begin and end with $C0. $FE is used as an escape character.
 
I'm catching up... but it strikes me... why not create a pilot signal spoofer? J1772 uses the duty cycle to indicate max current the car can draw. So if you use a Raspberry PI inline with the pilot signal(s) for each charger you could load share. This scheme would require the raspberry to measure the current and tweak each car's pilot signal. The beauty of this is that it would allow people to mix and match brands of EVSE equipment.
 
Still catching up guys.... so does the data in the rs485 steam indicate the current flow? In other words are some of the bytes in there telling how much the car is drawing? It strikes me that the Maxem literature says it can load share with your house and their controller might need to know how much the car is drawing. That or they simply configure the Tesla wall charger as slave and simply command it to throttle back when necessary.
 
Have you considered that you may have erased the TWC firmware (whole or partially) and it's expecting a new firmware to be loaded.

I can't have erased the whole firmware because it still behaves mostly like a TWC set to master mode. I can have TWCManager play fake slave and the broken TWC responds normally, other than it always reports state 02 (error state). I've mentioned I think I erased the TWC model information and perhaps other data, but any method I could think of that might restore them has failed.

If you're going to access the microcontroller via JTAG, I would strongly suggest to use TI's development software.

I ordered a CCS-compatible piece of hardware after my last post on the subject. It's shipping from China so not sure how much longer it will take to get here.
 
why not create a pilot signal spoofer?

This has been done by other companies such as eMotorWerks JuiceCard. It could be done with the pi as well but you would need a Pi in each TWC instead of one pi per 3 or more TWCs. You'd need some extra hardware to support the 12V pilot signal and it would be more risky in that if the software crashes or has a bug it could leave the car stuck charging at a high rate and the TWC couldn't stop it.

are some of the bytes in there telling how much the car is drawing?

Yes. You can read a summary of the protocol in the comments at the top of TWCManager.pl at github.
 
I can't have erased the whole firmware because it still behaves mostly like a TWC set to master mode. I can have TWCManager play fake slave and the broken TWC responds normally, other than it always reports state 02 (error state). I've mentioned I think I erased the TWC model information and perhaps other data, but any method I could think of that might restore them has failed.
It is possible that you overwrite some configuration parameters (like a model #) but still possible the firmware got messed up:
If the firmware is meant to be in field upgradable, it will have likely have 2 pieces
  1. Piece that handles communications on the bus, responds to commands -> not field-upgradable or it can only be upgraded from firmware #2 (the way I would have done it). I suspect that this firmware may reside in the OTP part of the flash of the TMS320F28034
  2. Piece that does the actual charging and all other functions - this would reside in the rewritable part of the flash
You might have nuked #2.

Either way, even the model # etc may be stored in the microcontroller, so if you were to copy the microcontroller non OTP flash image from a working TWC you might be able to fix it.


I ordered a CCS-compatible piece of hardware after my last post on the subject. It's shipping from China so not sure how much longer it will take to get here.
I meant get a kit from TI that allows you to read and write the TMS320F28034 chip, like TMDSDOCK28035 F28035 Piccolo Experimenter's Kit | TI.com

Btw, is the TMS320F28034 the one talking on the serial bus, or is there another microcontroller in there?
 
I meant get a kit from TI that allows you to read and write the TMS320F28034 chip, like TMDSDOCK28035 F28035 Piccolo Experimenter's Kit | TI.com

Btw, is the TMS320F28034 the one talking on the serial bus, or is there another microcontroller in there?

$130 for the Piccolo Experimenter's kit is more than I'm willing to spend. I bought this for $30 which is a clone of the board someone mentioned earlier was used by a Tesla tech to interface with an HPWC. It's also compatible with TI's Code Composer Studio and I linked earlier to a thread saying it can read/write to the TMS320F28034 chip if it's not locked.

TMS320F28034 is the largest chip inside the TWC. You can see photos and part numbers here. I have no idea what's talking on the serial bus or how to access the serial bus. I'm learning this hardware stuff as I go along.
 
I've added car API support. Thanks to gingerbeer for a primer on the API. My TWC benefactor requested I port the code to Python so the attached code is Python. I'll probably move the official github project to Python as well. If anyone would like to port changes back to Perl so we can maintain both languages, let me know.

I've been running it on my car for a few days, including through a period of clouds that kept starting and stopping charge. I'm pretty confident in its stability although I did just make a bunch of comment updates and a few variable name changes that might break something deeper than what I've tested since changes were made. Comment updates include details on Protocol 2. Also, this code is backwards compatible with Protocol 1 (though I can no longer test Protocol 1 without a Protocol 1 TWC).

There are some problems with using the car API tactic if you have more than one Tesla vehicle. If you plug one car into a TWCManager charger, and a second car into some other charger, if TWCManager needs to stop charging, it tells both cars to stop charging. If a second car is unreachable, it may prevent starting or stopping charge of a car plugged into the TWC. There is no way to know which car is plugged into which TWC so I'm not going to try to implement anything fancy with using the car API to check car charge percentage.

I never store the email/password that controls the car. Instead, it must be entered on the web interface. Once entered, it's sent to Tesla and they return a "bearer token" and a "refresh token" which we do store. Both are valid for 45 days and you can start that time period over by using the refresh token. TWCManager uses the refresh token to renew the 45 day period after 15 days.

The bearer token is kind of like a temporary password. If someone breaks into your TWC and steals the bearer token off the Pi and uses it within 45 days, they can do everything they can do with the real password except start the car. Tesla requires entering the real password to start the car. Unfortunately, you don't need the real password to unlock the car.

Python may be easier to read but it requires installing some extra libraries that Perl comes with, which may cause trouble in some installs. As long as you're using the version of Raspbian suggested in the installation manual, you shouldn't encounter errors.

To install:
  • Run these commands in the terminal:
Code:
sudo apt-get update
sudo apt-get install python3-pip
sudo python3 -m pip install pyserial
sudo python3 -m pip install sysv_ipc

  • Download the attached zip file.
  • Put TWCManager.py in ~/TWC and put index.php in / var / www / html
  • SSH into the Pi
  • Run screen -r
  • Ctrl-C to quit TWCManager.pl
  • Run ./TWCManager.py to test.
  • Once satisfied, run sudo nano /etc/rc.local and change TWCManager.pl to TWCManager.py
If you run the old TWCManager.pl script it will delete the bearer and refresh tokens from the settings file, in which case you will need to enter your password again in the web interface. Otherwise, you should never need to enter your password again unless you leave the car unplugged over 45 days. I can probably have TWCManager refresh the tokens even without the car being plugged in in a future update.
 

Attachments

  • TWCManagerCarAPI.zip
    38.9 KB · Views: 72
Last edited:
I was able to read the MCU using the JTAG connector. They did not set a security key so everything seems to be accessible. I'm not going to provide details on the process just to avoid anyone breaking their TWC trying to replicate my results, but if anyone needs that info and has a good reason, private message me.

It appears my two broken TWCs are broken because parts of the 1K OTP (One-Time Programmable) memory were altered. Sadly, OTP memory can't be changed once altered (technically I think any 1 bit can be changed to 0, but 0 can't change to 1) so I can't fix it short of removing the TMS320F28034 MCU and installing a new one, then writing correct firmware and OTP data on the new MCU. That's a risky task for someone that's never soldered the tiny pins of such a MCU. Plus I don't have great tools for desoldering it.

Good OTP looks like this (where ÿ is FF hex):

Code:
E.V.W.T.S.8.0.H.L.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA.1.7.I.0.0.3.9.3.9.9.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

Everything beyond that point is FF.

Corrupt OTP on protocol 2 TWC (where . is 00 hex):
Code:
E.V.W.T.S.8.0.H.L.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ....................ÿÿÿÿÿÿÿÿÿÿÿÿ....................ÿÿÿÿÿÿÿÿÿÿÿÿ....................ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA.1.7.I.0.0.3.9.3.9.3.ÿÿÿÿÿÿÿÿÿÿ

Corrupt OTP on protocol 1 TWC:
Code:
E.V.W.T.S.8.0.H.L.ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ....................ÿÿÿÿÿÿÿÿÿÿÿÿ....................ÿÿÿÿÿÿÿÿÿÿÿÿ....................ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA.1.6.G.0.0.0.1.8.1.4.ÿÿÿÿÿÿÿÿÿÿ......................ÿÿÿÿÿÿÿÿÿÿ......................ÿÿÿÿÿÿÿÿÿÿ......................ÿÿÿÿÿÿÿÿÿÿ......................ÿÿÿÿÿÿÿÿÿÿ......................ÿÿÿÿÿÿÿÿÿÿÿ.....................ÿÿÿÿÿÿÿÿÿÿë.0...................ÿÿÿÿÿÿÿÿÿÿ....ë.0...............ÿÿÿÿÿÿÿÿÿÿ....................0.ÿÿÿÿÿÿÿÿÿÿ....ë.0...............ÿÿÿÿÿÿÿÿÿÿ

In the first two cases, the TWCID is contained in the OTP written as 9.3.9.9. and 9.3.9.3. In other words, TWCID is written in ascii characters instead of binary, which seems odd. The entire flash is accessible in 16-bit sized 'bytes' (even though 'bytes' usually implies 8-bit), so 9. is actually a single, 16-bit byte with value 0x3900.

The odd thing is the p1 TWC has 1.8.1.4. where its TWCID should be, but it has never advertised 1814 as its TWCID. It started as 032E, changed to EB30, and later to EACC which is still what it's advertising. I searched the entire flash memory for a value of EACC in both binary and ascii and did not find it. EACC also does not exist anywhere in OTP. Even when it was advertising 032E, the FB19 RS485 command was returning A16G0001814 when interpreted as ascii, which implies the A.1.6.G.0.0.0.1.8.1.4. section of the OTP didn't get altered. So I don't understand where TWCID is actually stored. My only theory is that in p1 firmware, the TWCID was somehow obfuscated such that 1814 translates to 032E and that corruption in the OTP is causing a different part of OTP to be interpreted as the TWCID, and when un-obfuscated that results in EACC. Very mysterious.

Anyway, the rest of FLASH memory (the firmware) is identical between the broken and unbroken p2 TWCs, and boot ROM is identical, so I'm pretty sure it's the changes to OTP that are breaking them. The p1 TWC has different firmware, but that's expected since its protocol is different.

I have some ideas of ways I might fix the broken TWCs by hacking the firmware slightly to bypass reading OTP but I haven't tried writing firmware back yet. I need to research if that can be safely done while the TWC is running or what (anyone know?).
 
Last edited: