From 7f27e6cc7ffe4c8cda2a6f95d3d0ccbfb6b0dc54 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Jan 2024 09:17:18 +0100 Subject: [PATCH] boards/gd32vf103c-start: new board This adds support for the GD32VF103C-START, the official "starter board" for the GD32VF103C MCU by the MCU vendor. --- boards/gd32vf103c-start/Makefile | 3 + boards/gd32vf103c-start/Makefile.dep | 5 + boards/gd32vf103c-start/Makefile.features | 24 +++ boards/gd32vf103c-start/Makefile.include | 10 + boards/gd32vf103c-start/dist/openocd.cfg | 2 + boards/gd32vf103c-start/doc.txt | 103 +++++++++++ .../gd32vf103c-start/include/arduino_iomap.h | 150 +++++++++++++++ boards/gd32vf103c-start/include/board.h | 53 ++++++ boards/gd32vf103c-start/include/gpio_params.h | 52 ++++++ boards/gd32vf103c-start/include/periph_conf.h | 174 ++++++++++++++++++ 10 files changed, 576 insertions(+) create mode 100644 boards/gd32vf103c-start/Makefile create mode 100644 boards/gd32vf103c-start/Makefile.dep create mode 100644 boards/gd32vf103c-start/Makefile.features create mode 100644 boards/gd32vf103c-start/Makefile.include create mode 100644 boards/gd32vf103c-start/dist/openocd.cfg create mode 100644 boards/gd32vf103c-start/doc.txt create mode 100644 boards/gd32vf103c-start/include/arduino_iomap.h create mode 100644 boards/gd32vf103c-start/include/board.h create mode 100644 boards/gd32vf103c-start/include/gpio_params.h create mode 100644 boards/gd32vf103c-start/include/periph_conf.h diff --git a/boards/gd32vf103c-start/Makefile b/boards/gd32vf103c-start/Makefile new file mode 100644 index 0000000000..f8fcbb53a0 --- /dev/null +++ b/boards/gd32vf103c-start/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/gd32vf103c-start/Makefile.dep b/boards/gd32vf103c-start/Makefile.dep new file mode 100644 index 0000000000..a7dc06f36c --- /dev/null +++ b/boards/gd32vf103c-start/Makefile.dep @@ -0,0 +1,5 @@ +ifneq (,$(filter saul_default,$(USEMODULE))) + USEMODULE += saul_gpio +endif + +include $(RIOTBOARD)/common/gd32v/Makefile.dep diff --git a/boards/gd32vf103c-start/Makefile.features b/boards/gd32vf103c-start/Makefile.features new file mode 100644 index 0000000000..d663f67652 --- /dev/null +++ b/boards/gd32vf103c-start/Makefile.features @@ -0,0 +1,24 @@ +CPU_MODEL = gd32vf103cbt6 + +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_adc +FEATURES_PROVIDED += periph_i2c +FEATURES_PROVIDED += periph_pwm +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_usbdev +FEATURES_PROVIDED += sdcard_spi + +# Other features provided by the board (in alphabetical order) +FEATURES_PROVIDED += arduino_analog +FEATURES_PROVIDED += arduino_i2c +FEATURES_PROVIDED += arduino_pins +FEATURES_PROVIDED += arduino_pwm +FEATURES_PROVIDED += arduino_shield_uno +FEATURES_PROVIDED += arduino_spi +FEATURES_PROVIDED += arduino_uart +FEATURES_PROVIDED += highlevel_stdio +FEATURES_PROVIDED += tinyusb_device + +include $(RIOTBOARD)/common/gd32v/Makefile.features diff --git a/boards/gd32vf103c-start/Makefile.include b/boards/gd32vf103c-start/Makefile.include new file mode 100644 index 0000000000..4d7b8f4bab --- /dev/null +++ b/boards/gd32vf103c-start/Makefile.include @@ -0,0 +1,10 @@ +PORT_LINUX ?= /dev/ttyACM0 +PROGRAMMER ?= openocd +OPENOCD_DEBUG_ADAPTER ?= dap +OPENOCD_TRANSPORT := default + +# Only consider TTYs matching the following filter when auto-selecting the TTY +# with `MOST_RECENT_PORT=1`. +TTY_BOARD_FILTER := --driver 'ch341' --model 'USB2.0-Serial' + +include $(RIOTBOARD)/common/gd32v/Makefile.include diff --git a/boards/gd32vf103c-start/dist/openocd.cfg b/boards/gd32vf103c-start/dist/openocd.cfg new file mode 100644 index 0000000000..a1f4f41ecf --- /dev/null +++ b/boards/gd32vf103c-start/dist/openocd.cfg @@ -0,0 +1,2 @@ +adapter speed 10000 +source [find target/gd32vf103.cfg] diff --git a/boards/gd32vf103c-start/doc.txt b/boards/gd32vf103c-start/doc.txt new file mode 100644 index 0000000000..b23b962e91 --- /dev/null +++ b/boards/gd32vf103c-start/doc.txt @@ -0,0 +1,103 @@ +/** +@defgroup boards_gd32vf103c_start GD32VF103C-START +@ingroup boards +@brief Support for the GD32VF103C-START board +@author Marian Buschsieweke + +## Overview + +The GD32VF103C-START development board is an official starter kit by GigaDevice +for the GD32VF103CBT6 MCU, despite the lack of official documentation. It +featrures: + +- GD32VF103CBT6 RISC-V MCU @108MHz +- On-Board GD-Link Programmer/Debugger (middle mini-USB connector) +- USB-OTG (left mini-USB connector) +- Integrated USB to UART bridge (right mini-USB connector) +- 1 user LED +- 1 user Button +- 1 reset button +- Arduino UNO compatible pin headers (except ISP header) + +![Image of the GD32VF103C-START board](https://raw.githubusercontent.com/zephyrproject-rtos/zephyr/a0ac2faf9bde45b176f1e8b315ffb1b8a9096166/boards/riscv/gd32vf103c_starter/doc/img/gd32vf103c_starter.jpg) + +@warning The analog pins are labeled A1 - A6 rather than A0 - A5, as would + be the correct Arduino naming. The Arduino pin mapping uses the + correct Arduino naming, so that apps written for other boards + expecting Arduino UNO compatible shields remain compatible. + +## Hardware + +| MCU | GD32VF103CBT6 | Supported | +|:----------------- |:----------------------------------------- | --------- | +| Family | RISC-V with ECLIC | | +| Vendor | GigaDevice | | +| RAM | 32 KiB | | +| Flash | 128 KiB | | +| Frequency | 108 MHz | | +| Power Modes | 3 (Sleep, Deep Sleep, Standby) | yes | +| GPIOs | 37 | yes | +| Timers | 5 x 16-bit timer | yes | +| RTC | 1 x 32-bit counter, 20-bit prescaler | yes | +| WDT | 2 x 12-bit counter, 3-bit prescaler | yes | +| ADC | 2 x 12-bit units, 16 channels @ 1 Msps | yes | +| DAC | 2 x 12-bit channel | yes | +| UART | - | yes | +| USART | 3 | yes | +| SPI | 3 | yes | +| I2C | 2 x Fast Mode 400 kHz | yes | +| I2S | 2 | no | +| CAN | 2 x CAN 2.0B with up to 1 Mbps | no | +| PWM | 6 Channels | yes | +| USB | 1 x USB FS OTG (+ GD-Link + UART bridge) | yes | +| Vcc | 3.0V - 3.6V | | +| Datasheet | [Datasheet][gd32vf103c-datasheet] | | +| User Manual | [User Manual][gd32vf103c-manual] | | +| Board Manual | [Board Manual][gd32vf103c-board-manual] | | + +[gd32vf103c-datasheet]: https://web.archive.org/web/20240117072854/https://gd32mcu.com/data/documents/datasheet/GD32VF103_Datasheet_Rev1.6.pdf +[gd32vf103c-manual]: https://web.archive.org/web/20240117073025/https://gd32mcu.com/data/documents/userManual/GD32VF103_User_Manual_Rev1.5.pdf +[gd32vf103c-board-manual]: https://web.archive.org/web/20240117072723/https://en.maritex.com.pl/product/attachment/154626/6f28fdabafb9dff852537ced7bc0aa71 + +## Flashing + +@warning Flashing seems to fail with some Arduino UNO compatible boards + attached. Remove them and try again. + +By default, flashing is done via OpenOCD using the GD-Link programmer/debugger +using: + +``` +make BOARD=gd32vf103c-start -C path/to/app flash +``` + +It is also possible to flash via DFU-Util: + +1. Connect a mini USB cable to the USB connector labeled OTG. +2. Power the board (e.g. by connecting a second mini USB cable to the GD-Link + programmer/debugger, even though we won't use it) +3. Enter the DFU bootloader by placing the jumper on JP4 (below BOOT) in + position H. Press the reset button afterwards. +4. Run `make BOARD=gd32vf103c-start PROGRAMMER=dfu-util -C path/to/app flash` +5. Restore the JP4 jumper to position L. Afterwards press the reset button + again + +## Connecting to the Serial Output + +By default RIOT's uses UART for `stdio`. To access that, connect a mini USB +cable to the connector labeled "USART". In addition a jumper needs to be +placed on JP2 in the "Usart" position; otherwise RIOT's TXD is not connected +to the RXD of the integrated USB UART bridge. Afterwards just run: + +``` +make BOARD=gd32vf103c-start -C path/to/app term +``` + +Alternatively, `stdio_cdc_acm` can be used. In this case the mini USB cable +needs to be connected to the USB connector labeled OTG. + +@note It is safe to keep the jumper at JP2 in "Usart" position or even + remove the jumper with RIOT. PA9 is still used as UART/TXD and VBUS + sensing is disabled anyway. + + */ diff --git a/boards/gd32vf103c-start/include/arduino_iomap.h b/boards/gd32vf103c-start/include/arduino_iomap.h new file mode 100644 index 0000000000..6fa89369d8 --- /dev/null +++ b/boards/gd32vf103c-start/include/arduino_iomap.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2024 Marian Buschsieweke + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_gd32vf103c_start + * @{ + * + * @file + * @brief Mapping from MCU pins to Arduino pins + * + * You can use the defines in this file for simplified interaction with the + * Arduino specific pin numbers. + * + * @author Marian Buschsieweke + */ + +#ifndef ARDUINO_IOMAP_H +#define ARDUINO_IOMAP_H + +#include "macros/units.h" +#include "periph/adc.h" +#include "periph/gpio.h" +#include "periph/pwm.h" +#include "periph_conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Arduino's UART devices + * @{ + */ +#define ARDUINO_UART_D0D1 UART_DEV(0) +/** @} */ + +/** + * @name Arduino's SPI buses + * @{ + */ +/** + * @brief SPI_DEV(0) is connected to D11/D12/D13 + */ +#define ARDUINO_SPI_D11D12D13 SPI_DEV(0) +/** @} */ + +/** + * @name Arduino's I2C buses + * @{ + */ +/** + * @brief The first I2C bus is where shields for the Arduino UNO expect it + */ +#define ARDUINO_I2C_UNO I2C_DEV(0) +/** @} */ + +/** + * @brief Mapping of MCU pins to Arduino pins + * @{ + */ +#define ARDUINO_PIN_0 GPIO_PIN(PORT_A, 10) +#define ARDUINO_PIN_1 GPIO_PIN(PORT_A, 9) +#define ARDUINO_PIN_2 GPIO_PIN(PORT_B, 4) +#define ARDUINO_PIN_3 GPIO_PIN(PORT_B, 5) +#define ARDUINO_PIN_4 GPIO_PIN(PORT_B, 6) +#define ARDUINO_PIN_5 GPIO_PIN(PORT_B, 7) +#define ARDUINO_PIN_6 GPIO_PIN(PORT_B, 8) +#define ARDUINO_PIN_7 GPIO_PIN(PORT_B, 9) + +#define ARDUINO_PIN_8 GPIO_PIN(PORT_B, 1) +#define ARDUINO_PIN_9 GPIO_PIN(PORT_B, 0) +#define ARDUINO_PIN_10 GPIO_PIN(PORT_B, 12) +#define ARDUINO_PIN_11 GPIO_PIN(PORT_B, 15) +#define ARDUINO_PIN_12 GPIO_PIN(PORT_B, 14) +#define ARDUINO_PIN_13 GPIO_PIN(PORT_B, 13) +#define ARDUINO_PIN_14 GPIO_PIN(PORT_B, 11) +#define ARDUINO_PIN_15 GPIO_PIN(PORT_B, 10) + +#define ARDUINO_PIN_16 GPIO_PIN(PORT_A, 1) +#define ARDUINO_PIN_17 GPIO_PIN(PORT_A, 2) +#define ARDUINO_PIN_18 GPIO_PIN(PORT_A, 3) +#define ARDUINO_PIN_19 GPIO_PIN(PORT_B, 4) +#define ARDUINO_PIN_20 GPIO_PIN(PORT_C, 5) +#define ARDUINO_PIN_21 GPIO_PIN(PORT_C, 6) + +#define ARDUINO_PIN_LAST 21 +/** @} */ + +/** + * @name Aliases for analog pins + * @warning Silkscreen label is A1 - A6 instead of A0 - A5. We stick with + * Arduino UNO labeling here so that e.g. board independent drivers + * for shields can be provided. + * @{ + */ +#define ARDUINO_PIN_A0 ARDUINO_PIN_16 +#define ARDUINO_PIN_A1 ARDUINO_PIN_17 +#define ARDUINO_PIN_A2 ARDUINO_PIN_18 +#define ARDUINO_PIN_A3 ARDUINO_PIN_19 +#define ARDUINO_PIN_A4 ARDUINO_PIN_20 +#define ARDUINO_PIN_A5 ARDUINO_PIN_21 +/** @} */ + +/** + * @name Mapping of Arduino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) + +#define ARDUINO_ANALOG_PIN_LAST 5 +/** @} */ + +/** + * @name Mapping of Arduino pins to RIOT PWM dev and channel pairs + * @{ + */ +/** + * @brief PWM frequency + */ +#define ARDUINO_PWM_FREQU KHZ(100) + +#define ARDUINO_PIN_3_PWM_DEV PWM_DEV(0) +#define ARDUINO_PIN_3_PWM_CHAN 0 + +#define ARDUINO_PIN_5_PWM_DEV PWM_DEV(1) +#define ARDUINO_PIN_5_PWM_CHAN 0 + +#define ARDUINO_PIN_6_PWM_DEV PWM_DEV(1) +#define ARDUINO_PIN_6_PWM_CHAN 1 + +#define ARDUINO_PIN_9_PWM_DEV PWM_DEV(0) +#define ARDUINO_PIN_9_PWM_CHAN 1 +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ARDUINO_IOMAP_H */ +/** @} */ diff --git a/boards/gd32vf103c-start/include/board.h b/boards/gd32vf103c-start/include/board.h new file mode 100644 index 0000000000..bf2b7441d7 --- /dev/null +++ b/boards/gd32vf103c-start/include/board.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 Marian Buschsieweke + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_gd32vf103c_start + * @{ + * + * @file + * @brief Board specific definitions for the GD32VF103C-START board + * + * @author Marian Buschsieweke + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "board_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Button pin definitions + * @{ + */ +#define BTN0_PIN GPIO_PIN(PORT_A, 0) +#define BTN0_MODE GPIO_IN_PU +#define BTN0_INT_FLANK GPIO_FALLING +/** @} */ + +/** + * @name LED (on-board) configuration + * @{ + */ +#define LED0_PIN GPIO_PIN(PORT_A, 7) +#define LED0_MASK (1 << 7) +#define LED0_ON (GPIOA->BC = LED0_MASK) +#define LED0_OFF (GPIOA->BOP = LED0_MASK) +#define LED0_TOGGLE (GPIOA->OCTL ^= LED0_MASK) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/gd32vf103c-start/include/gpio_params.h b/boards/gd32vf103c-start/include/gpio_params.h new file mode 100644 index 0000000000..e68938eed7 --- /dev/null +++ b/boards/gd32vf103c-start/include/gpio_params.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 Marian Buschsieweke + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_gd32vf103c_start + * @{ + * + * @file + * @brief Configuration of SAUL mapped GPIO pins + * + * @author Marian Buschsieweke + */ + +#ifndef GPIO_PARAMS_H +#define GPIO_PARAMS_H + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED/Button SAUL configuration + */ +static const saul_gpio_params_t saul_gpio_params[] = +{ + { + .name = "Wakeup", + .pin = BTN0_PIN, + .mode = BTN0_MODE, + }, + { + .name = "LED0", + .pin = LED0_PIN, + .mode = GPIO_OUT, + .flags = SAUL_GPIO_INIT_CLEAR, + }, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* GPIO_PARAMS_H */ +/** @} */ diff --git a/boards/gd32vf103c-start/include/periph_conf.h b/boards/gd32vf103c-start/include/periph_conf.h new file mode 100644 index 0000000000..17ccc5f8e5 --- /dev/null +++ b/boards/gd32vf103c-start/include/periph_conf.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_gd32vf103c_start + * @{ + * + * @file + * @brief Board specific definitions for the GD32VF103C-START board + * + * @author Marian Buschsieweke + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include "macros/units.h" + +#ifndef CONFIG_BOARD_HAS_HXTAL +#define CONFIG_BOARD_HAS_HXTAL 1 /**< The board provides a high frequency oscillator. */ +#endif + +#ifndef CONFIG_BOARD_HAS_LXTAL +#define CONFIG_BOARD_HAS_LXTAL 1 /**< The board provides a low frequency oscillator. */ +#endif + +#ifndef CONFIG_CLOCK_HXTAL +#define CONFIG_CLOCK_HXTAL MHZ(8) /**< HXTAL frequency */ +#endif + +#ifndef I2C_DEV_1_USED +#define I2C_DEV_1_USED 1 /**< Enable I2C_DEV(1) by default */ +#endif + +#include "periph_cpu.h" +#include "periph_common_conf.h" + +#include "cfg_spi_default.h" +#include "cfg_uart_default.h" +#include "cfg_usbdev_default.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @name I2C configuration + * + * @note This board may require external pullup resistors for i2c operation. + * @{ + */ + +/** + * @brief PB10/PB11 (D15/D14) as I2C for Arduino UNO compatibility + * + * PB10/PB11 are located where Arduino UNO shields expect I2C. + */ +static const i2c_conf_t i2c_config[] = { + { + .dev = I2C1, + .speed = I2C_SPEED_NORMAL, + .scl_pin = GPIO_PIN(PORT_B, 10), + .sda_pin = GPIO_PIN(PORT_B, 11), + .rcu_mask = RCU_APB1EN_I2C1EN_Msk, + .irqn = I2C1_EV_IRQn, + } +}; + +#define I2C_NUMOF ARRAY_SIZE(i2c_config) +/** @} */ + +/** + * @name ADC configuration + * @{ + */ +static const adc_conf_t adc_config[] = { + { .pin = GPIO_PIN(PORT_A, 1), .dev = 0, .chan = 1 }, + { .pin = GPIO_PIN(PORT_A, 2), .dev = 0, .chan = 2 }, + { .pin = GPIO_PIN(PORT_A, 3), .dev = 0, .chan = 3 }, + { .pin = GPIO_PIN(PORT_A, 4), .dev = 0, .chan = 4 }, + { .pin = GPIO_PIN(PORT_A, 5), .dev = 0, .chan = 5 }, + { .pin = GPIO_PIN(PORT_A, 6), .dev = 0, .chan = 6 }, + /* ADC Temperature channel */ + { .pin = GPIO_UNDEF, .dev = 0, .chan = 16 }, + /* ADC VREF channel */ + { .pin = GPIO_UNDEF, .dev = 0, .chan = 17 }, +}; + +#define ADC_NUMOF ARRAY_SIZE(adc_config) +/** @} */ + +/** + * @name Timer configuration + * @{ + */ +static const timer_conf_t timer_config[] = { + { + .dev = TIMER0, + .max = 0x0000ffff, + .rcu_mask = RCU_APB2EN_TIMER0EN_Msk, + .bus = APB2, + .irqn = TIMER0_Channel_IRQn + }, + { + .dev = TIMER1, + .max = 0x0000ffff, + .rcu_mask = RCU_APB1EN_TIMER1EN_Msk, + .bus = APB1, + .irqn = TIMER1_IRQn + }, + /* TIMER2 and TIMER3 are used for PWM pins */ + { + .dev = TIMER4, + .max = 0x0000ffff, + .rcu_mask = RCU_APB1EN_TIMER4EN_Msk, + .bus = APB1, + .irqn = TIMER4_IRQn + } +}; + +#define TIMER_0_IRQN TIMER0_Channel_IRQn +#define TIMER_1_IRQN TIMER1_IRQn +#define TIMER_2_IRQN TIMER4_IRQn + +#define TIMER_NUMOF ARRAY_SIZE(timer_config) +/** @} */ + +/** + * @name PWM configuration + * @{ + */ +static const pwm_conf_t pwm_config[] = { + { + .dev = TIMER2, + .rcu_mask = RCU_APB1EN_TIMER2EN_Msk, + .chan = { + { .pin = GPIO_PIN(PORT_B, 5), .cc_chan = 1 }, + { .pin = GPIO_PIN(PORT_B, 0), .cc_chan = 2 }, + /* unused channels have to be defined by GPIO_UNDEF */ + { .pin = GPIO_UNDEF, .cc_chan = 0 }, + { .pin = GPIO_UNDEF, .cc_chan = 3 }, + }, + .af = GPIO_AF_OUT_PP, + .bus = APB1, + }, + { + .dev = TIMER3, + .rcu_mask = RCU_APB1EN_TIMER3EN_Msk, + .chan = { + { .pin = GPIO_PIN(PORT_B, 7), .cc_chan = 1 }, + { .pin = GPIO_PIN(PORT_B, 8), .cc_chan = 2 }, + /* unused channels have to be defined by GPIO_UNDEF */ + { .pin = GPIO_UNDEF, .cc_chan = 0 }, + { .pin = GPIO_UNDEF, .cc_chan = 3 }, + }, + .af = GPIO_AF_OUT_PP, + .bus = APB1, + }, +}; + +#define PWM_NUMOF ARRAY_SIZE(pwm_config) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ +/** @} */