GigaDevice Semiconductor is a leading fabless semiconductor company based in Beijing. They started life designing NOR flash memory and in 2013 started the production of microcontrollers, offering a whole family of devices (the GD32 series) based on the Arm Cortex-M architecture and up to now they offer more than 360+ part numbers of Arm Cortex-M MCUs, making them the biggest Chinese MCU supplier.

The GD32F103 caused a stir when it was introduced, offering fast execution and a large (zero wait-state) flash memory. In the meantime, GigaDevice has expanded its range of MCU’s with devices built around Arm Cortex-M3, Arm Cortex-M4, Arm Cortex-M23 and Arm Cortex-M33 cores. The range of devices currently available from GigaDevice [1] is shown below in Figure 1. GigaDevice also adds various peripheral devices to their MCU’s, some models even support a USB OTG function.

Figure 1. GigaDevice offers a good range of Arm® Cortex®-M 32-bit MCUs.

Armed with which board?

The family of GD32 microcontrollers includes variants with large flash memory banks but for device evaluation purposes we focus on the peripherals. The Arm Cortex-M23 based microcontrollers, GD32E230, GD32E231 and GD32E232 offer a good compromise of performance against cost. The entry-level series GD32E230 (value) offers a clock rate of up to 72MHz.

GigaDevice offers an extensive range of development tools [2] for the GD32 family. Click on the “View evaluation boards” link to see the range of full-function evaluation boards available. Clicking on the “View Starter Kits” takes you to the range of more basic starter boards with a white colored PCB.

Both the target board and the GD32 device are supplied with power via the mini-USB socket and the GD-Link USB socket is intended for the debugger and in some cases, it can be used for power too. As for the programming and debugging device, you can use the GD-Link 3-in-1 tool, the Segger J-Link or any other Arm programming tool.

The first time you connect a fresh starter board to the PC using a USB cable, the board runs a pre-programmed routine which blinks one of the board’s LEDs and also monitors the User Key push-button so that you can toggle the state of another LED on the board.

Figure 2. GD32E230C-EVAL.

At this point we need to select an evaluation board. GigaDevice offers about a dozen different boards here. Documentation support for the range of development boards can be found at www.GD32MCU.com. If the website loads in Chinese, just click on English link at the top right of the page to switch languages. The author used the GD32E230C-EVAL board for the rest of this article (see Figure 2). This board uses the GD32E230 microcontroller.

Installing the IDE

In the first step, go to the URL https://www2.keil.com/mdk5/editions/lite and click on the Download & Install button. The KEIL website takes you to another window where you can then click on the option “Download MDK-Core”. After registering, you can download the (approximately 850 MB) MDK529.EXE file. Once downloaded, you can install it like any other Windows program (see Figure 3).

The next step is to install the device pack, which can be found on the www.GD32MCU.com under the “Tools and Software” and the one we need in our case is under GigaDevice GD32E2 Series Device Support and Examples where we can select and download the version GigaDevice.GD32E23x_DFP.1.0.0.pack. Once downloaded, you can install it like we did before.

Figure 3. Keil Installation.

The next step is to download the firmware library for the GD32E23x devices and their associated example projects. Both files can be found at the “GD32E23x Demo Suites” under the download “Evaluation Board” list on the “Download” tab. We extract the file and we place it in the file “Keil_v5_for_gigadevice” that we created on the MDK installation earlier.

Under the following path “ GD32E23x_Demo_Suites_V1.0.1GD32E230C_EVAL_Demo_Suites Projects“ we can find the example projects for our board. We then open one of the projects. The project’s folder structure is shown below in Figure 4.

Figure 4. GigaDevice project’s folders structure.

We open the main.c file located in the “Application“ file and try a compilation, which ends with the following success message: “. output GD32E230C_EVAL.axf” - 0 Error (s), 0 Warning (s).

Run the program

Connect the board to the PC with a USB mini cable — don’t be surprised if Windows doesn’t display a driver installation prompt. Instead, click “Options for Target” in the KEIL environment to open the settings window for the target and then move to the “Debug” tab.

In the “Use” section you decide on the value CMSIS-DAP because you are using the GD-Link debugger. You can also use the Segger J-Link debugging tool and in the “Use“ section you should select “J-Link/J-TRACE Cortex“ instead. Actual selection of the target device takes place by selecting from a drop-down list by clicking on the Settings button. In the SWDIO section, the device should then appear selected — as shown below in Figure 5.

