2020-04-03
md
Blink with a Wio Lite RISC-V with ESP8266
-> <-"Hello World!" with the Longan Nano

In a recently arrived package from Seeed Studio there was a Wio Lite RISC-V WiFi module. This board uses the same 32-bit GD32VF103CBT6 core as used on the Longan Nano by Sipeed. There is an additional ESP8266 Wio Core for Wi-Fi connectivity.

Table of Contents

  1. Wio Lite RISC-V WiFi
  2. pinout
  3. PlatformIO Only
  4. Compiling Blink
  5. Installing the Latest dfu-utils Package
  6. Uploading With USB (DFU)
  7. Adding Serial Output
  8. Downloading the Example Blink Projects
  9. Next

Wio Lite RISC-V WiFiBoard toc

The Wio Lite RISC-V is a development board based on a 32-bit GD32VF103CBT6 core by GigaDevice and a ESP8266 Wio core. It resembles a wasp with the ESP8266 being the thorax and a Feather form-factor abdomen carrying the RISC-V processor. Through holes for standard 0.1" headers along the long edges of the abdomen are connected to the RISC-V core. The distance between the headers is breadboard compatible. In keeping with the Feather standard, there is a JST2.0 Lipo battery port on the top side. Its presence means that header pins should be soldered on the bottom side of the board as done with other Feather boards. Hopefully the micro SD slot on the bottom side will not be in the way. There is a provision for a JTAG connector on the abdomen near the waist and through holes for a Wio Core I/O header are situated above the waist. Since the latter are not breadboard compatible, any installed connector or header should be soldered on the top side. The USB-C connector is used to power the device and to upload new firmware.

The 108 MHz, 32 bit, GD32VF103CBT6 has impressive capabilities.

The Wio Core "can be considered equivalent to [the] ESP-WROOM-02 except that the original firmware is replaced with [Wio platform] firmware."

Pinout toc

So far, I have not seen an official pinout. Here is my poor attempt at documenting the connections on the board based on the schematic and the GD32VF103 Datasheet (rev 1.1). Imagine that the board is in the narrow white column in the centre, with the USB-C connector visible and at the bottom (as shown in the left photograph above). The header numbers correspond to the numbering on the schematic and follow the convention of assigning number 1 to the pin with the square solder mask. The labels with the green background next to the pin numbers are those printed on the board. Basically they are the pin name and default function of the corresponding core pins as described in section 2.6.3 GD32VF103Cx pin definitions of the data sheet. The labels with the white background are those found on the schematic. The Function column gives the alternate function description of the pin, any function after a ";" is a remap function (whatever that means, I obviously have a lot to learn).

Wio Lite RISC-V WiFi
Function (alternate; remap) Schematic Headers Schematic Function (alternate; remap)
I2C1_SDA, USART2_RX; TIMER1_CH3 PB11_SDA PB11 12 1 RST MCU_NRST Reset
I2C1_SCL, USART2_TX; TIMER1_CH2 PB10_SCL PB10 11 2 3V3 3.3 volt
I2C0_SDA, TIMER3_CH1; USART0_RX PB7_D5 PB7 10 3 VDDA VDDA
USART0_CK, TIMER0_CH0, CK_OUT0, USBFS_SOF PB8_D6 PB8 9 4 GND Ground
I2C0_SMBA, SPI2_MOSI, I2S2_SD; TIMER2_CH1, SPI0_MOSI, CAN1_RX PB5_D9 PB5 8 5 PA0 PA0_A0 WKUP, USART1_CTS, ADC0_IN0; TIMER1_CH0_ETI, TIMER4_CH0
ADC01_IN9, TIMER2_CH2; TIMER0_CH1_ON PB0_D10 PB0 7 6 PA1 PA1_A1 USART1_RTS, ADC01_IN1, TIMER4_CH1, TIMER1_CH1
SPI1_NSS, I2S_WS, I2C1_SMBA, USART2_CK, TIMER0_BRKIN, CAN1_RX PB12_D11 PB12 6 7 PA4 PA4_A4 SPI0_NSS, USART1_CK, ADC01_IN4; SPI2_NSS, I2S2_WS
I2C0_SCL, TIMER3_CH0; USART0_TX, CAN1_TX PB6_D12 PB6 5 8 PA5 PA5_A5 SPI0_SCK, ADC01_IN5, DAC_OUT1
TIMER3_CH3; I2C0_SDA, CAN0_TX PB9_D13 PB9 4 9 PA6 PA6_A6 SPI0_MISO, ADC01_IN6, TIMER2_CH0; TIMER0_BRKIN
5 volt 5V 3 10 PA7 PA7_A7 SPI0_MOSI, ADC01_IN7, TIMER2_CH1; TIMER0_CH0_ON
Ground GND 2 11 PB13 PB13_SPI1_SCK SPI1_SCK, I2S1_CK, USART2_CTS, TIMER0_CH0_ON, CAN1_TX
MCU_VBAT VBAT 1 12 PB15 PB15_SPI1_MOSI SPI1_MOSI, TIMER0_CH2_ON, I2S1_SD
13 PB14 PB14_SPI1_MISO USART0_CK, TIMER0_CH0, CK_OUT0, SPI1_MOSI, TIMER0_CH2_ON, I2S1_SD
14 PA10 PA10_UART0_RX_D0 USART0_RX, TIMER0_CH2, USBFS_ID
15 PA9 PA9_UART0_TX_D1 USART0_TX, TIMER0_CH1, USBFS_VBUS
16 GND Ground

