DIY Electric Car Forums banner

Elcon/TC Charger Firmware: Facts

39653 Views 28 Replies 3 Participants Last post by  pdove
Minimal Discussion!

Please direct all discussions to the Elcon/TC Charger Firmware: Discussion thread.

Obsolescence Notice
This topic refers to the oldest range of Elcon/TC charger hardware, those manufactured with Elcon or TC branding prior to December 2013.
However, Elcon branded PFC models (not the UHF models) seem to retain the same basic design and processor chip.
From 2014 onwards, the TC branded HQ and later models use a different processor altogether
(a 32-bit ARM based processor, compared to an 8-bit 8051 based one).
As a result, this topic DOES NOT APPLY to the following models: UHF models, or TC branded PFC models manufactured 2014 or later.
As far as I know, no work has been done on the firmware for the models with the ARM based processor.​



This thread is intended to discuss just the FACTS of Elcon/TC charger firmware.

History and acknowledgement.
Legal.
The processor.
Reading the firmware.
User selection.
Hardware for reading/writing firmware.
Writing the firmware.
Understanding the firmware:

Serial data contents.

EEPROM contents.
Building new firmware.
Flashing new firmware.
The comparator.
Firmware downloads

  • The Calibrator for setting the value of EEPROM contents.
    UniCAN: the (almost) Universal CAN bus firmware.
See less See more
21 - 29 of 29 Posts
Flashing New Firmware.

The final step is to program the compiled and linked image into the microcontroller's flash memory. There are several ways that this can be done in the NXP processors; here we use the In Circuit Programming (ICP) technique.

To do this, we have to reset the processor, and pulse the PDA and PCL signals. The same hardware is used as for reading the flash program, just using different ICP commands. In fact, we use the same Arduino program, using different commands to that user interface. The main menu is as follows:

Code:
[FONT=Courier New]h - Command help             d - Read ID
u - Read User Configuration  v - Read Boot Vector & status
f - Write user config UCFG1
w - Write boot vector        b - Set Status Byte
c - Clear Security Byte      g - Erase Global
r - Read Security Bits       m - Read Memory
e - Erase Sector 7           K - Clear Configuration Protection
G - Global CRC               P - Page CRC
S - Sector CRC
R - Enter ICP                o - Ordinary reset to user code
i - prog memory dump         j - prog  EEPROM peek
k - read max current EEPROM  l - write max current EEPROM
a - Clear Status Byte        p - program from hex file
[/FONT]


After entring ICP mode with the R command (it may take a few goes), the 'p' command should be selected. After entering 'Y' to "Are you sure?", the Arduino will then be waiting for a valid hex program. You should turn off local echo if it's on at this point. Next, from your terminal program, select the command to send an ascii file. For Tera Term, this is the File Send File command. Choose the hex file, and press OK. Any problem, and the Arduino will display "?". If the program loads correctly, it will display "Done!". The image is being programmed as it is sent, so if there is an error, you will have an incomplete image. The program erases while writing, so there is no need to bulk erase the image first. When you see the "Done!" message, the image should in fact be sent. Use the 'o' (ordinary reset) command to reset the microcontroller in the charger, and you should see the front panel LED flashing indicting that the new firmware is running.

The file ICP.zip containing the Arduino program is in this post: Hardware for Reading/Writing the Firmware .
See less See more
The Comparator

Edit 2018/Aug/01: I had this wrong, because I had reversed the mode bits for port 0.

I thought I'd document something that's bothered me for some time, and I believe I've just sorted it out.

There are two comparators in the processor; one is unused. The first one, comparator one, is configured with the negative input connected to the scaled DC output measurement using the CMPREF pin (pin 22), and the other input (CIN1B, pin 24) is connected via an RCRC network to the OCD output (PWM channel D output, processor pin 2).

This latter PWM channel is supposed to be the "voltage set point", fDC_VOL_SET. So the output will go low if the negative input is higher than the positive input, i.e. the DC output voltage is higher than the set point.