Figure 5. KEIL is set to the GD32 target device.

Then move to the “Utilities” tab, unckeck the “Use Debug Driver“ checkbox, then click on “Settings”, select the flash type that matches with the flash type on the onboard MCU chip and then click “Add“ and “Ok” as in shown below in Figure 6.

Figure 6. Flash memory settings.

Now download the program to the development board which overwrites the pre-programmed flash memory and stops the LED flashing.

The code at a glance

The GigaDevice microcontrollers are generally programmed using CMSIS. Nevertheless, there is a native API that we want to look at first in the main.c file. At entry point we open the main.c file and find the following code:

int main(void)

{

systick_config();

.

.

.

}

Similar to microcontrollers from other manufacturers, configuration of the clock tree must also be done in the code. For our relatively simple example here, the necessary code looks like this:

void systick_config(void)

{

/* setup systick timer for 1000Hz interrupts */

if (SysTick_Config(SystemCoreClock / 1000U)){

/* capture error */

while (1){

}

}

/* configure the systick handler priority */

NVIC_SetPriority(SysTick_IRQn, 0x00U);

}

The LEDs are then configured as you would expect via the GPIO API. It is interesting to note that the GPIO peripheral block must have its clock enabled before use:

/* enable the LED1 GPIO clock */

rcu_periph_clock_enable(RCU_GPIOA);

/* configure LED1 GPIO port */

gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_ PUPD_NONE, GPIO_PIN_8);

gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);

/* reset LED1 GPIO pin */

gpio_bit_reset(GPIOA,GPIO_PIN_8);

This looks quite familiar. The first step is to set up the communication direction, then we configure the GPIO output signal slew rate using the GPIO_OSPEED_50MHZ parameter and go on to assign the GPIO to the LED pin used to configure the driver hardware.

Next we will take a look at the analogue to digital converter project. The Arm Cortex-M based microcontroller from GigaDevice currently does not support a graphical configuration tool. Therefore, expand the Order Peripherals and then double-click on the gd32e23x_adc.c file. We can enable the ADC hardware using adc_enable(void) which writes directly into some registers, which are assigned physical addresses in a header file:

void adc_enable(void)

{

if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){

ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON;

}

}

It is interesting that the GigaDevice microcontroller does not return any data structures from this function used. This trend also continues in the deactivation method void adc_ disable (void), which also does not expect any parameters and writes directly to the register:

void adc_disable(void)

{

ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ADCON);

}

Next we turn to the I2C peripheral: it is traditionally another area where the chip manufacturers design paradigms are clearly visible. Open the file gd32e23x_i2c.c, which can also be found in the “GD32E23x_Peripherals” folder. Here you will find confirmation of the usage identified above. GigaDevice does not use structures in the GD32 API to describe peripheral devices. For example when we need to deinitialize or reset an I2C register to its default values, we can pass the numeric ID of the target channel when we call:

void i2c_deinit(uint32_t i2c_periph)

{

switch(i2c_periph){

case I2C0:

/* reset I2C0 */

rcu_periph_reset_enable(RCU_I2C0RST);

rcu_periph_reset_disable(RCU_I2C0RST);

break;

case I2C1:

/* reset I2C1 */

rcu_periph_reset_enable(RCU_I2C1RST);

rcu_periph_reset_disable(RCU_I2C1RST);

break;

default:

break;

}

}

Developers not familiar with the language C before may be curious of the uint32_t data type; this just describes any 32-bit unsigned integer. The bottom line is that the GD32 API uses an old school hardware abstraction layer. In practice, the GD32 peripherals are quite straightforward to work with.

Conclusion

Developers using the KEIL embedded development tools should have minimal effort to work with the GD32 devices. With experience you will discover that family of chips from GigaDevice represents a good range of well-thought-out and very powerful 32-bit microcontrollers, some of which offer a number of additional features compared with the products available from alternative manufacturers.

Web Links

[1] GigaDevice Product Selection Guide: www.gigadevice. com/wp-content/uploads/2019/06/GigaDevice-Product- Selection-Guide.pdf

[2] GigaDevice GD32 Development Tools: www.gigadevice. com/products/microcontrollers/gd32-development-tools/


Expand reading