The blue LED beside the USB-C connector and below the reset push button switch is connected to pin PA8 and is active high. Pins PA11 and PA12 are connected to the D- and D+ USB data lines. The SD-card slot is connected with SPI bus 1. As far as I can determine, the only connection between the RISC-V core and the ESP core is through a two wire serial connection, USART1 (RX = PA3, Tx = PA2) on the RISC-V side.

PlatformIO Only toc

The Wio Lite RISC-V WiFi is quite new. There is no support for the board in the Arduino IDE. Furthermore, I cannot find much information about it on the Web, and the vendor does make it clear that the PlatformIO environment is the only currently available playground.

Since it uses the same microprocessor as the Sipeed Longan Nano, I assumed that programming it would be relatively similar. Indeed, I managed to upload a blink firmware to the device. The sketch was written for the Arduino framework in PlatformIO on a Linux desktop. In the following discussion on how to proceed, it will be assumed that PlatformIO (PIO for short) is installed and working properly on the desktop, but if not, here are the installation instructions.

Compiling Blink toc

Just started a new project

  1. If PIO Home is not open, click on the PIO icon on the left edge,
  2. Select QUICK ACCESS/PIO Home/Open in the PLATFORMIO LIST in the left panel.
  3. Click on + New Project in the PIO Home page.

A Project Wizard window will pop up.

  1. Set the project name. I chose Wioblink.
  2. Select the board. I entered "Wio" in the box and then scrolled down the list of boards with "Wio" somewhere in their name.
  3. Select Wio Lite RISC-V (SeeedStudio).

  1. Change the framework from GigaDevice GD32V SDK to Arduino
  2. Click on the Finish button.

PIO will obtain the platform toolchain and set up the project as a directory with assorted subdirectories all shown in the EXPLORER panel on the left.

  1. Click on the src directory and then on the main.cpp file name in the EXPLORER panel.
  2. The typical bare source template will be displayed in the main.cpp tab. Replace the bare setup() and loop() functions with those in the standard Arduino Blink sketch. Do not remove the #include <Arduino.h> directive at the top of the file; it is necessary in PlatformIO when using the Arduino platform, it is implicit in the Arduino IDE. Note that I shortened the LED on time by an order of magnitude for a reason to be explored below.
  3. Click on the PlatformIO: Build icon. It is the check mark on the tool bar along the bottom of the application window.

If everything worked, then success should be reported as shown below.

However at the time of writing this post, the build fails because of a missing variant pins_arduino.h file.

/home/michel/.platformio/packages/framework-arduino-gd32v/cores/arduino/Common.h:11:10: fatal error: pins_arduino.h: No such file or directory