The comparator output (CMP1, pin 20) is connected to current error comparator (U6, the half whose output is pin 7) in such a way that it would override the current control itself, which happens through OCB (PWM channel 1, processor pin 5). (See attached schematic fragment.) How does this work? It turns out that while the comparator output is configured on, pin P0.6/CMP1/KBI6 is configured as an open drain output. In other words, it can pull low, but not push high. So when the output of the charger is higher than the voltage set point, the current is throttled to zero. When the output voltage is less than the set point, the comparator output does not affect the requested current (from PWM output OCB) and the current is controlled as normal.

As of 2018/Aug/01, I'm not sure if the below applies or not; I keep it for future reference.

It turns out that there are two special function register bits (CMP1.0 and CMP1.1) that give whether the comparator output has changed, and the present state of the comparator output. The latter isn't used, but the changed bit is used. In fact, it's used just once (though cleared twice).

The voltage setpoint is only ever set to zero, or the maximum possible voltage, or to the battery voltage when about to turn on the output relay. When set to zero, the charger is in state zero, and the output relay is off, so the charger isn't charging. When the voltage setpoint is set to the maximum possible, the comparator is effectively disabled (the output will never change). However when charging is started, it seems to be assumed that the battery voltage will only ever go up. So if there is a change, then it is assumed that the battery voltage has decreased. When charging normally (not in state 0, not started yet, or state 8, charging complete), the comparator changed bit is checked. If it is set, then the current is compared with the maximum charger current divided by 40. (For example, on a charger capable of 15 A output maximum, the current is compared with 0.375 A). If lower than this, then something special happens.

In a CAN model, which only has three states, it transitions to state 0 (stops charging and disconnects the output relay). On non CAN models, it transitions to a new state based on the current state, using an entry in the "curve" array that I've labelled cv_LineCutToState. So I think that at each stage, you can determine which state to jump to in this condition, which seems to be referred to as the "line cut" state. I think they imagine this can only happen if the output cable to the battery is cut, or a battery link or cell goes open circuit, or a similar catastrophic failure.

Attachments

See less See more
4
I found that the original serial adapter had too much strain on the Veroboard tracks, which lifted and became intermittent. After a few fiddlings with this, I decided to mount the D9 connector vertically, and siliconed it to the board. Somehow, I didn't use much (that's not like me, I must have had an off day :) So that one failed recently as well.

There are only about 5 parts in the circuit, 7 if you count the two diodes, so I figured I could Christmas Tree them into a DE9 connector shell, and "pot" them with my beloved silicone. I sure hope this one lasts.

Edit: the power supply is only needed for debugging the control board with the charger switched off. The 12 V from the power supply is regulated down to 3.3 V for the charger's processor and it's associated parts. So it's rarely needed.

Attachments

See less See more
I've belatedly noticed that IAR Embedded Workbench for 8051, while not free, costs nothing to download a size-limited "trial" version, and the software presented here for generating new firmware could presumably be adapted to this development environment (really, only the assembler and linker are needed; possibly the C compiler solely for floating point convenience).

It would make the whole process of firmware generation much tidier and simpler. Unfortunately, with the change of processor in 2014, it's not worth it for me to pursue this. If you happen to have a bunch of these older chargers to use, and have the skills, it might be worth it for you to make the required changes. If you do, it would be great to publish the results here. But I suspect it will never happen.

[ Edit: while the TC branded Chargers changed processor in 2014, it seems that the Elcon branded chargers have not. So it seems that there are still plenty of chargers around with the old processor, so this effort seems worthwhile after all. ]
See less See more
8
It turns out that IAR Embedded Workbench for 8051 takes a bit of setting up for work with the chargers. I'll document them here before I forget some of them.

[ Edit: NOTE: most users won't have to worry about these, I'll eventually post the project and workspace files, which will have all these settings already set. ]

Start with Project / Create New Project... and click on Empty Project and OK. Add your assembler file (see other posts for examples) with Project / Add Files... . Use File / Save Workspace As... to save the workspace containing this one project.

Now use Project / Options to configure the project. See the first attachment. Select General Options in the Category box at the left of the Project Options dialog. Select the Target tab (see orange box for the tab), and work your way through the tree of options to get to NXP P89LPC938. Now select the Library Configurations tab (next row) and select "None".

Now choose Assembler in the Category box, and the Output tab. Deselect "Generate debug information". I like listings, so in the List tab I ticked "Output List File".

