Hoverboard-Firmware-Hack-Gen2.x icon indicating copy to clipboard operation
Hoverboard-Firmware-Hack-Gen2.x copied to clipboard

Gen2.3.1 (ex2.7) = GD32E230C8T6

Open RoboDurden opened this issue 2 years ago • 134 comments

thanks to @WizzardDr who added this new layout which needs a new Keil compiler target: https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/pull/15

As i am not really experienced at all with this Keil platform, help from anybody would be appreciated :-)

I see that this board has three mosfet gate driver chips instead of analog gate drivers like the original 2.0. Be aware that this firmware here was written for the 2.0 layout where the low side mosfets are turned on with a LOW signal !! With layouts having gate driver chips however, the on-signal might be HIGH for both high-side and low-side mosfets. If this is not correctly applied, all three half-bridges will short cut and burn !!

When testing a new layout it is mandatory to use a CC constant current power supply with only 1-2 A max !!!

RoboDurden avatar Sep 07 '23 07:09 RoboDurden

I noticed when I was tracing the connections that the Hi and Lo sides of the driver connect to TIMER0_CH2_ON TIMER0_CH2 respectively whereas the other designs had Lo to _ON. I double and triple checked since I expected it to be the same. Because of this it may be that the on and off timing also needs inverting. I will do some testing and look at how the PWM timers are setup to drive the outputs once I get it to compile.

WizzardDr avatar Sep 07 '23 07:09 WizzardDr

The GD32E230 also has only one advanced timer capabale of driving a 3 phase motor. With the GD32F130, the output pins for such a 3 phase bldc is very very limited and therefore all the gen2-x layouts so far had the same output pins

// Channel G
#define BLDC_GH_PIN PA10
#define BLDC_GL_PIN PB15
// Channel B
#define BLDC_BH_PIN PA9
#define BLDC_BL_PIN PB14
// Channel Y
#define BLDC_YH_PIN PA8
#define BLDC_YL_PIN PB13

These connect to TIMER0_CH0, TIMER0_CH1 and TIMER0_CH2

We are currently working on a simpleFOC port for these Gen2 boards: https://github.com/Candas1/Split_Hoverboard_SimpleFOC/issues/6#issuecomment-1694725771

But please also continue to get the GD32E230 compiled for this Gen2.x firmware.

RoboDurden avatar Sep 07 '23 07:09 RoboDurden

@Candas1 has begun with a nice spreadsheet of the pin connections for various board layouts: https://docs.google.com/spreadsheets/d/15msbDAIMxC2rIkq8Au8vf82ub1qEaS67Lc1cFb86Jpc/edit#gid=0

RoboDurden avatar Sep 07 '23 07:09 RoboDurden

I think that all #include "gd32f1x0.h" lines can be removed from the Inc/*.h files. But for the Src/*.c file i guess we have to add a #ifdef TARGETXY #ELSE #ENDIF to choose between #include "gd32f1x0.h" and #include "gd32e2x0.h" I might know how to do this with PlatformIO, but not with Keil.

RoboDurden avatar Sep 07 '23 08:09 RoboDurden

Yes this seems to work:

#ifdef GD32E230 #include "gd32e2x0.h" #else #include "gd32f1x0.h" #endif

keil multiple targets

But the file "gd32e2x0.h" is not found. Ideas welcome.

RoboDurden avatar Sep 07 '23 08:09 RoboDurden

Okay, i have replace all #include "gd32f1x0.h" with #include "../Inc/target.h" in all *.c files and removed all #include "gd32f1x0.h" in the *.h files.

target.h simply is

#ifdef GD32E230
	#include "gd32e230.h"
#else
	#include "gd32f1x0.h"
#endif

This compiles successfully for the f130 target. Still need to find the correct #include "gd32e230.h"

Will publish my code now.

RoboDurden avatar Sep 07 '23 08:09 RoboDurden

#include "gd32e23x.h" is the correct wording. Now it compiles but i get 10 compiler errors. But these should not pose big problems:

Src/setup.c(63): error: use of undeclared identifier 'NVIC_PRIGROUP_PRE4_SUB0'
        nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
                                ^
Src/setup.c(117): error: too many arguments to function call, expected 2, have 3
        nvic_irq_enable(TIMER13_IRQn, 0, 0);
        ~~~~~~~~~~~~~~~                  ^
C:/Users/PAN CF-LX6/AppData/Local/Arm/Packs/GigaDevice/GD32E23x_DFP/1.0.2/Device/Firmware/Peripherals/inc\gd32e23x_misc.h(69): note: 'nvic_irq_enable' declared here
void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority);
     ^
Src/setup.c(327): error: too many arguments to function call, expected 2, have 3
        nvic_irq_enable(TIMER0_BRK_UP_TRG_COM_IRQn, 0, 0);
        ~~~~~~~~~~~~~~~                                ^
