Library for GD32F130C8

Is it there a library for GD32F130C8 arm processor?
I would like to port this project from keil to platformio: Hoverboard-Firmware-Hack-Gen2/README.md at master · flo199213/Hoverboard-Firmware-Hack-Gen2 · GitHub

Hi. I suspect that I have the same hardware as you, and I don’t have a windows machine for running Keil on, so putting a toolchain together has become a blocker.

Looking down the list of forks or that repo, Tecnologic has added a Makefile, but is missing some headers so won’t compile. TobinHall also has a Makefile on their devel branch, but seems to have abandoned it.

I’m thinking that I will start with a minimal “blink some LEDs” firmware from scratch, and port code across from there. Flashing with the open source st-flash utility is currently what I’m blocked on.

How did you get on with this? Did you stick with Keil for your entire lawnmower project?

Hm, interseting. I originally added PlatformIO support for the GD32F130C6 chip with the SPL firmware in GitHub - maxgerhardt/pio-gd32f130c6: Test project for the GigaDevice's GD32F130C6 using PlatformIO, this was then further used in also a hoverboard firmware but a different one – GitHub - EFeru/hoverboard-sideboard-hack-GD: Hoverboard sideboard hack for GD32 boards.

The C6 and C8 chips should only differ by flash size, so if you add board_upload.maximum_size = 65536 and board_upload.maximum_ram_size = 8196 to the platformio.ini it should basically work (in my repo). I added support for the C8 variant in my linked repro, the environment GD32F130C8T6 can be used for that.

I can see if I can quickly fork the original repo above from above and compile with PlatformIO – the firmware seems to also be using the SPL but a self-contained version of it. That can also be accomadated though.

EDIT: I’ve gotten the project above to compile (with SPL support since the files in the project itself were incomplete). It can be found at Hoverboard-Firmware-Hack-Gen2/HoverBoardGigaDevice at master · maxgerhardt/Hoverboard-Firmware-Hack-Gen2 · GitHub. There’s an instruction for a compile fix in the platformio.ini that has to be done until my new framework-spl package version is approved.

1 Like

I think that having a minimal example that I can try flashing will be enough for now. I will try flashing it and report back. Thank you so much!

\o/ 
 |
/ \

A working toolchain!

It looks like the initialisation code is working (turning the case LED on if I leave LED1_PIN set as is, and not turning it on if I change it to something else) but the blinking isn’t working (maybe something to do with the clock?).

I have a long weekend next weekend, so I will continue my investigation then.

This has been a light at the end of a very frustrating weekend of getting errors from st-flash. Thanks again!

[EDIT: uart is working and prints 2-3 times per second according to miniterm /dev/ttyS0 115200 | ts on my rpi4]

Huh interesting because a delay of 1 second is written in the code, not 0.5 or 0.33. Sure, the UART printing needs some time at low baudrates but not in the order of… seconds… I think…

The clock source is chosen inside the framework file C:\Users\<user>\.platformio\packages\framework-spl\gd32\cmsis\variants\gd32f13\system_gd32f1x0.c as

/* select a system clock by uncommenting the following line */
//#define __SYSTEM_CLOCK_8M_HXTAL              (__HXTAL)
//#define __SYSTEM_CLOCK_8M_IRC8M              (__IRC8M)
//#define __SYSTEM_CLOCK_72M_PLL_HXTAL         (uint32_t)(72000000)
#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2    (uint32_t)(72000000)

which means it choses the internal 8MHz RC oscilator (IRC8M) together with the PLL is used to achive 72MHz core clock speed. So, it doesn’t have any dependency on an external crystal where if it’s the wrong frequency it can lead to a different speed, thus it should be very robust…

You can still choose

  • a 72MHz from crystal oscilator option by adding the -D__SYSTEM_CLOCK_72M_PLL_HXTAL=72000000 option to the build_flags of the platformio.ini
  • or -D__SYSTEM_CLOCK_8M_HXTAL for a 8MHz speed from the crystal
  • or comment the #define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 line to get __SYSTEM_CLOCK_8M_IRC8M

and see if it makes a difference.

Otherwise if you can share the exact board schematics and your exact test-code with the firmware behavior (e.g., LED blinks exactly twice as fast as expected) I can also help.

I’ve been working a bit on this with @alsuren, and it turned out the problem was that the watchdog timer was resetting the chip every 400 ms or so. Configuring it to wait longer, and calling fwdgt_counter_reload each time through the loop, makes the LED flashing work properly. I haven’t yet figured out if there’s a way to disable the watchdog entirely.

I suspect it’s also what was causing our earlier attempts at flashing firmware to fail partway through, by resetting the chip before it finished flashing. Is that likely? Any idea how to avoid it?

That is weird. Does the firmware explicitly call into fwdgt_enable()? The watchdog shouldn’t be on by default.

This is just using GitHub - maxgerhardt/pio-gd32f130c6: Test project for the GigaDevice's GD32F130C6 using PlatformIO, so no. If we don’t call fwdgt_enable, then it seems to default to around 400 ms. Could there be some kind of bootloader or something running before our code which is initialising it?

In the manual page 250 I read

The free watchdog timer can automatically start at power on when the hardware free watchdog timer bit in the device option bits is set.

And from the datasheet

0x1FFF F800 - 0x1FFF F80F: Option bytes

and again from the manual

So bit 0 of the option byte stored at 0x1ffff802 determines if the free watchdog timer is started from hardware on powerup or via software. Can you readout that byte with a C pointer (I believe for reading from this address you don’t need any special unlocking voodoo) and print it via UART?

Do you know if the option bytes were ever modified in this chip? If you have multiple chips, do they all behave the same?

Aha! It appears do be 0, which would explain it. Running

openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt; stm32f1x options_write 0 SWWDG"

seems to have fixed it. Thanks for your help again!