I have found two ways to solve this problem which hopefully will be resolved quickly.

Quick fix:

  1. Click on platformio.ini in the EXPLORER panel. (If the panel is not visible, click on the "sheets of paper" icon below File or use the CtrlShiftE keyboard shortcut).
  2. Change the board definition to board = gd32vf103v-eval.
  3. In main.cpp add the following line above the setup() function:
    #define LED_BUILTIN PA8
  4. Compile the project and this time it should work.

With the gd32vf103v-eval or sipeed-longan-nano board definition, the I/O pin names such as PA9 will work correctly because all three boards use the same GD32VF103 chip. However the on board LEDs are connected to different I/O pins. That is why it was necessary to redefine LED_BUILTIN in main.cpp. The compiler will complain, but it will work.

Better fix?

I will not go into the details.

  1. If it does not exist, create a subdirectory named wio_lite_risc-v in ~/.platformio/packages/framework-arduino-gd32v/variants/.
    ; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:wio_lite_risc-v] platform = gd32v ;board = wio_lite_risc-v board = gd32vf103v-eval framework = arduino
  2. Copy the missing files pins_arduino.h and pins_arduino.c which can be found in Longuino GitHub repository into /home/michel/.platformio/packages/framework-arduino-gd32v/variants/wio_lite_risc-v.
  3. Compile the project and this time it should work.

Presumably, the missing variant files will be added in the repository. I have attempted to use the upstream development platform with no success. PlatformIO documentation on the Wio Litd RISC-V board says "Please use wio_lite_risc-v ID for [the] board option", which is why this solution may be better in the long run. However, I hope that meddling in the gd32v package will not be the cause of problems when it is updated.

Now there remained the task of uploading the binary to the Wio.

Installing the Latest dfu-utils Package toc

If you have already uploaded firmware to a GD32VF103 based board such as the Sipeed Longan Nano, then you can skip this section.

As far as I can ascertain, it is not possible to upload with a serial connection. Instead the DFU (Device Firmware Upgrade) protocol will be used to upload the firmware over the USB connection. As far as I know, dfu-util is the only way to support this mechanism on a desktop running Linux. Unfortunately, the version of the utility that is installed with GD32V package in PIO is not up to date and it will not work. I tried installing the package available in the Ubuntu repository

michel@hp:~$ sudo apt-cache policy dfu-util dfu-util: Installé : (aucun) Candidat : 0.9-1 Table de version : 0.9-1 500 500 http://ca.archive.ubuntu.com/ubuntu bionic/universe amd64 Packages

It certainly looked recent enough, but it would not work. It is necessary to build dfu-utils from the source. Again following advice found on the Web, I tried the gd32-dfu-utils which is supposed to be a fork of dfu-utils that added GD32VF103 support without success. The same type of error occured when trying with a more recent fork of the fork. In the end what worked was the latest version of dfu-utils on SourceForge. I followed the instructions by dr-br to download and compile the latest version of dfu-utils package.

michel@hp:~$ git clone https://git.code.sf.net/p/dfu-util/dfu-util ... michel@hp:~$ cd dfu-utils michel@hp:~/dfu-util$ ./autogen.sh autoreconf: Entering directory `.' ... autoreconf: Leaving directory `.' michel@hp:~/dfu-util$ ./configure --prefix=$HOME/.local checking for a BSD-compatible install... /usr/bin/install -c ... ... config.status: creating doc/Makefile config.status: creating config.h config.status: executing depfiles commands michel@hp:~/dfu-util$ make -j install Making install in src ... make[1] : on quitte le répertoire « /home/michel/dfu-util » michel@hp:~/dfu-util$ cd ~

If the configure command given had been ./configure --prefix=$HOME as suggested by dr-br, the utilities would have ended up in a ~/bin which is not in the search path on my system. I checked that the utility was installed in my .local/bin directory.

michel@hp:~$ ls -l ..dfu-* -rwxr-xr-x 1 michel michel 47944 mar 31 17:52 ../.local/bin/dfu-prefix -rwxr-xr-x 1 michel michel 47936 mar 31 17:52 ../.local/bin/dfu-suffix -rwxr-xr-x 1 michel michel 175680 mar 31 17:52 ../.local/bin/dfu-util