In the Build Actions category, enter the following into the Post-build command line box:
"$PROJ_DIR$\orderhex.bat" "$EXE_DIR$" "$PROJ_FNAME$"
All the quotes are needed.

In the Linker category, Config tab, tick "Override default program entry" and select "Defined by application".
In the Output tab, in the Output File group, tick "Override default" and change the filename extension to .hex. In the Format group, choose "Other", and set the "Output Format" to "intel-standard".
Finally, in the Diagnostics tab, under "Suppress these diagnostics", enter e78 . Click OK to save these settings.

You should now be able to choose Project / Make (F7) and there should only be a one or a few warnings about "Number out of range" (it's telling you that -2 doesn't fit into a byte). You should see "Performing Post-Build Action" in the Build window, and "Total number of errors: 0".

Edit: next time you want to start a new project with similar settings, copy Calibrator.ewp (the old project file) to the new folder, named as newproject.ewp. Close any existing workspace, choose Project / Add Existing Project... and add the new project. It will have the wrong assembly file; delete Calibrator.asm from the workspace bar at the left, and use Project / Add Files... to add the new assembler file. Use File / Save Workspace As... to save the new workspace. This saves setting up all these settings again. Copy orderhex.bat from the old project's folder to the new. It will not need modifying, as long as the project filename (apart from the .ewp extension) is the same as the assembler file name (apart from the .asm).

Edit 2: Don't put a period in the project name, like FoomakerV1.1. It confuses the assembler, which takes the first period as the end of the project or assembly language file name.

Attachments

See less See more
In the Linker category, Config tab, tick "Override default program entry" and select "Defined by application".
In the Output tab, in the Output File group, tick "Override default" and change the filename extension to .hex. In the Format group, choose "Other", and set the "Output Format" to "intel-standard".
Finally, in the Diagnostics tab, under "Suppress these diagnostics", enter e78 . Click OK to save these settings.
.
I had to go to Project / Edit Configurations and select Release in order to see the Linker category
Here is the first full firmware file set that you can assemble for free.

It's the Calibrator program, which is a temporary stand-alone firmware that you can program into any charger to change the EEPROM values. When would you need to use this? One time is if you have to replace the microcontroller chip. Its flash, but also its EEPROM, will be completely blank. This software will calculate approximate initial values for the EEPROM, then allow you to change them so that they do their jobs more accurately.

You should also use this whenever you change a component whose value is calibrated, for example one of the (usually) four voltage divider resistors for measuring the battery and charger output voltages, or any resistor that would affect the gain or quiescent output voltage of the current shunt amplifier, including the actual current shunt resistor(s).

You might also want to run the calibrator if you suspect that the voltage or current that the charger outputs is inaccurate. Finally, it might be useful for debugging a charger that isn't working properly, or that you are testing after a repair. You have good control over what the charger is doing with this software.

Requirements

The main hardware requirement is the same as for reading and writing other firmware. See Hardware for Reading/Writing the Firmware. That's either a USB in-circuit programmer, or an Arduino board with a small veroboard circuit.

You'll also need a way to connect to the serial port of the charger. This is detailed in Reading the serial data. That's something like a Prolific USB to serial adapter and a small circuit with a 7-pin round connector on the end.

A decent multimeter is needed to calibrate against. It needs to measure the battery voltage and current. A DC clamp meter is adequate for the latter, as long as the reading doesn't drift too much. You will need a battery to test the charger with. It doesn't have to be in a car; I use a set of 8 CALB cells that I have in the workshop that run some lights in my home. It's best if the battery voltage is near the upper limit of the charger, but anything down to 24 V nominal is adequate even for a 144 V nominal charger.

You'll also need a Windows computer with at least 2 USB ports. A communications program such as Tera Term is needed to send and receive serial data. Finally, you need Embedded Workbench for 8051, a free (no cost, not open source) development environment for 8051. It's only free for uses with certain restrictions, for example you can't use the C compiler unless the output file is under 4 KiB, but that doesn't matter as we only need the assembler and editor.

One last requirement: you'll need Cygwin installed with the BinUtils package. That's so that the post-build step can run the objcopy utility. See below for how to customise orderhex.bat to call it.

User Interface
When you run the Calibrator the serial port is connected at 2400 bps, 8 bits, no parity, 1 stop bit, and the "h" key is pressed:

Code:
Calibrator V1.2.22 Type h for help
h Help           Space Emergency stop
b Battery volts  c Current reading
v DC volts       s current Setting
                 z base current
e eeprom dump    r relay toggle
< less           > more
+ more current   - less current
0 zero current   d data dump
p Program eeprom o overWrite w/defaults
rb026.7 V
It is a simple menu based program like the program for programming the firmware (see other posts for details on that). The output at the bottom ("rb026.7 V") is dynamic, updated once per second. So make sure that your communications program processes carriage return without a linefeed.

The first "r" is lower case, indicating that the output relay is off. The second letter, "b", indicates that it's in "battery voltage" mode (use the "b" key to get back to this display if needed). The "026.7 V" indicates that the battery voltage reading is 26.7 V. If this agrees exactly with your multimeter reading, great. If not, use the "<" and ">" keys to correct the reading. This will change the values in RAM that will eventually be written to the EEPROM.

You can experiment with the other modes, e.g. "v" to read the charger output. If this is a high value, it might be because the base current reading is too high. Use the "z" key to enter base current mode, and adjust the base current down with the "<" key. Flip back to the "v" mode to see if it's affecting the charger output voltage. When it does, you'll know, as the output voltage will start falling from say 95% of maximum output towards zero, though it might take a minute to get there. As soon as it's lower than the battery voltage plus 10 volts, you will be allowed to turn out the output relay.

For the other calibrations, you will need to turn on the output relay with the "r" command. It takes about 3 seconds, during which time there will be no dynamic output. Use the "+" and "-" keys to increase and decrease the charge current. The "c" command will display the current reading, which can be calibrated with the "<" and ">" commands as before. There is also the "s" command, which shows what the charger is requesting. This can also be calibrated to agree with the multimeter reading. It's confusing at first, but this is necessary to separately calibrate the ADC and PWM EEPROM constants. You don't need to do this for voltage readings, because the same voltage divider is used for reading and setting voltage.

There are also commands to dump the EEPROM contents (really the RAM copy with the possibly changed values), and also some runtime data, mainly for debugging the Calibrator program itself.

When all is done, or to "save your work", use the "p" command to program the EEPROM. If you want to start from scratch with all guessed values, use the "o" command to overwrite the RAM copies with default values.

If the EEPROM contents aren't valid (e.g. a blank chip), or after you've used the "o" command, the data are marked as "not calibrated". All this means is that the first byte is other than hex C5. When the Calibrator starts, it will read the EEPROM values, and if the first byte is C5, it won't overwrite with guesses. If the first byte is other than C5, it will effectively do an "o" command and fill the RAM with guesses.

These guesses mainly come from some include files, so you have to assemble up a Calibrator program specific for your particular charger. I've come up with many values for many models, but you might be unlucky and have to write your own. The only two lines in Calibrator.asm you should need to change are near the start. At present, they look like this:

Code:
#define Model 145		// Mike's present test model
#include "Models_2000.inc"      // Use Models_1500.inc or 2000 or 2500
I've classified the models by power (1500, 2000, or 2500 watts), and the nominal maximum voltage, which seems to be the half-power maximum output voltage. For example, a 1500 W charger for a nominal 144 V battery has a half-power maximum output voltage of 203 V. If it's for a lead-acid battery, it will be called a 144 V charger. However, if it's a CAN model or a Lithium model, it will be called a 203 V max charger.

The first line specifies this voltage as a #define (here 145 V), and the power is specified as part of the include file name (here it's a 2000 W charger, so Models_2000.inc is used).

When you "compile" the software, it runs the assembler, and if there are no errors, it runs a post-compile build step. This is needed to "massage" the hex output into a contiguous format required by the ISP.INO program. If you are using a third party ICP programmer, you may not need this step.

Unfortunately, you might need to customize the batch file that implements this post-build step. It's called orderhex.bat, and it contains a line that must point to the folder where objcopy.exe resides. For most people, this will be in c:\cygwin64\bin, in which case no change is required. If you have a 32-bit computer or chose to install Cygwin in a different directory or drive, then edit orderhex.bat to point to the correct directory. If the post-build step works correctly, you'll have a file called Calibrator_ordered.hex in the Debug\Exe directory relative to where Calibrator.asm is located. This is the final firmware file to send to the charger. It should have a timestamp the same or later than Calibrator.asm and Calibrator.hex (the latter is also in the Debug\Exe directory). If you're not using the Arduino software, you can use Calibrator.hex and delete the post-build step (Project / Options / Build Actions / Post-build command line).