C:/Users/PAN CF-LX6/AppData/Local/Arm/Packs/GigaDevice/GD32E23x_DFP/1.0.2/Device/Firmware/Peripherals/inc\gd32e23x_misc.h(69): note: 'nvic_irq_enable' declared here
void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority);
     ^
Src/setup.c(347): error: too many arguments to function call, expected 2, have 3
        nvic_irq_enable(DMA_Channel0_IRQn, 1, 0);
        ~~~~~~~~~~~~~~~                       ^
C:/Users/PAN CF-LX6/AppData/Local/Arm/Packs/GigaDevice/GD32E23x_DFP/1.0.2/Device/Firmware/Peripherals/inc\gd32e23x_misc.h(69): note: 'nvic_irq_enable' declared here
void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority);
     ^
Src/setup.c(430): error: too many arguments to function call, expected 2, have 3
                nvic_irq_enable(DMA_Channel3_4_IRQn, 2, 0);
                ~~~~~~~~~~~~~~~                         ^
C:/Users/PAN CF-LX6/AppData/Local/Arm/Packs/GigaDevice/GD32E23x_DFP/1.0.2/Device/Firmware/Peripherals/inc\gd32e23x_misc.h(69): note: 'nvic_irq_enable' declared here
void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority);
     ^
Src/setup.c(489): error: too many arguments to function call, expected 2, have 3
        nvic_irq_enable(DMA_Channel1_2_IRQn, 2, 0);
        ~~~~~~~~~~~~~~~                         ^
C:/Users/PAN CF-LX6/AppData/Local/Arm/Packs/GigaDevice/GD32E23x_DFP/1.0.2/Device/Firmware/Peripherals/inc\gd32e23x_misc.h(69): note: 'nvic_irq_enable' declared here
void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority);
     ^
6 errors generated.
compiling setup.c...
compiling bldc.c...
compiling main.c...
compiling commsBluetooth.c...
compiling comms.c...
compiling it.c...
compiling led.c...
compiling commsSteering.c...
compiling commsMasterSlave.c...
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'FMC_WS'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
    ^
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'FMC_WS_WSCNT'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
                         ^
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'FMC_WS'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
              ^
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'WS_WSCNT_2'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
                                          ^
4 errors generated.
compiling system_gd32e23x.c...
".\Objects\Hoverboard.axf" - 10 Error(s), 0 Warning(s).

@WizzardDr please continue as i want to work on something else :-)

RoboDurden avatar Sep 07 '23 08:09 RoboDurden

5 compiler errors with

#ifdef GD32E230
	#include "gd32e23x.h"
	#define TARGET_nvic_irq_enable(a, b, c){nvic_irq_enable(a, b);}
#else
	#include "gd32f1x0.h"
	
	#define TARGET_nvic_irq_enable(a, b, c){nvic_irq_enable(a, b, c);}
#endif

:-)

RoboDurden avatar Sep 07 '23 08:09 RoboDurden

4 errors:

#ifdef GD32E230
	#include "gd32e23x.h"
	#define TARGET_nvic_irq_enable(a, b, c){nvic_irq_enable(a, b);}
	#define TARGET_nvic_priority_group_set(a)	// that function does not exist for this target = not needed ?
#else
	#include "gd32f1x0.h"
	
	#define TARGET_nvic_irq_enable(a, b, c){nvic_irq_enable(a, b, c);}
	#define TARGET_nvic_priority_group_set(a){nvic_priority_group_set(a);}
#endif

But the remaining four errors are not in our user code:

RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'FMC_WS'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
    ^
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'FMC_WS_WSCNT'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
                         ^
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'FMC_WS'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;
              ^
RTE/Device/GD32E230C8/system_gd32e23x.c(202): error: use of undeclared identifier 'WS_WSCNT_2'
    FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT_2;

So i guess some compiler setting must be adjusted :-/ I am out for now.

RoboDurden avatar Sep 07 '23 08:09 RoboDurden

Okay if i simple remove that strange line with //FMC_WS... this leads to a successful compilation:

#ifdef GD32E230
	#include "gd32e23x.h"
	#define TARGET_nvic_irq_enable(a, b, c){nvic_irq_enable(a, b);}
	#define TARGET_nvic_priority_group_set(a)	// that function does not exist for this target = not needed ?
	#define TARGET_adc_vbat_disable()
#else
	#include "gd32f1x0.h"
	
	#define TARGET_nvic_irq_enable(a, b, c){nvic_irq_enable(a, b, c);}
	#define TARGET_nvic_priority_group_set(a){nvic_priority_group_set(a);}
	#define TARGET_adc_vbat_disable(){adc_vbat_disable();}
#endif

@WizzardDr , you continue !

RoboDurden avatar Sep 07 '23 09:09 RoboDurden