I copied those three dfu-* files in /.local/bin/ on top of the files in ~/.platformio/packages/tool-gd32vflash/.

Uploading With USB in Platformio (DFU) toc

The project configuration file platformio.ini should have the following content.

... [env:wio_lite_risc-v] platform = gd32v framework = arduino board = wio_lite_risc-v upload_protocol = dfu

In other words, add upload_protocol = dfu to the configuration file. Note that I am using the "better fix" for the missing variant files.

Connect the USB-C cable to the desktop and the Wio, slide the BOOT0 switch towards the battery connector and press the reset button across from the connector. The board is now in download mode. Before uploading the firmware, it is not a bad idea to check that the Wio now shows up as an anonymous USB device with ID 28e9:0189 and to check that there is a UDEV rule for the device. You can even check that the installeddfu utility recognizes the Wio.

michel@hp:~$ lsusb ... Bus 003 Device 071: ID 28e9:0189 ... michel@hp:~$ sudo cat /etc/udev/rules.d/99-platformio-udev.rules | grep 28e9 ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" michel@hp:~$ .platformio/packages/tool-gd32vflash/dfu-util -l dfu-util 0.9 ... Found DFU: [28e9:0189] ver=0100, devnum=71, cfg=1, intf=0, path="3-10", alt=0, name="@Internal Flash /0x08000000/128*001Kg", serial="3CBJ"

Click on the PlatformIO: Upload icon on the tool bar along the bottom of the application window. You will probably see something contradictory like this.

Download done. File downloaded successfully dfu-util: Error during download get_status *** [upload] Error 74 ============================ [FAILED] Took 2.03 seconds ============================ The terminal process terminated with exit code: 1

PIO gave an even scarier FAILED message, but the new firmware was uploaded to the Wio. Change the LED frequency, press on the reset and upload the firmware to the Wio again just to confirm that the new firmware was installed.

Do not forget to slide the BOOT0 switch back up towards the BOOT0 label. Otherwise when the board is powered up in the future, it will appear to be defective while it is merely waiting for new firmware as it will be in download mode.

Adding Serial Output toc

It is not too difficult to output text to the terminal, but the Serial class used in Arduino to do this is not available. Instead, USART0 will be initialized explicitly and output to the terminal will be through printf which by default sends its ouyput to the UART. The source for this is a Sipeed documentation page entitled UART. The document is not available in English, so thank you Google translate.

<#include <Arduino.h> #include <stdio.h> #define CYCLES 2           // 2 yields a heartbeat effect #define SHORT_DELAY  100   // 1/10 second #define LONG_DELAY  1000   // 1 second static void wio_serial_init(void) {   // enable GPIO clock   rcu_periph_clock_enable(RCU_GPIOA);   // enable USART clock   rcu_periph_clock_enable(RCU_USART0);     // USART configure   usart_deinit(USART0);         usart_baudrate_set(USART0, 115200U);   usart_word_length_set(USART0, USART_WL_8BIT);   usart_stop_bit_set(USART0, USART_STB_1BIT);   usart_parity_config(USART0, USART_PM_NONE);   usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);   usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);   usart_receive_config(USART0, USART_RECEIVE_ENABLE);   usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);   usart_enable(USART0); } /* // retarget the C library printf function to USART0 // Not needed, see the _put_char functino in //   ~.platformio/packages/framework-arduino-gd32v/cores/arduino/GD32VF103_Firmware_Library/RISCV/stubs/write.c extern "C" int _put_char(int ch) // used by printf {    usart_data_transmit(USART0, (uint8_t) ch );    while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET){    }    //delay(100);  // make it obvious the function is being used    return ch; } */ // the setup function runs once when you press reset or power the board void setup() {   // initialize digital pin LED_BUILTIN as an output.   pinMode(LED_BUILTIN, OUTPUT);     wio_serial_init();      printf("\nSeeed Wio Lite RISC-V WiFi\n");   printf("==========================\n");   printf("Platform: Arduino\n");   printf("LED_BUILTIN: %d\n", LED_BUILTIN);   printf("\n");    } // the loop function runs over and over again forever void loop() {   for (int i=0; i<CYCLES; i++) {     digitalWrite(LED_BUILTIN, HIGH);  // turn the red LED on     printf("ON ");                    // update terminal     delay(SHORT_DELAY);               // wait for a short on period     digitalWrite(LED_BUILTIN, LOW);   // turn the red LED off     delay(SHORT_DELAY);               // wait for a short off period   }       digitalWrite(LED_BUILTIN, LOW);     // turn the LED off   printf("OFF\n");                    // update terminal   delay(LONG_DELAY);                  // wait for a long off period }