To get started, unzip the attached Calibrator.zip into a suitable directory and use File / Open Workspace to open the Calibrator.eww file.

Please direct any questions to the Elcon/TC Charger Firmware: Discussion thread. Remember to have the power off when using ICP.INO to connect to the charger with the "R" command.

Attachments

See less See more
"UniCAN" Firmware

This is another firmware file set. It will replace any CAN model firmware, or convert any fixed voltage charger to a "CAN" model. It is almost "universal" in that no changes are needed to the firmware if the charger is a single unit (i.e. it's a 1500, 2000, or 2500 W model). The firmware automatically makes adjustments based on the EEPROM values. A single byte can be changed (and of course the associated checksum) to make this suitable for a 2, 3, or 4 unit charger (3 kW to 8 kW models have 2, 3, or 4 1500-2500 W units paralleled in one enclosure). Alternatively, the firmware can be re-assembled for a 3000+ W charger. This firmware is suitable only for models with the NXP processor, which I believe is any 1500 / 2500 / 2000 W Elcon branded charger, and TC branded chargers manufactured before 2014.

NOTE: These Elcon chargers do NOT have a real CAN bus in the main enclosure; they implement control via a 2400 bps serial interface, using part of the 7-pin round connector. An external "CAN box" is required to convert these serial signals into real CAN bus signals. Some Battery Management Systems dispense with the actual CAN bus, and control these chargers directly via the serial interface on the 7-pin round connector.

NOTE: The serial signals are NOT RS-232. They are an opto-coupler interface, where idle = off/dark.

NOTE: At least older versions of the external "CAN box" could only handle up to about two CAN messages per second. That meant that the charger had to be the only device on the CAN bus (i.e. the charger required a dedicated CAN bus, and can't share the CAN bus with e.g. a motor controller). I do not know if later versions of the "CAN box" removed that restriction.

Requirements

The main hardware requirement is the same as for reading and writing other firmware. See Hardware for Reading/Writing the Firmware. That's either a USB in-circuit programmer, or an Arduino board with a small Veroboard circuit.

You'll also need a way to connect to the serial port of the charger. This is detailed in Reading the serial data. That's something like a Prolific USB to serial adapter and a small circuit with a 7-pin round connector on the end.

You'll also need a Windows computer with at least 1, preferably 2, USB ports. A communications program such as Tera Term is needed to send and receive serial data. Finally, IF you need to reassemble the firmware, then you also need Embedded Workbench for 8051, a free (no cost, but not open source) development environment for 8051. It's only free for uses with certain restrictions, for example you can't use the C compiler unless the output file is under 4 KiB, but that doesn't matter as we only need the assembler and editor.

One last requirement if you need to re-assemble the firmware: you'll need Cygwin installed with the BinUtils package. That's so that the post-build step can run the objcopy utility. See below for how to customise orderhex.bat to call it. Cygwin is also needed if you want to run the test program "elconsend".

Building

It is not necessary to build this software unless you want to make changes, or you have a 3000+ W model with more than one charge unit in one enclosure. (Even in the latter case, you could edit the ordered hex file for more than one charge unit. )

When you build the software, it runs the assembler, and if there are no errors, it runs a post-compile build step. This is needed to "massage" the hex output into a contiguous format required by the ISP.INO program. If you are using a third party ICP programmer, you may not need this step.

Unfortunately, you might need to customize the batch file that implements this post-build step. It's called orderhex.bat, and it contains a line that must point to the folder where objcopy.exe resides. For most people, this will be in c:\cygwin64\bin, in which case no change is required. If you have a 32-bit computer or chose to install Cygwin in a different directory or drive, then edit orderhex.bat to point to the correct directory. If the post-build step works correctly, you'll have a file called UniCANV1_1_ordered.hex in the Debug\Exe directory relative to where UniCAN_V1_1.asm is located. This is the final firmware file to send to the charger. It should have a timestamp the same or later than UniCAN_V1_1.asm and UniCAN_V1_1.hex (the latter is also in the Debug\Exe directory). If you're not using the Arduino software, you can use UniCAN_V1_1.hex and delete the post-build step (Project / Options / Build Actions / Post-build command line).

To get started, unzip the attached UniCAN_V1_1.zip into a suitable directory and use File / Open Workspace to open the UniCAN_V1_1.eww file.

Testing
I've also attached a simple program called "elconsend" that is useful for testing. It's a Cygwin application that allows you to send voltage and current requests to a serial port once per second. For example, to send 52.8 V and 1.8 A to the charger on COM6, use

./elconsend.exe COM6 52.8 1.8 <enter>

Use control-C to exit. C source code is provided; compile with gcc for Cygwin. To find out what serial port your USB to serial adapter is on, use a communications program such as Cygwin (but exit it before using elconsend).

Please direct any questions to the Elcon/TC Charger Firmware: Discussion thread. Remember to have the power off when using ICP.INO to connect to the charger with the "R" command.

Attachments

See less See more
Not sure where to add this but working with rjones he came up with a method to build new firmware without Keil

Building New Firmware

Installation
Install python3 (current version) at time of writing (July 2022) In some installations, the command ‘python’ below may have to be ‘python3’ instead. From the Widows Powershell prompt enter:

PS C:\path where you want to install> python --version Python 3.10.5
or
PS C:\path where you want to install> python3 --version Python 3.10.5

Add the following python packages needed by the commands;
pip install intelhex
pip install crcmod
pip install pyserial

PS C:\path where you want to install> python -m pip list

Package Version -------- -------
crcmod 1.7
intelhex 2.3.0
pyserial 3.5

Cygwin
Use cygwin installer to install python3
That install also installs pip tool
Run same pip commands as above

Decode
Help

PS C:\path where you have files and python scripts> python .\decodeHex.py -h

Decode Elcon hex file to a json configuration file
Usage:
python decodeHex.py [options] INFILE [OUTFILE]
Arguments:
INFILE Known good Elcon charger .hex file
OUTFILE name of json output file. If omitted then output will be written to INFILE.json

Options:
-h, --help this help message.
-v, --version version info.
-s, --silent Dont display decoded configuration

Typical use - verbose
PS C:\....insert your path\> python .\decodeHex.py 1500W_master_144V_4stage.ordered.hex

Read known good hex file: 1500W_master_144V_4stage.ordered.hex

Decoded configuration written to 1500W_master_144V_4stage.ordered.json
Output .json file is created with the curve parameters

Decode header
0xd76 0x14 20 charge_curve
0xd77 0x02 2 user_sel
0xd78 0x42c80000 100.0000 Ah capacity1
0xd7c 0x42c80000 100.0000 Ah capacity2
0xd80 0x42c80000 100.0000 Ah capacity3
0xd84 0x42c80000 100.0000 Ah capacity4
etc.

Copy the .json file and change the parameters as needed.
example; 1500W_master_144V_4stage.ordered_arsalan.json
Then use encodeHex.py to create a new hex with the new configuration.

Encode
Help

PS C:\Users\rjones\Documents\projects\ElconPFCChargerFW> python .\encodeHex.py -h
Encode Elcon hex file with a json configuration file
Usage:
python encodeHex.py [options] HEXFILE JSONFILE [OUTFILE]
Arguments:
HEXFILE Known good Elcon charger .hex file
JSONFILE Confguration .json file
OUTFILE name of hex output file. If omitted then output will be written to JSONFILE.hex

Options:
-h, --help this help message.
-v, --version version info.
-s, --silent Dont display configuration

Typical use - verbose

PS C:\your path> python .\encodeHex.py 1500W_master_144V_4stage.ordered.hex 1500W_master_144V_4stage.ordered_arsalan.json

Read known good hex file: 1500W_master_144V_4stage.ordered.hex
Read new json config file: 1500W_master_144V_4stage.ordered_arsalan.json

This will create new firmware with the new curve information entered in the .json file 1500W_master_144V_4stage.ordered_arsalan.json that you created.

The new firmware will be named 1500W_master_144V_4stage.ordered_arsalan.hex
See less See more
  • Like
Reactions: 2
21 - 29 of 29 Posts
Top