Skip to content

Add GD32VF103 port #5449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@
[submodule "lib/nxp_driver"]
path = lib/nxp_driver
url = https://github.com/hathach/nxp_driver.git
[submodule "ports/gd32vf103/gd32vf103inator"]
path = ports/gd32vf103/gd32vf103inator
url = https://github.com/esmil/gd32vf103inator.git
14 changes: 13 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ jobs:
- MICROPYPATH=examples/natmod/features2 ./ports/unix/micropython-coverage -m features2
- (cd tests && ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py)
# run coveralls coverage analysis (try to, even if some builds/tests failed)
- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod)
- '[ "x$NOCOVERALLS" != x ] || (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options ''\-o build-coverage/'' --include py --include extmod)'
after_failure:
- tests/run-tests --print-failures

Expand Down Expand Up @@ -394,3 +394,15 @@ jobs:
script:
- make ${MAKEOPTS} -C ports/powerpc UART=potato
- make ${MAKEOPTS} -C ports/powerpc UART=lpc_serial

# gd32vf103 port
- stage: test
name: "gd32vf103 port build"
os: linux
dist: focal
install:
- sudo apt-get install gcc-riscv64-unknown-elf gcc-riscv64-linux-gnu
script:
- make ${MAKEOPTS} -C ports/gd32vf103 submodules
- make ${MAKEOPTS} -C ports/gd32vf103 BUILD=build-baremetal
- make ${MAKEOPTS} -C ports/gd32vf103 BUILD=build-linux CROSS_COMPILE=riscv64-linux-gnu-
2 changes: 2 additions & 0 deletions extmod/extmod.mk
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
lfs2.c \
lfs2_util.c \
)

$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
endif

################################################################################
Expand Down
4 changes: 2 additions & 2 deletions extmod/machine_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ STATIC void mp_machine_soft_i2c_print(const mp_print_t *print, mp_obj_t self_in,
STATIC void machine_i2c_obj_init_helper(machine_i2c_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_scl, ARG_sda, ARG_freq, ARG_timeout };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
};
Expand Down
1 change: 1 addition & 0 deletions extmod/modbluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "py/runtime.h"
#include "extmod/modbluetooth.h"
#include <string.h>
#include <assert.h>

#if MICROPY_PY_BLUETOOTH

Expand Down
1 change: 1 addition & 0 deletions extmod/modlwip.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <string.h>
#include <stdio.h>
#include <assert.h>

#include "py/objlist.h"
#include "py/runtime.h"
Expand Down
3 changes: 2 additions & 1 deletion extmod/moductypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
return mp_obj_new_bytearray_by_ref(uctypes_struct_agg_size(sub, self->flags, &dummy), self->addr + offset);
}
// Fall thru to return uctypes struct object
MP_FALLTHROUGH
}
case PTR: {
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
Expand Down Expand Up @@ -627,7 +628,7 @@ STATIC mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
return mp_obj_new_int((mp_int_t)(uintptr_t)p);
}
}
/* fallthru */
MP_FALLTHROUGH

default:
return MP_OBJ_NULL; // op not supported
Expand Down
1 change: 1 addition & 0 deletions extmod/moduselect.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#if MICROPY_PY_USELECT

#include <stdio.h>
#include <assert.h>

#include "py/runtime.h"
#include "py/obj.h"
Expand Down
1 change: 1 addition & 0 deletions extmod/moduwebsocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>

#include "py/runtime.h"
#include "py/stream.h"
Expand Down
1 change: 1 addition & 0 deletions extmod/modwebrepl.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>

#include "py/runtime.h"
#include "py/stream.h"
Expand Down
1 change: 1 addition & 0 deletions extmod/re1.5/compilecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
prog->len++;
break;
}
MP_FALLTHROUGH
default:
term = PC;
EMIT(PC++, Char);
Expand Down
1 change: 1 addition & 0 deletions extmod/re1.5/recursiveloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int n
case Char:
if(*sp != *pc++)
return 0;
MP_FALLTHROUGH
case Any:
sp++;
continue;
Expand Down
1 change: 1 addition & 0 deletions extmod/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <stdint.h>
#include <string.h>
#include <assert.h>

#include "py/runtime.h"
#include "py/objstr.h"
Expand Down
1 change: 1 addition & 0 deletions extmod/vfs_fat.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#endif

#include <string.h>
#include <assert.h>
#include "py/runtime.h"
#include "py/mperrno.h"
#include "lib/oofatfs/ff.h"
Expand Down
1 change: 1 addition & 0 deletions extmod/vfs_fat_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#if MICROPY_VFS && MICROPY_VFS_FAT

#include <stdio.h>
#include <assert.h>

#include "py/runtime.h"
#include "py/stream.h"
Expand Down
2 changes: 1 addition & 1 deletion extmod/vfs_lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
enum { LFS_MAKE_ARG_bdev, LFS_MAKE_ARG_readsize, LFS_MAKE_ARG_progsize, LFS_MAKE_ARG_lookahead, LFS_MAKE_ARG_mtime };

