The ZombieVerter VCU Project
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Yeah I can probably make a table of some sort work. Will just be linear with a ramp function for initial testing. Regarding the Sam3 I had seen it back in stock thanks but I'm not going to pursue any more builds based on that part. The 105 is much more available and from what I can tell a more capable part. I mean I have it pumping out can on two channels, reading analogs, reading digitals , writing digitals , running 3 usarts , dmas, timer pwm timer schedular with 4 timed tasks and the processor load is not even 1%
I'm going to need a hacksaw
- mdrobnak
- Posts: 692
- Joined: Thu Mar 05, 2020 5:08 pm
- Location: Colorado, United States
- Has thanked: 1 time
- Been thanked: 5 times
Re: The ZombieVerter VCU Project
Nice. How are you calculating utilization?Jack Bauer wrote: ↑Wed Dec 23, 2020 6:13 pm I mean I have it pumping out can on two channels, reading analogs, reading digitals , writing digitals , running 3 usarts , dmas, timer pwm timer schedular with 4 timed tasks and the processor load is not even 1%
- mackoffgrid
- Posts: 94
- Joined: Thu Jan 02, 2020 10:18 am
- Location: Brisbane Australia
- Has thanked: 6 times
- Been thanked: 1 time
Re: The ZombieVerter VCU Project
I'm the same way. I've not bare metal-ed the SAM to see what it can really do , but I've invested in the STM32F1 line and similar to the 105, I've been using the 107, still in the Arduino environment but using a fair degree of bare metal coding.Jack Bauer wrote: ↑Wed Dec 23, 2020 6:13 pmThe 105 is much more available and from what I can tell a more capable part. I mean I have it pumping out can on two channels, reading analogs, reading digitals , writing digitals , running 3 usarts , dmas, timer pwm timer schedular with 4 timed tasks and the processor load is not even 1%
- johu
- Site Admin
- Posts: 6645
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 348 times
- Been thanked: 1506 times
- Contact:
Re: The ZombieVerter VCU Project
It's a function of the scheduler. It has a 100 kHz base clock so it can time its tasks with 10us resolution. So if a task recurring every 10ms uses 100us of time that is 1% cpu usage.
Time spent in terminal tasks and other interrupts is not accounted for if not handled separately.
For example the inverter firmware also tracks the time in the 8.8 kHz TIM1 irq which causes the most cpu load
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
- mdrobnak
- Posts: 692
- Joined: Thu Mar 05, 2020 5:08 pm
- Location: Colorado, United States
- Has thanked: 1 time
- Been thanked: 5 times
Re: The ZombieVerter VCU Project
Ok, that makes sense. When there's as scheduler that type of calculation is easy.johu wrote: ↑Wed Dec 23, 2020 9:30 pmIt's a function of the scheduler. It has a 100 kHz base clock so it can time its tasks with 10us resolution. So if a task recurring every 10ms uses 100us of time that is 1% cpu usage.
Time spent in terminal tasks and other interrupts is not accounted for if not handled separately.
For example the inverter firmware also tracks the time in the 8.8 kHz TIM1 irq which causes the most cpu load

- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Uhhh....Yeah! What Johannes said:)
E46 message module done , running and selectable. Now on to the big 7:)
E46 message module done , running and selectable. Now on to the big 7:)
I'm going to need a hacksaw
Re: The ZombieVerter VCU Project
I got the segger programmer this morning and still no luck in unlocking or communicating with the cpu. I then tried the uart method as it goes into boot mode, still no luck. Finally soldered to usart 2 still no response. Tried injecting in the 7f character with correct polarity etc.. nothing.
So I've ordered up a new cpu and will swap it over. Feel so stupid for disabling debug wire. I think something wired has happened the configuration of the cpu.
So I've ordered up a new cpu and will swap it over. Feel so stupid for disabling debug wire. I think something wired has happened the configuration of the cpu.
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Sent another two boards your way also but will probably get held up over Christmas.
I'm going to need a hacksaw
Re: The ZombieVerter VCU Project
Thanks for sending them on, I will keep them safe and return when I get the other board working here. I'm also a bit cautious as I don't want to brick another board, although I now have the SDW interface enabled, so hopefully, that won't happen. Thanks again
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
No problem at all. So folks we have the E65 Can done and selectable from the interface. Last piece of the puzzle will be the Gs450H module and I'll test in the cars and then post it up on Github where hopefully people who can actually code will help clean up my mess. I'm gonna break away for a few days and wish you all a Merry Christmas:)
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Dilbert, what freq are you running the psuedoclock and uart 2 baud?
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Also if we swap req and clk there is no need for any board mods as timer 2 can operate on PA1. So Req becomes clk and vice versa.
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Well, one of those days. Highs and lows. The highs of getting timer2 pumping out a nice juicy square wave and the lows of the dreaded DMA CONTROLLER!!! Anyway, we're into the GS450H module as you may have guessed and we are pumping out big chunks of data on usart2 via dma. Woohoo. Now I just gotta receive......anndd figure out why enabling an a dma interrupt on channel 7 (usart2 tx) kills channel 3 (usart3 rx) but hey it's all good fun.
Now, your first post Christmas pro tip : Can_E65::DashOn; complies just fine but doesnt do the same as Can_E65::DashOn();
Got me for two hours that one.....
Now, your first post Christmas pro tip : Can_E65::DashOn; complies just fine but doesnt do the same as Can_E65::DashOn();
Got me for two hours that one.....
I'm going to need a hacksaw
Re: The ZombieVerter VCU Project
Running 500khz or very close to... Using a pwm channel and letting it run.Jack Bauer wrote: ↑Sun Dec 27, 2020 10:05 am Dilbert, what freq are you running the psuedoclock and uart 2 baud?
Have pll x 4, so 32 mhz, but the adc needs a divider set on this....
Re: The ZombieVerter VCU Project
Jack Bauer wrote: ↑Sun Dec 27, 2020 10:16 am Also if we swap req and clk there is no need for any board mods as timer 2 can operate on PA1. So Req becomes clk and vice versa.
Good thinking on that...
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Okay, 500khz clock , dma send and receive and sync pulses all running away happy on the bench. Of course it probably won't work in a car but we'll soon see...
I'm going to need a hacksaw
Re: The ZombieVerter VCU Project
It's a pain my cpu is locked as I have the inverter beside my desk so could test the comms. I checked my CPU again it looks like the SWCLK pin is internally shorted to ground, so will need to swap over the CPU when the spare arrives from RS.
I've made up a cross over cable to flip req and clk pins signals, handy using cat 5 cables for testing.
I've made up a cross over cable to flip req and clk pins signals, handy using cat 5 cables for testing.
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Soo today was bug swatting and front end tidy up day. Now have both pos and neg scaled torque sending working for Leaf and GS450H inverters. Tied into the openinverter throttle handling so things like throtmax and min, ramp, dc current lim, temp lim etc are working. Few more days of this and it will be time to figure out how Johannes does that cool git link , make get-deps thingy....
Pro tip : When is 1 not equal to 1? when its equal to 32
Pro tip : When is 1 not equal to 1? when its equal to 32
I'm going to need a hacksaw
- johu
- Site Admin
- Posts: 6645
- Joined: Thu Nov 08, 2018 10:52 pm
- Location: Kassel/Germany
- Has thanked: 348 times
- Been thanked: 1506 times
- Contact:
Re: The ZombieVerter VCU Project
Nice work, nice mojo goingJack Bauer wrote: ↑Tue Dec 29, 2020 3:19 pm Soo today was bug swatting and front end tidy up day. Now have both pos and neg scaled torque sending working for Leaf and GS450H inverters. Tied into the openinverter throttle handling so things like throtmax and min, ramp, dc current lim, temp lim etc are working. Few more days of this and it will be time to figure out how Johannes does that cool git link , make get-deps thingy....

Oh yesJack Bauer wrote: ↑Tue Dec 29, 2020 3:19 pm Pro tip : When is 1 not equal to 1? when its equal to 32

Always wanted to make a fixed point class but it always came out more complicated than I thought. So stuck to the macros.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
- mdrobnak
- Posts: 692
- Joined: Thu Mar 05, 2020 5:08 pm
- Location: Colorado, United States
- Has thanked: 1 time
- Been thanked: 5 times
Re: The ZombieVerter VCU Project
Makefiles are mostly easy enough to figure out: You have targets, and commands to run at the target, and you specify their dependency on the same line as the target name. The big annoyance is, gotta use hard tabsjohu wrote: ↑Tue Dec 29, 2020 4:08 pmNice work, nice mojo goingJack Bauer wrote: ↑Tue Dec 29, 2020 3:19 pm Soo today was bug swatting and front end tidy up day. Now have both pos and neg scaled torque sending working for Leaf and GS450H inverters. Tied into the openinverter throttle handling so things like throtmax and min, ramp, dc current lim, temp lim etc are working. Few more days of this and it will be time to figure out how Johannes does that cool git link , make get-deps thingy....You could build your code on stm32-template that gets you make get-deps.
Oh yesJack Bauer wrote: ↑Tue Dec 29, 2020 3:19 pm Pro tip : When is 1 not equal to 1? when its equal to 32
Always wanted to make a fixed point class but it always came out more complicated than I thought. So stuck to the macros.

