Page 5 of 38

Re: The ZombieVerter VCU Project

Posted: Tue Jan 05, 2021 6:24 pm
by Dilbert
I wonder is it a scaling issue?

Re: The ZombieVerter VCU Project

Posted: Tue Jan 05, 2021 11:13 pm
by Dilbert
I might be looking at the wrong commit, but it doesn't seem to check the transfered flag, to confirm that the dma has happened. It's still looking at the rx_buffer_count variable.

Also maybe the code could be sending the htm_setup data to the inverter, possibly every second time. Could that explain the strange behavior.

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 7:42 am
by Jack Bauer
Has the hal version been verified working?

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 10:25 am
by Jack Bauer
Little progress this morning. Re did the dma so the loop now looks at the dma transfer complete interrupt flag before pulling out data. Annnndd we get a sane temp value displayed on the interface. Tried in the E65 and the tacho is quite jumpy despite the mgs not spinning. Same result with throttle. Vibration from the gearbox but no rotation.

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 2:06 pm
by Dilbert
Ok definitely something funny happening here.

Here's a link to it running off the STM32 using that state machine.

https://drive.google.com/file/d/1ndIS5_ ... sp=sharing

It doesn't run in the other direction when i press the button as my PSU didn't have enough current, the voltage was dropping right down. The temperature was cold too, so i'm guessing it was due to the oil being cold. I was able to get it going both directions by adjusting the power supply a bit.

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 3:16 pm
by Jack Bauer
Ah that's excellent! I'm just being an idiot with the software:)

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 3:47 pm
by Jack Bauer
Ok so this is where I'm at with the gs450h control routine and I'm encountering a problem that so far I've not been able to solve. So , after being a world class idiot with the interrupt and dma priorities I have them working away properly and the nvic system seems happy. Now, DMA1 Channel 3 is used by usart3 receive for the wifi interface. it does not use interrupts. I am using DMA1 Channel 6 and 7 for transmitt and receive on usart 2 for talking to the gs450h inverter. If I don't use interrupts but manually check and clear the transfer complete interrupt flags (TCIF) on channels 6 and 7 all is well from the perepective of the wifi interface. Now, If I enable one or the other or both interrupts on channels 6 and 7 , even if the isr does nothing then we dont receive any data on usart3 from the wifi. All the interrupts work as far as I can tell and the micro runs away happy but won't see any data on Usart3 from wifi. DMA1 Channel 3 is set to max priority, Channels 6 and 7 to lowest, Interrupts on 6 and 7 set to low or high priority makes no difference. Its probably not stopping anything working from a gs450h point of view but would be nice to know why:)

Any way, here is my latest on the 450h routine. More tests tomorrow :

Code: Select all

void GS450H::UpdateHTMState1Ms(int8_t gear, int16_t torque)
{


switch(htm_state){

case 0:{
dma_read(mth_data,100);//read in mth data via dma. Probably need some kind of check dma complete flag here
 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){
        if (dma_get_interrupt_flag(DMA1, DMA_CHANNEL7, DMA_TCIF))// if the transfer complete flag is set then send another packet
        {
        dma_clear_interrupt_flags(DMA1, DMA_CHANNEL7, DMA_TCIF);//clear the flag.
          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:{
    //
   // dma_get_interrupt_flag(DMA1, DMA_CHANNEL6, DMA_TCIF);
if(CalcMTHChecksum()==0 || dma_get_interrupt_flag(DMA1, DMA_CHANNEL6, DMA_TCIF)==0){
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1 );
statusInv=0;
}
else{
//HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0 );
//exchange data and prepare next HTM frame
dma_clear_interrupt_flags(DMA1, DMA_CHANNEL6, DMA_TCIF);
statusInv=1;
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;


}
}

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 4:29 pm
by mdrobnak
Jack Bauer wrote: Wed Jan 06, 2021 3:47 pm Ok so this is where I'm at with the gs450h control routine and I'm encountering a problem that so far I've not been able to solve. So , after being a world class idiot with the interrupt and dma priorities I have them working away properly and the nvic system seems happy. Now, DMA1 Channel 3 is used by usart3 receive for the wifi interface. it does not use interrupts. I am using DMA1 Channel 6 and 7 for transmitt and receive on usart 2 for talking to the gs450h inverter. If I don't use interrupts but manually check and clear the transfer complete interrupt flags (TCIF) on channels 6 and 7 all is well from the perepective of the wifi interface. Now, If I enable one or the other or both interrupts on channels 6 and 7 , even if the isr does nothing then we dont receive any data on usart3 from the wifi. All the interrupts work as far as I can tell and the micro runs away happy but won't see any data on Usart3 from wifi. DMA1 Channel 3 is set to max priority, Channels 6 and 7 to lowest, Interrupts on 6 and 7 set to low or high priority makes no difference. Its probably not stopping anything working from a gs450h point of view but would be nice to know why:)
Various pins share the same interrupt, as I'm sure you're aware. USART2 and 3 _should_ be on different pins (like PA2 vs PA3) but, I don't have the pinout in front of me. Unfortunately DMA / Interrupts are a bit messy. And in this case, Rust doesn't help one bit. :D Your only resource is: the programming guide. There's probably something in there that says something about clearing flags under certain circumstances. I've been told that the STM32 is powerful but a bit quirky. I guess it is true. ;)

I noticed you touched libopeninv/src/stm32_can.cpp - Ideally this change should go in that library. Over the weekend I think I'm going to put together (or find) a good guide on how to do a Pull Request (PR from now on) on Github.

This is why the way Johannes did it is slightly different - he is using git submodules, which allows you to keep track of items which you are using, but don't necessarily maintain. That way you're not inadvertently forking libraries. Unfortunately there's a little more to do than just "git clone" in this case, but it's not insane.

I'm more than willing to help with getting the repo stuff all set up.

-Matt

Re: The ZombieVerter VCU Project

Posted: Wed Jan 06, 2021 4:52 pm
by Dilbert
I think i'm going to have to do a side by side test with my STM32 code based on the HAL running on the demo board alongside the VCU running the new code. It will be Friday before i get to do this with the motor connected.

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 12:45 am
by mdrobnak
Paydirt 1:

Code: Select all

src/stm32_vcu.cpp:476:8: error: Array 'mTemps[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]
 mTemps[2] = TempMeas::Lookup(tmpmg2, TempMeas::TEMP_TOYOTA);
       ^
That's probably an issue. :)

-Matt

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 2:06 am
by mdrobnak
Attempting to build it yields problems.

1. The version of libopencm3 has issues with:
mdrobnak@dell-cp2-md-ubuntu:~/vcs/git/mdrobnak-stm32-vcu$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:9-2019-q4-0ubuntu1) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]

