/gd32vf103inator

Program the GD32VF103 using C, your favourite editor and make

Primary LanguageC++BSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

gd32vf103inator

What is this?

This is a collection of headers, some code, linkerscript and Makefile to make it easy to program the GD32VF103 RISC-V microcontroller from GigaDevice. It is already supported in PlatformIO and ArduinoIDE is underway, but sometimes it's nice to just use your favourite editor and make. This is exactly what this project will help you do.

The user manual and datasheet for the chip as available from here.

Using gd32vf103inator

The quick and dirty way

git clone https://github.com/esmil/gd32vf103inator.git
mkdir myproject
cd myproject
echo include ../gd32vf103inator/Makefile > Makefile
cp ../gd32vf103inator/main.c .
make

The sophisticated way

mkdir myproject
cd myproject
git init
git submodule add https://github.com/esmil/gd32vf103inator.git
echo include gd32vf103inator/Makefile > Makefile
echo build/ > .gitignore
cp gd32vf103inator/main.c .
git add .
git commit -m 'initial commit'

Local settings

As seen above the Makefile is meant to be included by the Makefile in local project. It is made such that most settings should be overwritable. As an example your Makefile could look like this:

include path/to/gd32vf103inator/Makefile

# disable link-time optimization, but optimize for speed
OPT = -O2

# too many annoying warnings, I know how to write code
#WARNINGS = -Wall
# be extra pedantic, and make sure we fix all warnings
WARNINGS += -Werror -pedantic

# gd32vf103inator defaults to GD32VF103xB chips
# with 32k SRAM and 128k FLASH, but we use an x8 chip
RAM_SIZE = 20*1024
FLASH_SIZE = 64*1024

Bootloader

The chip has a built-in DFU bootloader in ROM but unfortunately it has some bugs quirks: it only works with a patched version of dfu-utils and some workarounds.

That's a bit annoying so this project includes another DFU bootlader that can be programmed into the first 4k flash. This bootloader does work with the regular dfu-util and is much faster. The bootloader will activate when the chip is reset by the external reset pin (aka. the reset button is pressed). On any other reset (power on, watchdogs etc.) the bootloader will immediately jump 4k into the flash and run the regular program.

You can use the built-in bootloader in ROM to flash this bootloader. First make sure to reboot the chip into the ROM bootloader (on the LonganNano board hold BOOT and press RESET) and then run:

cd gd32vf103inator/examples/dfu-bootloader
make clean
make release
make DFU_UTIL=/path/to/gd32-dfu-utils/src/dfu-util romdfu

This will show errors even when the chip is succesfully flashed. Apparently that's just how the built-in bootloader works :/

Once the bootloader is flashed the chip can be programmed by just pressing the reset button and run:

make dfu

This will use the dfu-util in your path, flash the chip and reset it to run your program.

For this to work regular programs must be compiled to run from an offset of 4k into the flash. That happens automatically, but if you're happy with the built-in bootloader or you have some other means of flashing the chip you can disable it by adding this line to your Makefile:

BOOTLOADER = 0

Getting a RISC-V toolchain

Ideally you want a toolchain for embedded use. For RISC-V it will typically be called something containing riscv64-unknown-elf. This is similar to arm-none-eabi toolchains in ARM land. Don't worry that it's called "riscv64" even though the core in the chip is only 32bit. The toolchain will still be able to produce 32bit code, floating point/non-floating point code and many other valid RISC-V combinations.

Unfortunately RISC-V toolchains for embedded use are not yet available in most distributions, but cross compilers for Linux seem to be. They are usually called something containing riscv64-linux-gnu, and gd32vf103inator has been made to work with such toolchains too. This is not ideal but with enough options to gcc it can be persuaded to not use any libc bits.

If your chosen toolchain is not prefixed with riscv64-unknown-elf- you can overwrite the CROSS_COMPILE variable in your local Makefile. Eg. append this to your Makefile:

CROSS_COMPILE = riscv64-linux-gnu-

Below are some suggestions for specific operating systems. Please make a pull request to add your favourite OS.

Archlinux

There are packages riscv64-unknown-elf-binutils and riscv64-unknown-elf-gcc available in AUR.

Alternatively there are prebuilt riscv64-linux-gnu packages in community repo. Eq.

pacman -S riscv64-linux-gnu-gcc make
Debian/Ubuntu

If you're running Debian unstable aka. sid or Ubuntu 20.04 (Focal Fossa) you should use the riscv64-unknown-elf toolchain:

apt-get install gcc-riscv64-unknown-elf make

On older Ubuntus you might want to try the embedded toolchain from SiFive below.

Otherwise it should also work with the cross compiler for Linux. Eg.:

apt-get install gcc-riscv64-linux-gnu make
Fedora

Unfortunately I don't know of any prebuilt riscv64-unknown-elf toolchains for Fedora, but again the cross-compiler for Linux should work:

dnf install gcc-riscv64-linux-gnu make
OSX

See SiFive's toolchain below.

Windows
Option 1

See SiFive's toolchain below for the toolchain. You'll also need GNU Make to build your code.

Option 2

Use Windows Subsystem for Linux and proceed as on Ubuntu above.

Prebuilt toolchains from SiFive

Go to SiFive's software page and search for "GNU Embedded Toolchain". Download the relevant tarball/zip-file and unpack it. Now you can either update your path to include the bin folder inside, or add the following line to your Makefile:

CROSS_COMPILE = /full/path/to/the/extracted/folder/bin/riscv64-unknown-elf-

License

This project is licensed under the BSD 3-Clause license just like the firmware library released by GigaDevice. Register and bit definitions are copied from there and modified to be usable without including the rest of the library.