/GD32F130K6-hoverboard-hack

Hoverboard sideboard hack for GD32 F130K6 boards

GD32 F130K6 Hoverboard hack

This repository shows the steps to unlock the hoverboard sideboards and flash a firmware. No firmware is included, but the amazing work from EmanuelFeru can be reused.

Identifying the hoverboard

Multiple different hoverboard models exist, you should find the right repository for your device. Here, we are using (this board), wich needs as a specific procedure to flash it, described below.

Hardware

The sideboard has a 4-pin debugging header with a 3V3, SWDIO, SWCLK, and GND input accessible next to the chip:

Hoverboard master sideboard

The chip itself is a GD32 F130K6, for which you can find a datasheet here:

Hoverboard master sideboard GD32F130K6 pin mapping

Important: The "dot" on the datasheet's schematics used to indicate the orientation is located at the bottom left of the chip when the text is upright, contrary to what you might expect.

Helpful notes:

  • We recommend plugging a pin header to make debugging and flashing easier, as well as testing faster (in the improbable case where you don't succeed first try). It also makes the pins accessible when the PCB is fully assembled on the chassis.
  • Put a piece of tape on the speaker of the slave board, this just might save your ears during the hacking process.
  • The motherboards detect the orientation of the hoverboard for safety reasons, so you may find yourself trying to unlock the chip but instead making the board beep, and being unable to turn it off without unplugging the battery. Keep in mind that you can reset the board by pushing the on/off button once, then pressing it for 5 secondes while the hoverboard is leveled.

TODO: Add a picture of the board with the debug pins and the of tape.

Here are some of the pins located on a real board:

Hoverboard master sideboard

Since the 3V3, GND, SWDIO and SWCLK are already connected to the debugging header, there is no need to bother with them. However, correctly identifying the NRST pin is important to unlock the board.

Flashing

For this setup, you can completly disconnect the sideboards from the rest of the equipment, including the battery. We recommend working on them while totaly disconnected from any hardware for practicality. You must have access to an ST-LINK v2 like the following:

ST-LINK v2

Connect the 3V3, SWDIO, SWCLK, and GND pins from the ST-LINK to the debugging header on the sideboard.

Unlocking

If this is your first time flashing the board, it must be unlocked.

At this points, you can plug the ST-LINK in your computer and use ST-LINK utility to connect to it. However, the GD32 itself will most likely not respond, resulting in an error. You can try EmanuelFeru's tutorial on how to unlock it. If this works, good for you, you can skip the rest of these steps! Otherwise, keep on reading.

Now, the NRST pin must be taken care of. Because it is not connected to the debugging header, you need to find a way to manually connect a cable. It is considerably easier to access the first component to which the pin is connected than the pin itself, as it is bigger and there is less risk of creating a short.

NRST stands for "Not ReSeT", which means that if the ST-Link sends a '1' bit on the RST pin, the NRST pin on the GD32 must receive a 0 instead (and vice versa). To do so, we used an Arduino Mega with a very simple program:

void setup() {
  pinMode(40, INPUT);
  pinMode(A0, OUTPUT);
}

void loop() {
  int rst = digitalRead(40);
  analogWrite(A0, 1023 * !rst);
}

Because the output is 5.5V, and we can't use PWM considering our use case, we added a simple voltage divider to match the GD32's expected 3.3V amplitude on the NRST pin.

TODO: Add a diagram showing our setup and the voltage divider.

Note: The same result could be achieved in an easier fashion by using simple transistors, but we used what was handy. It would also probably reduce the delay between the ST-LINK and the GD32, which might make the whole procedure more reliable. Our procedure isn't plug'n'play'n'it'works, you may have to try few times (for us, less than 10 times) the following procedure to get results, but it works.

Here's a look at our quick and dirty setup:

Setup to reset the GD32 chip

Now that the 3V3, SWDIO, SWCLK, GND, and NRST pins are connected, we can try unlocking the GD32.

We used OpenOCD to launch commands and check if our reset was working correctly:

./openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "stm32f1x unlock 0" -d

Note: If you're running Windows, you might need to start cmd as administrator to access the USB ports. On Linux / macOS, sudo might be necessary, but the error messages should be clear enough to figure it out.

The first few times, we ran into errors such as:

Error: init mode failed (unable to connect to the target) 
stlink_usb.c:515 jtag_libusb_bulk_transfer_n(): ERROR, transfer 0 failed, error -1
stlink_usb.c:515 jtag_libusb_bulk_transfer_n(): ERROR, transfer 1 failed, error -1
stlink_usb.c:1679 stlink_usb_idcode(): IDCODE: 0xFFFFFFFF
hla_interface.c:93 hl_interface_init_target(): UNEXPECTED idcode: 0xffffffff
hla_interface.c:95 hl_interface_init_target(): expected 1 of 1: 0x1ba01477
stlink_usb.c:788 stlink_usb_error_check(): unknown/unexpected STLINK status code 0x5

However, we were able to successfully run the OpenOCD command with the following procedure:

  • Step 1: Unplug the ST-LINK from your computer so the GD32 is unpowered.
  • Step 2: Plug the NRST pin with the inverter setup.
  • Step 3: Powerup the ST-LINK by plugging it to your computer and wait a few seconds.
  • Step 4: Run the OpenOCD command.
  • Step 5: Unplug the NRST pin.
  • Step 6: Run the command again.

The goal here is to send the OpenOCD command at the right timing in the GD32 starting procedure. If it doesn't work, try again but execute Step 5 before Step 4.

You can also try executing Step 5 while the OpenOCD command is running. It's all about having the right timing. As this isn't very reproducible, it hopefully won't be necessary.

If it works, OpenOCD should keep running and you should be able to spot the following message:

options.c:63 configuration_output_handler(): stm32x unlocked.

Once you're able to run the OpenOCD command, you can follow EmanuelFeru's tutorial using ST-Link utility if need-be (your GD32 may already be unlocked thanks to the OpenOCD command). Make sure to stop OpenOCD before following the tutorial or both programs might conflict with one another.

Note: Unlocking your GD32 only needs to be done once. Afterwards, you no longer need to fiddle with the NRST pin and the whole inverter: the 3V3, SWDIO, SWCLK, and GND pins should be enough.

Flashing

The hard part is done, now you're in known territory. The easiest was of doing things is following EmanuelFeru's tutorial with the associated firmware.

Note: For now, the linked firmware probably won't work as the pin mapping is different from the one of our chip. It shouldn't be too hard to get it working, but this is a work in progress.

Resources

Special thanks

  • Candas for their help on handling the GD32 chip.
  • Emanuel Feru for their amazing work on different boards.
  • All the folks at Hooover for their advice and ideas.