- This could be a python 2 vs python 3 thing.
Edit: Tried with newer version of python 3 version of scripts and still get:

Code: Select all

ake[1]: *** [../../Makefile.include:41: vector.o] Error 1
  BUILD   lib/vf6xx
  CC      vector.c
In file included from ../cm3/vector.c:22:
../../include/libopencm3/cm3/vector.h:41:10: fatal error: libopencm3/cm3/nvic.h: No such file or directory
   41 | #include <libopencm3/cm3/nvic.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~
2. After resolving that:

Code: Select all

mdrobnak@dell-cp2-md-ubuntu:~/vcs/git/mdrobnak-stm32-vcu$ make
  CPP     obj/stm32_vcu.o
src/stm32_vcu.cpp: In function 's32fp ProcessUdc()':
src/stm32_vcu.cpp:231:10: warning: unused variable 'udcmin' [-Wunused-variable]
  231 |    s32fp udcmin = Param::Get(Param::udcmin);
      |          ^~~~~~
src/stm32_vcu.cpp: In function 'void Ms100Task()':
src/stm32_vcu.cpp:517:27: error: 'Can_VAG' has not been declared
  517 |   if(Module_Vehicle==VAG) Can_VAG::SendVAG100msMessage();
      |                           ^~~~~~~
src/stm32_vcu.cpp: In function 's32fp ProcessThrottle()':
src/stm32_vcu.cpp:560:11: warning: unused variable 'throtSpnt' [-Wunused-variable]
  560 |     s32fp throtSpnt, finalSpnt;
      |           ^~~~~~~~~
src/stm32_vcu.cpp: In function 'void Ms10Task()':
src/stm32_vcu.cpp:660:5: error: 'Can_E39' has not been declared
  660 |     Can_E39::SendE39(speed, Param::Get(Param::tmphs)); //send rpm and heatsink temp to e39 cluster
      |     ^~~~~~~
src/stm32_vcu.cpp:655:10: warning: unused variable 'tmpm' [-Wunused-variable]
  655 |    s32fp tmpm = Param::Get(Param::tmpm);
      |          ^~~~
src/stm32_vcu.cpp: At global scope:
src/stm32_vcu.cpp:320:13: warning: 'void ProcessCruiseControlButtons()' defined but not used [-Wunused-function]
  320 | static void ProcessCruiseControlButtons()
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [Makefile:84: obj/stm32_vcu.o] Error 1
CAN_E39.h and CAN_VAG.h are missing.

Please do a `git status` in your main folder. I'd bet money it will say "Untracked files" present...probably with those filenames. ;)

Whenever you create a new file, please be sure to `git add <filename>` to make sure it's tracked. `git commit -a` DOES NOT include untracked files.

-Matt

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 6:38 am
by johu
I have recreated it, I think this should be copied over and updated with the latest commits: https://github.com/jsphuebner/stm32-vcu

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 6:55 am
by mdrobnak
There were definitely some things found by clang and cppcheck, but some of them are minor, and some of them I'm not sure about. The only major item was that incorrect index, which, incidentally was picked up by gcc as a warning. (We should probably do -Werror).

I'd say what I would like to see done is:
1. Fixup of the missing code.
2. Work from your repo which has it set up right. (Or fix Damien's copy)
3. Run clang-tidy on it to format the code in a standard fashion.
4. Get cppcheck running on PRs.
5. Help debug everything. :)