static const mp_arg_t lfs_make_allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_readsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
{ MP_QSTR_progsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
{ MP_QSTR_lookahead, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/pyexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* THE SOFTWARE.
*/

#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
Expand Down
2 changes: 1 addition & 1 deletion mpy-cross/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ INC += -I$(TOP)

# compiler settings
CWARN = -Wall -Werror
CWARN += -Wpointer-arith -Wuninitialized
CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith
CFLAGS = $(INC) $(CWARN) -std=gnu99 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables

Expand Down
104 changes: 104 additions & 0 deletions ports/gd32vf103/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
include ../../py/mkenv.mk

# qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h

# include py core make definitions
include $(TOP)/py/py.mk

GIT_SUBMODULES = ports/gd32vf103/gd32vf103inator

CROSS_COMPILE = riscv64-unknown-elf-
OBJDUMP = $(CROSS_COMPILE)objdump

DFU_UTIL = dfu-util
DFU_DEVICE = 1d50:613e

INC += -I.
INC += -I$(TOP)
INC += -I$(BUILD)
INC += -Igd32vf103inator/include
INC += -Igd32vf103inator/std

ARCH = rv32imac
ABI = ilp32
CODEMODEL = medlow

BOOTLOADER = 4*1024
FLASH_SIZE = 128*1024
RAM_SIZE = 32*1024

CORECLOCK = 96000000
HXTAL = 8000000

ARCHFLAGS = -march=$(ARCH) -mabi=$(ABI) -mcmodel=$(CODEMODEL) -fno-pie
WARNINGS = -Wall -Wextra -Wshadow -Wformat=2 -Wformat-truncation=2 -Wno-unused-parameter
DIMENSIONS = -DBOOTLOADER=$(BOOTLOADER) -DFLASH_SIZE=$(FLASH_SIZE) -DRAM_SIZE=$(RAM_SIZE)
CLOCKS = -DHXTAL=$(HXTAL) -DCORECLOCK=$(CORECLOCK)

CFLAGS = $(COPT) -std=c99 $(ARCHFLAGS) $(WARNINGS)
CFLAGS += $(INC) $(DIMENSIONS) $(CLOCKS) -D_LIBC_LIMITS_H_
CFLAGS += -ffreestanding #-ftls-model=local-exec
LDFLAGS = $(COPT) $(ARCHFLAGS) -static -nostdlib -Tgd32vf103inator/gd32vf103.ld
LDFLAGS += -Wl,-O1,--gc-sections,--relax,--build-id=none,-Map=$@.map,--cref

CSUPEROPT = -Os # save some code space

# Tune for Debugging or Optimization
ifeq ($(DEBUG), 1)
COPT = -Os -ggdb
else
COPT = -Os -flto -DNDEBUG
CFLAGS += -fno-common -ffunction-sections -fdata-sections
endif


LIBS = -lgcc

SRC_C = \
main.c \
usbacm.c \
mphalport.c \
modutime.c \
modmachine.c \
pin.c \
gd32vf103inator/lib/rcu.c \
gd32vf103inator/lib/eclic.c \
gd32vf103inator/lib/mtimer.c \
gd32vf103inator/lib/gpio.c \
lib/utils/printf.c \
lib/utils/stdout_helpers.c \
lib/utils/pyexec.c \
lib/mp-readline/readline.c \
lib/libc/string0.c

# List of sources for qstr extraction
SRC_QSTR += modutime.c pin.c modmachine.c

OBJ = $(BUILD)/gd32vf103inator/start.o \
$(PY_O) \
$(patsubst %.c,$(BUILD)/%.o,$(SRC_C))

.PHONY: all dump dfu romdfu

all: $(BUILD)/firmware.bin

$(BUILD)/firmware.elf: $(OBJ)
$(ECHO) "LINK $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
$(Q)$(SIZE) $@

$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
$(ECHO) "OBJCOPY $@"
$(Q)$(OBJCOPY) -O binary $^ $@

dump: $(BUILD)/firmware.elf
$(OBJDUMP) -x -d -j .init -j .text -j .data $< | $(PAGER)

dfu: $(BUILD)/firmware.bin
$(Q)$(DFU_UTIL) -d $(DFU_DEVICE) -D $< -R

romdfu: $(BUILD)/firmware.bin
$(Q)$(DFU_UTIL) -d 28e9:0189 -a 0 --dfuse-address 0x08000000:leave -D $<

include $(TOP)/py/mkrules.mk
47 changes: 47 additions & 0 deletions ports/gd32vf103/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# The minimal port

This port is intended to be a minimal MicroPython port that actually runs.
It can run under Linux (or similar) and on any STM32F4xx MCU (eg the pyboard).

## Building and running Linux version

By default the port will be built for the host machine:

$ make

To run the executable and get a basic working REPL do:

$ make run

## Building for an STM32 MCU

The Makefile has the ability to build for a Cortex-M CPU, and by default
includes some start-up code for an STM32F4xx MCU and also enables a UART
for communication. To build:

$ make CROSS=1

If you previously built the Linux version, you will need to first run
`make clean` to get rid of incompatible object files.

Building will produce the build/firmware.dfu file which can be programmed
to an MCU using:

$ make CROSS=1 deploy

This version of the build will work out-of-the-box on a pyboard (and
anything similar), and will give you a MicroPython REPL on UART1 at 9600
baud. Pin PA13 will also be driven high, and this turns on the red LED on
the pyboard.

## Building without the built-in MicroPython compiler

This minimal port can be built with the built-in MicroPython compiler
disabled. This will reduce the firmware by about 20k on a Thumb2 machine,
and by about 40k on 32-bit x86. Without the compiler the REPL will be
disabled, but pre-compiled scripts can still be executed.

To test out this feature, change the `MICROPY_ENABLE_COMPILER` config
option to "0" in the mpconfigport.h file in this directory. Then
recompile and run the firmware and it will execute the frozentest.py
file.
1 change: 1 addition & 0 deletions ports/gd32vf103/gd32vf103inator
Submodule gd32vf103inator added at e6b138
Loading