Modify the platformio.ini configuration file by adding the baud of the serial connection.

... [env:wio_lite_risc-v] platform = gd32v board = wio_lite_risc-v framework = arduino upload_protocol = dfu monitor_speed = 115200

Upload the firmware to the Wio as describe above. Do not forget to return the BOOT0 switch away from the battery connector.

To see the output it will be necessary to connect a USB to TTY (3.3 volt) converter to the Wio. Do this with the USB-C cable disconnected, and the USB - TTY converter not connected to the desktop. USB to TTY converters that support both 3.3 and 5 volts, select 3.3 volts. Do not use a 5 volt converter. Make sure your converter will output 3.3 volt signals otherwise the Nano will be damaged. Finally, connect the converter Rx pin to the USART0_TX pin of the Wio which is pin PA9 (physical pin 15). The next pin (physical pin 16, the last pin beside the reset button) is the ground pin which has to be connected to the ground pin of the converter. Connect the USB-C cable and the USB end of the USB - TTY converter to the desktop.

The output will be sent to the serial port just as soon as power is the firmware is uploaded. If the terminal is not visible then click on the PlatformIO: Serial Monitor icon, which looks like a 2 prong plug facing up on the bottom tool bar. To view the beginning of the output, press on the RESET button on the Wio.

... ON ON OFF ON ON OFF ON ON OFF Pressed Wio reset button Seeed Wio Lite RISC-V WiFi ========================== Platform: Arduino LED_BUILTIN: 8 ON ON OFF ON ON OFF ON ON OFF ON ON OFF ...

Downloading the Example Blink Projects toc

Three Blink projects can be downloaded with the following links.

Just extract the content of the archive somewhere in the PlatformIO projects directory. Here is one way to do it in Linux.

michel@hp:~$ wget https://sigmdel.ca/michel/ha/gd32v/dnld/wioblink.zip ... 2020-04-01 13:19:10 (770 KB/s) - «wioblink.zip» enregistré [4982/4982] michel@hp:~$ mkdir -p Documents/PlatformIO/Projects/wio_risc-v/blink1 michel@hp:~$ unzip nanoblink.zip -d Documents/PlatformIO/Projects/wio_risc-v/blink1 Archive: wioblink.zip inflating: Documents/PlatformIO/Projects/wio_risc-v/blink1/platformio.ini ... michel@hp:~$ ls Documents/PlatformIO/Projects/wio_risc-v/blink1 include lib platformio.ini src michel@hp:~$ rm wioblink.zip

Note that I decided to put the wioblink example project in a subdirectory, called wio_risc-v, of the PlatformIO project directory. The -p option of the mkdir command creates all needed directories along the specified path. In other words, it created directory wio_risc-v before creating blink1 inside of it.

To start using a downloaded project

  1. Click on the Open Project button in the PIO Home page
  2. Click on the Projects folder in the Places section of the Favorites panel
  3. Navigate to the desired project directory such as ~Documents/PlatformIO/Projects/wio_risc-v/blink1
  4. Click on the Open "blink1" button.

The project can now be compiled.

Next toc

There will not be a next step until work on the Wio platform is updated. Right now, the example code showing how to communicate with the ESP8266 does not compile. Now that's ok, because the same package that brought me this module included a Longan Nano, which I have already written about and a Seeeduino XIAO about which a post will be available shortly.

-> <-"Hello World!" with the Longan Nano