-Matt

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 8:00 am
by Jack Bauer
Ok I've added the missing files (i think...) and thanks for the pointers. I'm focusing on getting some motors spinning and cars moving then will be able to spend more energy on the git side of things.

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 2:17 pm
by Jack Bauer
Ok sports fans we have some progress. Dug my second GS450H gearbox and inverter out of hibernation , undid the mods to the logic board that I had done during reverse engineering and wired up a bench setup.

1)At very low torque input it works perfectly. Output shaft spins nice and smoothly and we get steady speed feedback on the wifi.

2)Once torque demand is increased the motor becomes very jerky. Its almost like the inverter looses sync, resets, sees a torque demand, pumps power into the motor then trips out. rinse and repeat.

3)Tested on 30v 2 amps psu, 60v 5amp psu and 160v battery. All the same.

4)Connected up my Saleae logic and did 3 captures : idle, smooth slow running and faster rough running. Attached in the zip.

Going to see If I can spot anything in the analyser captures.

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 3:40 pm
by Jack Bauer
Ok I have an idea of what's going on. Pouring over the analyser data shows that in idle we are spitting out the standard htmdata frame correctly, in slow and easy we are sending a correct torque request to mg2 but none to mg1 for some reason. In higher throttle setting we are wrapping around numbers and making a mess of the data. I wonder is this a result of using dma. It is a 32 bit micro so I wonder is it treating the data like that in memory and then dumping what it thinks is correct out to the usart. Or it could be a Damien moment.........

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 3:51 pm
by mdrobnak
Yes, please be careful with your data types. I noticed you using a char for some things that aren't...

Did you fix
src/stm32_vcu.cpp:476:8: error: Array 'mTemps[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]
mTemps[2] = TempMeas::Lookup(tmpmg2, TempMeas::TEMP_TOYOTA);

to be
mTemps[1] = TempMeas::Lookup(tmpmg2, TempMeas::TEMP_TOYOTA);

You could be getting garbage data there, which who knows what that is doing.

I'll try and look at the state of the repo when I get a moment.

-Matt

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 3:58 pm
by Dilbert
I've been looking at the SAM Code V's this new code also. I was wondering if we were telling the inverter to re-init. There is a flag called inv_status and it was being used along with the MTH_data byte 1 to determine if the inverter requires initialization. It was also been used due to how the sequencing was being programmed.

In state 1 we could look at changing:-

if(mth_data[1]!=0)
inv_status--;
}

To

if(inv_status != 0 && mth_data[1]!=0)
inv_status--;
}

This will make sure this number doesn't wrap around.


Or you could use the new "statusInv" flag to see if the inverter is correctly online, also we can read this from the web-interface.
So in state 1 you could change:-
if(inv_status==0){ }

To

if(statusInv==0){ }

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 4:07 pm
by Dilbert
In the reverse direction, MG1 will have a torque command of 0, might that be what your seeing?

if(gear=-32) mg1_torque=0; //no mg1 torque in reverse.

It looks like the over speed check has been removed from the code, so it can't be that.
if((mg2_speed>MG2MAXSPEED)||(mg2_speed<-MG2MAXSPEED))mg2_torque=0;

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 5:10 pm
by johu
I see you're correctly using

Code: Select all

dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
So DMA will handle data as bytes.

Just not 100% sure if this is good:

Code: Select all

htm_data[5]=(mg1_torque*-1)&0xFF;  //negative is forward
htm_data[6]=((mg1_torque*-1)>>8);
Maybe dump out some data to see if it is converted right.

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 5:22 pm
by Jack Bauer
Thanks Johannes that's exactly one of the bits I'm looking at. Plan for tomorrow is to dump it out on usart 1 which has an ftdi on it for usb.

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 5:26 pm
by johu
Thats handy.
Also your DMA ISRs don't do anything meaningful right now. No need to disable DMA after the transfer, it won't do anything anyway once it runs out of data. So if you're not planning to add anything, just disable interrupts.

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 6:04 pm
by Jack Bauer
Ok, in these two lines we take a 16 bit int with a possible value from -3500 to 3500 where 0 represents 0 torque:

Code: Select all

	htm_data[26]=(mg2_torque)&0xFF; //positive is forward
	htm_data[27]=((mg2_torque)>>8);
As I understand this, we and with 0xff to chop off the 8 msb bits so htm_data[26] should contain the lsb 8 bits of the torque value? But, are we still trying to stuff a 16 bit number into an 8 bit register or does the compiler understand this and just use the lsb 8 bits?

Likewise in the next line an 8 bit right shift now brings the msb 8 bits into the lsb field for htm_data[27] but are we overstuffing the register? I am seeing data in the htm byte 28 with high throttle settings on the analyser captures which should not be there as best as I can tell....

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 6:07 pm
by Jack Bauer
High throttle bytes 26,27 and 28 :
0x00
0x70
0x01

Low throttle :
0x00
0x25
0x00

Re: The ZombieVerter VCU Project

Posted: Thu Jan 07, 2021 6:07 pm
by mdrobnak
26th is fine... 27... potentially undefined?
I'd do the same thing:

Code: Select all

htm_data[26]=(mg2_torque) &0xFF; //positive is forward
htm_data[27]=((mg2_torque)>>8) & 0xFF;
Try that.