Tesla Model 3 Charge Port Controller Standalone Development
Posted: Sat Sep 26, 2020 1:17 am
As discussed in my BMW 330 thread, Damien and myself will work on producing a combination of hardware (Damien) and software (me) to control the CP ECU outside of a Tesla. Due to firmware differences, it is highly recommended to get a unit that was in a 2019 or newer vehicle, as 2018 US vehicles may not support the CHAdeMO adapter.
What does the CP ECU do?
The Charge Port ECU is the interface between a AC or DC charging station and the rest the vehicle. The CP ECU uses data from the BMS to communicate limits to the charging station for fast chargers, send VIN numbers to Tesla Superchargers, and tell AC sources when to turn power on and off in conjunction with the charger in the car.
What are the goals of this project?
Reading over the SimpBMS documentation, I think the correct output from this is a Charge Enable / AC Present signal. The rest of the design ideas I'm copying from my thread (here):
* Write code in a logical way, keeping thing as simple as possible, organized and attempt to catch unhandled scenarios.
* Keep the CP ECU happy.
* Provide Charge Enable signal when plugged in and ready to start charging (ie so SimpBMS can turn on the charger).
* Optionally provide contactor control for DC fast charge.
* DC Fast Charge via CHAdeMO adapter initially, hopefully CCS for EU units as well.
* RTC + battery to support scheduled charging.
* Support saving of configuration parameters.
* Simple / Advanced mode - Simple being Tesla SWCAN / J1772 AC only, Advanced handling contactors to switch between AC/DC.
ToDo:
* IVT-S integration to read voltages - In progress
* SimpBMS integration to read voltages
* EEPROM settings - In progress
* CHAdeMO adapter tests (I think done, but not 100% certain)
State of the Word as of 2021-01-30:
IVT-S tested on the CHAdeMO EVSE code, and looks to be fine. I'll add this in here soon. Working on the EEPROM, but I'm not familar with I2C, so this is slow going.
State of the World as of 2021-01-23:
CHAdeMO session logged on my Model 3, and it looks like there's nothing more to do on this end for a 96S NMC battery pack. Need to test CHAdeMO max voltage setting, but should work for mid voltage setups (350-430V). IVT-S library is coming along, I should be able to read values from a stock-configuration shunt, that will be tested soon.
State of the World as of 2021-01-09:
Voltage control is still not right, unclear what is wrong here. There are some CAN related fixes in progress with the code to try and handle it more efficiently.
State of the World as of 2020-12-16:
CHAdeMO adapter is working! Working on voltage control, current control is working.
State of the World as of 2020-12-02:
Moved software to use RTIC which is a scheduling framework in Rust. Working well, no more timeouts, and consistent timings. CAN driver timeout optimized to not give false alerts. Verified it wasn't just driver by going back to old code with new settings, still had timeout issues. Migrating to RTIC was the right thing to do.
State of the World as of 2020-11-24:
Did some initial CHAdeMO adapter tests. With 'baseline' firmware, it works to the point of where it will stay in standby. I don't have the proper setup created to test further yet. Older firmware US reports unsupported EVSE. Therefore it is recommended to get a unit from a 2019+ car (noted above now).
State of the World as of 2020-11-23:
Fault line reading still ignored. However, latch voltage control and CAN messages are sync'd, fixing an error. Older firmware US, and EU now working. Newer firmware works, but requires non-backwards-compatible changes to enable. Older messages don't break medium term firmware, but do break new firmware. Need to add configuration items to enable modified messages. Working on getting app CRC to match to a list of known values to switch to the new style.
State of the World as of 2020-11-16:
Latch control is working, fault line reading is implemented but currently ignored. Initialization takes a few seconds but is consistent and works. As a result of stability, the touch sensor (inductive door sensor) is working as expected now. Unfortunately no additional ECU support as of yet, working on EU support.
State of the World as of 2020-10-21:
Charging auto-start works now. Latch control being tested and fault line reading implemented. Created a utilities module with a common checksum routine. Fixed issue in said routine. Renamed some variables to be better (like hv_can instead of control_can). Disallowed any warnings in all files. Released redacted version of code on github.
State of the World as of 2020-10-12:
First draft of code written in Rust. Running on STM32F7 processor. Code is in similar state to 2020-09-25, as there have been no major logic changes yet, only porting of the code. Serial console improved with last 4 activity items with uptime timestamp, not just the most recent. Code has no warnings, and only 1 unsafe block that is used during initialization to turn on the TIM2 timer interrupt. Plenty of room for refactoring and optimization, but manual charge does work as expected.
State of the World as of 2020-09-25:
Code is written in C++, using little C++isms except for sed 's/struct/class' for the most part, and using the OO-wrapper on the FlexCAN library from Collin Kidder. Code is being built in Sloeber for Teensy 3.2 (SimpBMS board), which is Eclipse + 'magic' to make Arduino stuff work...but I can make it build via Makefile too. No .ino files (that is what the Sloeber magic part is for, handling .ino files), but still making use of the Arduino core library functions such as Serial.write().
Init code for CP ECU is weak. It definitely gets upset in certain situations. Having the door open makes it happy. :: shrug ::
State machine for Insert cable -> start charge not there yet. Insert cable -> idle -> start charge via serial command is working.
Serial console code is OK but too scattered. I should be able to rewrite things to pass in the needed data to the console.
Code will be rewritten in Rust for the STM32. The opinionated nature of the language, plus memory safety items, plus speed, leads me down this path.
This thread will track progress.
-Matt
What does the CP ECU do?
The Charge Port ECU is the interface between a AC or DC charging station and the rest the vehicle. The CP ECU uses data from the BMS to communicate limits to the charging station for fast chargers, send VIN numbers to Tesla Superchargers, and tell AC sources when to turn power on and off in conjunction with the charger in the car.
What are the goals of this project?
Reading over the SimpBMS documentation, I think the correct output from this is a Charge Enable / AC Present signal. The rest of the design ideas I'm copying from my thread (here):
* Write code in a logical way, keeping thing as simple as possible, organized and attempt to catch unhandled scenarios.
* Keep the CP ECU happy.
* Provide Charge Enable signal when plugged in and ready to start charging (ie so SimpBMS can turn on the charger).
* Optionally provide contactor control for DC fast charge.
* DC Fast Charge via CHAdeMO adapter initially, hopefully CCS for EU units as well.
* RTC + battery to support scheduled charging.
* Support saving of configuration parameters.
* Simple / Advanced mode - Simple being Tesla SWCAN / J1772 AC only, Advanced handling contactors to switch between AC/DC.
ToDo:
* IVT-S integration to read voltages - In progress
* SimpBMS integration to read voltages
* EEPROM settings - In progress
* CHAdeMO adapter tests (I think done, but not 100% certain)
State of the Word as of 2021-01-30:
IVT-S tested on the CHAdeMO EVSE code, and looks to be fine. I'll add this in here soon. Working on the EEPROM, but I'm not familar with I2C, so this is slow going.
State of the World as of 2021-01-23:
CHAdeMO session logged on my Model 3, and it looks like there's nothing more to do on this end for a 96S NMC battery pack. Need to test CHAdeMO max voltage setting, but should work for mid voltage setups (350-430V). IVT-S library is coming along, I should be able to read values from a stock-configuration shunt, that will be tested soon.
State of the World as of 2021-01-09:
Voltage control is still not right, unclear what is wrong here. There are some CAN related fixes in progress with the code to try and handle it more efficiently.
State of the World as of 2020-12-16:
CHAdeMO adapter is working! Working on voltage control, current control is working.
State of the World as of 2020-12-02:
Moved software to use RTIC which is a scheduling framework in Rust. Working well, no more timeouts, and consistent timings. CAN driver timeout optimized to not give false alerts. Verified it wasn't just driver by going back to old code with new settings, still had timeout issues. Migrating to RTIC was the right thing to do.
State of the World as of 2020-11-24:
Did some initial CHAdeMO adapter tests. With 'baseline' firmware, it works to the point of where it will stay in standby. I don't have the proper setup created to test further yet. Older firmware US reports unsupported EVSE. Therefore it is recommended to get a unit from a 2019+ car (noted above now).
State of the World as of 2020-11-23:
Fault line reading still ignored. However, latch voltage control and CAN messages are sync'd, fixing an error. Older firmware US, and EU now working. Newer firmware works, but requires non-backwards-compatible changes to enable. Older messages don't break medium term firmware, but do break new firmware. Need to add configuration items to enable modified messages. Working on getting app CRC to match to a list of known values to switch to the new style.
State of the World as of 2020-11-16:
Latch control is working, fault line reading is implemented but currently ignored. Initialization takes a few seconds but is consistent and works. As a result of stability, the touch sensor (inductive door sensor) is working as expected now. Unfortunately no additional ECU support as of yet, working on EU support.
State of the World as of 2020-10-21:
Charging auto-start works now. Latch control being tested and fault line reading implemented. Created a utilities module with a common checksum routine. Fixed issue in said routine. Renamed some variables to be better (like hv_can instead of control_can). Disallowed any warnings in all files. Released redacted version of code on github.
State of the World as of 2020-10-12:
First draft of code written in Rust. Running on STM32F7 processor. Code is in similar state to 2020-09-25, as there have been no major logic changes yet, only porting of the code. Serial console improved with last 4 activity items with uptime timestamp, not just the most recent. Code has no warnings, and only 1 unsafe block that is used during initialization to turn on the TIM2 timer interrupt. Plenty of room for refactoring and optimization, but manual charge does work as expected.
State of the World as of 2020-09-25:
Code is written in C++, using little C++isms except for sed 's/struct/class' for the most part, and using the OO-wrapper on the FlexCAN library from Collin Kidder. Code is being built in Sloeber for Teensy 3.2 (SimpBMS board), which is Eclipse + 'magic' to make Arduino stuff work...but I can make it build via Makefile too. No .ino files (that is what the Sloeber magic part is for, handling .ino files), but still making use of the Arduino core library functions such as Serial.write().
Init code for CP ECU is weak. It definitely gets upset in certain situations. Having the door open makes it happy. :: shrug ::
State machine for Insert cable -> start charge not there yet. Insert cable -> idle -> start charge via serial command is working.
Serial console code is OK but too scattered. I should be able to rewrite things to pass in the needed data to the console.
Code will be rewritten in Rust for the STM32. The opinionated nature of the language, plus memory safety items, plus speed, leads me down this path.
This thread will track progress.
-Matt