I re-recommend the git documentation: http://git-scm.com/doc which will end up helping you greatly in the long run.
As for 1 being 32....What's been quite disappointing is most errors you've mentioned have not been 'Well that's awfully silly, Damien' but items in which the compiler goes "yeah, that's allowed" even though expensive 3rd party tools would have been like "Are you _sure_ you meant to do that?" C is wonderfully powerful, but it leaves a LOT of rope lying around. I like that Rust yells at me (You can't divide an int by a float, for instance), and is like "You probably meant to do this: ..." and then I laugh and fix it.
Maybe when done run it through cppcheck? https://github.com/danmar/cppcheck - I'll try and jump on that (maybe add it as a Makefile target)
I'm am overall really happy for you and the progress you've made on this in a relatively short time. Keep up the good work!
-Matt
Re: The ZombieVerter VCU Project
This is the code that i developed for the GS450H, which just needs to be called from a 1mS task (or possibly interrupt). It needs the function calls converted over, but the timing should be correct.
void UpdateHTMState1Ms(void){
switch(htm_state){
case 0:
rx_buffer_count=0;
HAL_GPIO_WritePin(HTM_SYNC_GPIO_Port, HTM_SYNC_Pin, 0);
htm_state++;
break;
case 1:
HAL_GPIO_WritePin(HTM_SYNC_GPIO_Port, HTM_SYNC_Pin, 1);
if(inv_status==0){
HAL_UART_Transmit_IT(&huart2, htm_data, 80);
}
else {
HAL_UART_Transmit_IT(&huart2, htm_data_setup, 80);
if(mth_data[1]!=0)
inv_status--;
}
htm_state++;
break;
case 2:
htm_state++;
break;
case 3:
if(CalcMTHChecksum()==0 || rx_buffer_count!=100){
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1 );
}
else{
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0 );
//exchange data and prepare next HTM frame
dc_bus_voltage=(((mth_data[82]|mth_data[83]<<8)-5)/2);
temp_inv_water=(mth_data[42]|mth_data[43]<<8);
temp_inv_inductor=(mth_data[86]|mth_data[87]<<8);
mg1_speed=mth_data[6]|mth_data[7]<<8;
mg2_speed=mth_data[31]|mth_data[32]<<8;
}
mth_data[98]=0;
mth_data[99]=0;
htm_state++;
break;
case 4:
UpdateHTMParams();
if(counter>100){
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin );
counter = 0;
}
else{
counter++;
}
htm_state=0;
break;
case 5:
break;
}
}
void UpdateHTMState1Ms(void){
switch(htm_state){
case 0:
rx_buffer_count=0;
HAL_GPIO_WritePin(HTM_SYNC_GPIO_Port, HTM_SYNC_Pin, 0);
htm_state++;
break;
case 1:
HAL_GPIO_WritePin(HTM_SYNC_GPIO_Port, HTM_SYNC_Pin, 1);
if(inv_status==0){
HAL_UART_Transmit_IT(&huart2, htm_data, 80);
}
else {
HAL_UART_Transmit_IT(&huart2, htm_data_setup, 80);
if(mth_data[1]!=0)
inv_status--;
}
htm_state++;
break;
case 2:
htm_state++;
break;
case 3:
if(CalcMTHChecksum()==0 || rx_buffer_count!=100){
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1 );
}
else{
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0 );
//exchange data and prepare next HTM frame
dc_bus_voltage=(((mth_data[82]|mth_data[83]<<8)-5)/2);
temp_inv_water=(mth_data[42]|mth_data[43]<<8);
temp_inv_inductor=(mth_data[86]|mth_data[87]<<8);
mg1_speed=mth_data[6]|mth_data[7]<<8;
mg2_speed=mth_data[31]|mth_data[32]<<8;
}
mth_data[98]=0;
mth_data[99]=0;
htm_state++;
break;
case 4:
UpdateHTMParams();
if(counter>100){
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin );
counter = 0;
}
else{
counter++;
}
htm_state=0;
break;
case 5:
break;
}
}
- ggeter
- Posts: 135
- Joined: Wed Nov 18, 2020 1:56 pm
- Location: Houston, TX
- Has thanked: 4 times
- Been thanked: 26 times
Re: The ZombieVerter VCU Project
So, I ordered a v2 450h board that requires hand assembly by Damien (order 452 Dec 8). Should I wait on Zombie? I'm about four to six weeks away from needing a board, and can probably wait longer. Damien, what say you? If you haven't shipped my order yet, should I wait?
Houston, Texas, USA
EV Newbie
1979 MG Midget + GS450h = "Mexus?"
IT Consultant
EV Newbie
1979 MG Midget + GS450h = "Mexus?"
IT Consultant
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Perhaps I should have been clearer. This is a development project. It is not and will not be available for sale until such time as it has been tested in my vehicles. I'll update the first post with this notice. Regarding the order from ggeter it is packed and due for dispatch today.
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Matt, I did actually get the git book on kindle so need to start reading it I guess:)
I'm going to need a hacksaw
- Jack Bauer
- Posts: 3645
- Joined: Wed Dec 12, 2018 5:24 pm
- Location: Ireland
- Has thanked: 9 times
- Been thanked: 288 times
- Contact:
Re: The ZombieVerter VCU Project
Here is my ham fisted attempt to port Dilbert's HAL code over to libopencm3. It compiles and we have action on clk,req and htm. Delving into the refference manual to find the dma flags as we will need to know when dma rx has completed..........
Code: Select all
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Dilbert's code here
//////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t CalcMTHChecksum(void){
uint16_t mth_checksum=0;
for(int i=0;i<98;i++)mth_checksum+=mth_data[i];
if(mth_checksum==(mth_data[98]|(mth_data[99]<<8))) return 1;
else return 0;
}
void CalcHTMChecksum(void){
uint16_t htm_checksum=0;
for(int i=0;i<78;i++)htm_checksum+=htm_data[i];
htm_data[78]=htm_checksum&0xFF;
htm_data[79]=htm_checksum>>8;
}
void GS450H::UpdateHTMState1Ms(int8_t gear, int16_t torque)
{
dma_read(mth_data,100);//read in mth data via dma. Probably need some kind of check dma complete flag here
switch(htm_state){
case 0:{
rx_buffer_count=0;
DigIo::req_out.Clear(); //HAL_GPIO_WritePin(HTM_SYNC_GPIO_Port, HTM_SYNC_Pin, 0);
htm_state++;
}break;
case 1:{
DigIo::req_out.Set(); //HAL_GPIO_WritePin(HTM_SYNC_GPIO_Port, HTM_SYNC_Pin, 1);
if(inv_status==0){
dma_write(htm_data,80); //HAL_UART_Transmit_IT(&huart2, htm_data, 80);
}
else {
dma_write(htm_data_setup,80); //HAL_UART_Transmit_IT(&huart2, htm_data_setup, 80);
if(mth_data[1]!=0)
inv_status--;
}
htm_state++;
break;
case 2:
htm_state++;
}break;
case 3:{
if(CalcMTHChecksum()==0 || rx_buffer_count!=100){
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1 );
}
else{
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0 );
//exchange data and prepare next HTM frame
dc_bus_voltage=(((mth_data[82]|mth_data[83]<<8)-5)/2);
temp_inv_water=(mth_data[42]|mth_data[43]<<8);
temp_inv_inductor=(mth_data[86]|mth_data[87]<<8);
mg1_speed=mth_data[6]|mth_data[7]<<8;
mg2_speed=mth_data[31]|mth_data[32]<<8;
}
mth_data[98]=0;
mth_data[99]=0;
htm_state++;
}break;
case 4:{
// -3500 (reverse) to 3500 (forward)
if(gear==0) mg2_torque=0;//Neutral
if(gear==32) mg2_torque=torque;//Drive
if(gear==-32) mg2_torque=torque*-1;//Reverse
mg1_torque=((mg2_torque*5)/4);
if(gear=-32) mg1_torque=0; //no mg1 torque in reverse.
Param::SetInt(Param::torque,mg2_torque);//post processed final torue value sent to inv to web interface
//speed feedback
speedSum=mg2_speed+mg1_speed;
speedSum/=113;
uint8_t speedSum2=speedSum;
htm_data[0]=speedSum2;
htm_data[75]=(mg1_torque*4)&0xFF;
htm_data[76]=((mg1_torque*4)>>8);
//mg1
htm_data[5]=(mg1_torque*-1)&0xFF; //negative is forward
htm_data[6]=((mg1_torque*-1)>>8);
htm_data[11]=htm_data[5];
htm_data[12]=htm_data[6];
//mg2
htm_data[26]=(mg2_torque)&0xFF; //positive is forward
htm_data[27]=((mg2_torque)>>8);
htm_data[32]=htm_data[26];
htm_data[33]=htm_data[27];
//checksum
htm_checksum=0;
for(int i=0;i<78;i++)htm_checksum+=htm_data[i];
htm_data[78]=htm_checksum&0xFF;
htm_data[79]=htm_checksum>>8;
if(counter>100){
//HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin );
counter = 0;
}
else{
counter++;
}
htm_state=0;
}break;
case 5:{
}break;
}
}
//////////////////////////////////////////////////////////////
I'm going to need a hacksaw