Well this is unfortunate, I didn't see your updates, I have wasted my time doing what you have just done, but I did it worse and slower lol. I looked into the FMC stuff and found "The FMC provides a security protection function to prevent illegal code/data access on theFlash memory." so it probably isn't important. Thanks for getting it to compile.

WizzardDr avatar Sep 07 '23 09:09 WizzardDr

Only test the binary with a 1-2A CC power supply !!! I have cleaned up your Schematics_2.7 a bit. Tell me if i deleted some nice images.

The master and slave boards seem to be different, slave having new room for the buzzer and bluetooth on board !

RoboDurden avatar Sep 07 '23 10:09 RoboDurden

I am currently working to add your defines_2-7.h ! 22 errors at the moment..

RoboDurden avatar Sep 07 '23 10:09 RoboDurden

Okay i added the defines_2-7.h and removed the compiler errors.


#ifdef GD32E230
	#define LAYOUT_2_7	// https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/issues/16
#else
	#define LAYOUT_2_0	// https://github.com/flo199213/Hoverboard-Firmware-Hack-Gen2
	//#define LAYOUT_2_1	// https://github.com/krisstakos/Hoverboard-Firmware-Hack-Gen2.1
	//#define LAYOUT_2_2	// 2023/05/11 only MASTER and TEST_SPEED: motor is spinning but needs a push to startup :-/
	//#define LAYOUT_2_4	// NOT READY !!! https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/issues/3
#endif

It seems to me that the gate driver chips expect a negated signal for low side mosfets. So maybe the 2.0 code will run.

EG2131DatasheetCircuitDiagram

But again, be careful !

RoboDurden avatar Sep 07 '23 10:09 RoboDurden

If you do not find the CHARGE_STATE_PIN then you need to deactivate (add //)

chargeStateLowActive = gpio_input_bit_get(CHARGE_STATE_PORT, CHARGE_STATE_PIN); in main.c::367

RoboDurden avatar Sep 07 '23 10:09 RoboDurden

Okay i added #ifdef CHARGE_STATE_PIN to the only two references.. Shift+Strg+F is your friend !

RoboDurden avatar Sep 07 '23 10:09 RoboDurden

@RoboDurden I do not understand how the pulse time is correct with the PWM running in mode 1. In mode 1 "When counting up, OxCPRE is low when the counter is smaller than TIMER0_CHxCV, and high otherwise.".

Is "pulse_value" = TIMER0_CHxCV?

How does timer_channel_output_pulse_value_config(TIMER_BLDC, TIMER_BLDC_CHANNEL_G, CLAMP(g + pwm_res / 2, 10, pwm_res-10)); dictate the PWM on time rather than PWM off time?

WizzardDr avatar Sep 10 '23 19:09 WizzardDr

What was wrong with UCC1800_dcdc_chip.PDF ? I did not program this firmware. I only added the different layouts and rewrote the serial communications. I guess you are the better person to answer this pwm init code. It will take me longer to understand that then it would take you. Candas1 i think would know the answer instantly, but i am happy that he is busy with the simpleFOC port, so i do not like to ask him.

Have you started testing the binary with a constant current power supply ??? If the defines_2-7.h is close to complete, you could give it a try. All your pull requests are not really worth anything if you will not test the 2.7 layout at some time. Before that, further pull requests do not really make the current gen2.x firmware better.

RoboDurden avatar Sep 11 '23 14:09 RoboDurden

I think that pdf is for a different chip. It shows a different pinout to the chip that is on the board. E.g. My schematic shows pin1 connected to vcc whereas that datasheet shows vcc at pin 7. That datasheet also shows an external switching mosfet.

WizzardDr avatar Sep 11 '23 15:09 WizzardDr

My problem at the moment is that https://github.com/EFeru/hoverboard-firmware-hack-FOC/wiki/How-to-Unlock-MCU-flash seems to have bricked the mcu... I connected it and it seamed to be unlocked, It read a 4kB image. Then I followed the step and now it just says the chip protection is enabled and it won't let me set the option bits to unlock it. STM32CubeProgrammer returns 15:36:31 : Error: Expected value for STM32F1 Option Byte "RDP": 0xA5, found: 0x1 15:36:31 : Error: Option Byte Programming failed, ST-LINK Utility doesn't work either.

WizzardDr avatar Sep 11 '23 15:09 WizzardDr

I lifted the Boot0 pin and used UART and got it to load the firmware. (I selected "Read Unprotect (MCU)" in STM32CubeProgrammer)

WizzardDr avatar Sep 11 '23 16:09 WizzardDr

If you indeed succeeded with a stlink dongle to flash with the uart protocol and not the SWD protocol, please make a youtube tutorial. With my the 2.0 test setup the flashing quite often fails and i need to flash under reset. I use the stlink.exe you can download on my readytoflash folder because it only need a press on the return key to run the .bat file with st-flash --connect-under-reset write hoverboard.bin 0x8000000 But these cheap st-link dongle have only the rst pin wroking for that other protokol and not the usual SWD (?) Therefore you need to solder a tiny cable onto the little circuit board... Already wanted to add two photos to this repo here but forgot and now i do not find the photos to show how to solder the cable. But you can google for it.. With the 2.0 layout there is a nice small smd resistor connected to that NREST pin of the mcu. So it is quite simple to press a male dupont pin to the end of that smd resistor connecting the mcu NRST pin and hit the return key to start the patch file. Or F8 in the Keil ide. But this will block with some error popups if you do not succeed in the first run. Might help you next time.

RoboDurden avatar Sep 11 '23 16:09 RoboDurden

I have tested it with 20v (1a) with the battery cell count set to 5, but the power doesn't seem to be latching ON.

WizzardDr avatar Sep 11 '23 20:09 WizzardDr

add

#define DEBUG_LED_PIN 	UPPER_LED_PIN
#define DEBUG_LED_PORT 	UPPER_LED_PORT

to your defines_2-7.h and understand how the DEBUG_LedSet macro should make the upper_led go on and off. Then you can test if the code gets executed and were it stops. Or if it reaches the while(1) loop..

I never got the debug step by step mode working with this Keil ide. Porting this firmware to platformIO would make debugging (also using the great StmStudio) much easier..

RoboDurden avatar Sep 11 '23 20:09 RoboDurden

Yes, I guess I'll have to trace more of the pcb and find the led pins.

WizzardDr avatar Sep 11 '23 20:09 WizzardDr

I guess these are the 5 led pins: led pins - guess

Good night from Germany :-)

RoboDurden avatar Sep 11 '23 20:09 RoboDurden

I've been trying to get it to work and have come to the realization that the main code doesn't seem to be running at all. I've blocked out the main code with ifndef and just have a small section to turn a pin on (plus some some bits to stop it complain about speed being an undefined symbol) main.c

#define BLINKTEST
#ifdef BLINKTEST
#define BLINKTEST_PORT GPIOA
#define BLINKTEST_PIN GPIO_PIN_14
#include "gd32e23x.h"
#include "../Inc/defines.h"
int main (void){
	gpio_mode_set(BLINKTEST_PORT , GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,BLINKTEST_PIN);	
	gpio_output_options_set(BLINKTEST_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, BLINKTEST_PIN);
	gpio_bit_write(BLINKTEST_PORT, BLINKTEST_PIN, 0);
}
int32_t speed = 0; 												// global variable for speed.    -1000 to 1000
int32_t steer = 0; 												// global variable for steering. -1000 to 1000
FlagStatus beepsBackwards = SET;  			// global variable for beeps backwards
DataSlave oDataSlave;
#endif
#ifndef BLINKTEST

#define ARM_MATH_CM3
......

This should be working no matter what, right?

WizzardDr avatar Sep 14 '23 00:09 WizzardDr

This is the code that works on my gen2.0 test setup:

#define BLINKTEST

#ifdef BLINKTEST

#include "../Inc/target.h"
#include "../Inc/config.h"
#include "../Inc/defines.h"

uint32_t iLoop = 0;
int main (void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
	
	gpio_mode_set(SELF_HOLD_PORT , GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SELF_HOLD_PIN);	
	gpio_output_options_set(SELF_HOLD_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, SELF_HOLD_PIN);
	gpio_bit_write(SELF_HOLD_PORT, SELF_HOLD_PIN, SET);
	
	gpio_mode_set(LED_GREEN_PORT , GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,LED_GREEN);	
	gpio_output_options_set(LED_GREEN_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, LED_GREEN);
	while(1)
	{
		gpio_bit_write(LED_GREEN_PORT, LED_GREEN, (iLoop++ % 200000) < 100000 );
	}
}

int32_t speed = 0;							// global variable for speed.    -1000 to 1000
int32_t steer = 0;							// global variable for steering. -1000 to 1000
FlagStatus beepsBackwards = SET;  			// global variable for beeps backwards
DataSlave oDataSlave;

#else
...
#endif

RoboDurden avatar Sep 14 '23 10:09 RoboDurden

That code didn't work either. I don't think the mcu is entering the main code. What option bytes are set on yours?

WizzardDr avatar Sep 14 '23 22:09 WizzardDr

All Option bytes must be set in the St link utility. But if you can flash successfully then I think your code should run. Do you have a 36v battery connected ? Or better a cc power supply set to 26v and 2A. Do not connect the 3.3v of the flash header. The led needs the 15V on the led header. Check this with a multimeter.

From which country are you ?

RoboDurden avatar Sep 15 '23 06:09 RoboDurden