You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2023/10/21 14:45:09 UTC
[nuttx] branch master updated: add gd32f470i board support
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 6e94f7432f add gd32f470i board support
6e94f7432f is described below
commit 6e94f7432ff41cd4ea09f74c22f920ae35f457d8
Author: GD32-MCU <ji...@gigadevice.com>
AuthorDate: Sat Oct 21 14:19:44 2023 +0800
add gd32f470i board support
---
arch/arm/include/gd32f4/chip.h | 2 +-
arch/arm/src/gd32f4/Kconfig | 9 +-
arch/arm/src/gd32f4/gd32f4xx_enet.c | 2 +-
arch/arm/src/gd32f4/gd32f4xx_progmem.c | 10 +-
arch/arm/src/gd32f4/gd32f4xx_serial.c | 2 +
arch/arm/src/gd32f4/gd32f4xx_usart.h | 6 +-
boards/Kconfig | 13 +
boards/arm/gd32f4/gd32f470ik-eval/Kconfig | 138 +++++++
.../gd32f470ik-eval/configs/fmclfsnsh/defconfig | 89 +++++
.../gd32f470ik-eval/configs/i2c0testnsh/defconfig | 60 ++++
.../gd32f470ik-eval/configs/netnsh/defconfig | 83 +++++
.../gd32f4/gd32f470ik-eval/configs/nsh/defconfig | 49 +++
boards/arm/gd32f4/gd32f470ik-eval/include/board.h | 394 ++++++++++++++++++++
.../arm/gd32f4/gd32f470ik-eval/scripts/Make.defs | 41 +++
.../arm/gd32f4/gd32f470ik-eval/scripts/gnu-elf.ld | 116 ++++++
.../gd32f4/gd32f470ik-eval/scripts/kernel-space.ld | 97 +++++
.../arm/gd32f4/gd32f470ik-eval/scripts/ld.script | 130 +++++++
.../arm/gd32f4/gd32f470ik-eval/scripts/memory.ld | 85 +++++
.../gd32f4/gd32f470ik-eval/scripts/user-space.ld | 111 ++++++
boards/arm/gd32f4/gd32f470ik-eval/src/Makefile | 64 ++++
.../gd32f4/gd32f470ik-eval/src/gd32f470i_eval.h | 264 ++++++++++++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_appinit.c | 266 ++++++++++++++
.../arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_at24.c | 155 ++++++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_autoleds.c | 177 +++++++++
.../arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_boot.c | 90 +++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_bringup.c | 184 ++++++++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_buttons.c | 190 ++++++++++
.../arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gd25.c | 164 +++++++++
.../arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gpio.c | 397 +++++++++++++++++++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c | 137 +++++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.h | 62 ++++
.../arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_sdio.c | 149 ++++++++
.../arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_spi.c | 283 +++++++++++++++
.../gd32f4/gd32f470ik-eval/src/gd32f4xx_userleds.c | 149 ++++++++
34 files changed, 4157 insertions(+), 11 deletions(-)
diff --git a/arch/arm/include/gd32f4/chip.h b/arch/arm/include/gd32f4/chip.h
index 73111b51e6..68e715e175 100644
--- a/arch/arm/include/gd32f4/chip.h
+++ b/arch/arm/include/gd32f4/chip.h
@@ -35,7 +35,7 @@
* It must be done in arch/arm/src/gd32f4/Kconfig !
*/
-#if defined(CONFIG_ARCH_CHIP_GD32F450IK)
+#if defined(CONFIG_ARCH_CHIP_GD32F450IK) || defined(CONFIG_ARCH_CHIP_GD32F470IK)
# define GD32_NGPIO_PORTS 9 /* GPIOA-I */
# define GD32_NCRC 1 /* CRC calculation unit */
# define GD32_NTRNG 1 /* True random number generator (RNG) */
diff --git a/arch/arm/src/gd32f4/Kconfig b/arch/arm/src/gd32f4/Kconfig
index 20111a6c42..56a5b53697 100644
--- a/arch/arm/src/gd32f4/Kconfig
+++ b/arch/arm/src/gd32f4/Kconfig
@@ -67,6 +67,13 @@ config ARCH_CHIP_GD32F470ZK
---help---
GD32 F4 Cortex M4, 3072 Kb FLASH, 256 Kb SRAM
+config ARCH_CHIP_GD32F470IK
+ bool "GD32F470IK"
+ select GD32F4_GD32F4XX
+ select GD32F4_GD32F470Z_I
+ ---help---
+ GD32 F4 Cortex M4, 3072 Kb FLASH, 256 Kb SRAM
+
endchoice # GD32F4 Chip Seclection
choice
@@ -138,7 +145,7 @@ config GD32F4_GD32F450Z_I
select GD32F4_GD32F450
select GD32F4_HAVE_SPI5
config GD32F4_GD32F470Z_I
- # bool "GD32F470Z or GD32F70I"
+ # bool "GD32F470Z or GD32F470I"
bool
default n
select GD32F4_GD32F470
diff --git a/arch/arm/src/gd32f4/gd32f4xx_enet.c b/arch/arm/src/gd32f4/gd32f4xx_enet.c
index 30b43d19b2..f52082841f 100644
--- a/arch/arm/src/gd32f4/gd32f4xx_enet.c
+++ b/arch/arm/src/gd32f4/gd32f4xx_enet.c
@@ -3356,7 +3356,7 @@ static inline void gd32_enet_gpio_config(struct gd32_enet_mac_s *priv)
*/
gd32_gpio_config(GPIO_CKOUT0);
- gd32_rcu_ckout0_config(BOARD_CFG_CKOUT0_SOURCE, BOARD_CFG_CKOUT0_DIV);
+ gd32_rcu_ckout0_config(BOARD_CFG_CKOUT0_SOURCE, BOARD_CFG_CKOUT0_DIVIDER);
# elif defined(CONFIG_GD32F4_RMII_CKOUT1)
/* Configure CKOUT1 to drive the PHY. Board logic must provide
diff --git a/arch/arm/src/gd32f4/gd32f4xx_progmem.c b/arch/arm/src/gd32f4/gd32f4xx_progmem.c
index 1bd0dcb58e..07f2c8de88 100644
--- a/arch/arm/src/gd32f4/gd32f4xx_progmem.c
+++ b/arch/arm/src/gd32f4/gd32f4xx_progmem.c
@@ -72,12 +72,12 @@
# define FMC_PROGMEM_SECTOR_EADDR (0x0810FFFF)
# elif defined(CONFIG_GD32F4_FLASH_CONFIG_K)
-#if defined(CONFIG_ARCH_CHIP_GD32F450ZK)
+#if defined(CONFIG_GD32F4_GD32F450)
# define FMC_PROGMEM_SECTOR_SIZES {_K(16), _K(16), _K(16), _K(16)}
# define FMC_PROGMEM_SECTOR_NUM (4)
# define FMC_PROGMEM_SECTOR_SADDR (0x08100000)
# define FMC_PROGMEM_SECTOR_EADDR (0x0810FFFF)
-#elif defined(CONFIG_ARCH_CHIP_GD32F470ZK)
+#elif defined(CONFIG_GD32F4_GD32F470)
# define FMC_PROGMEM_SECTOR_SIZES {_K(256), _K(256), _K(256), _K(256)}
# define FMC_PROGMEM_SECTOR_NUM (256)
# define FMC_PROGMEM_SECTOR_SADDR (0x08200000)
@@ -130,7 +130,7 @@ typedef struct
uint32_t sector_end_addr; /* the end address of the sector */
} fmc_sector_info_struct;
-#if !defined(CONFIG_ARCH_CHIP_GD32F470ZK)
+#if !defined(CONFIG_GD32F4_GD32F470)
static const size_t sector_sizes[FMC_PROGMEM_SECTOR_NUM] =
FMC_PROGMEM_SECTOR_SIZES;
#endif
@@ -303,7 +303,7 @@ size_t up_progmem_erasesize(size_t block)
}
else
{
- #ifdef CONFIG_ARCH_CHIP_GD32F470ZK
+ #ifdef CONFIG_GD32F4_GD32F470
return FMC_PROGMEM_PAGESIZE;
#else
return sector_sizes[block];
@@ -442,7 +442,7 @@ ssize_t up_progmem_eraseblock(size_t block)
gd32_fmc_unlock();
gd32_fmc_flag_clear(FMC_STAT_PERR);
-#ifdef CONFIG_ARCH_CHIP_GD32F470ZK
+#ifdef CONFIG_GD32F4_GD32F470
if (gd32_fmc_page_erase(addr))
{
return -EFAULT;
diff --git a/arch/arm/src/gd32f4/gd32f4xx_serial.c b/arch/arm/src/gd32f4/gd32f4xx_serial.c
index 4e3c301090..a5ad8a5cb7 100644
--- a/arch/arm/src/gd32f4/gd32f4xx_serial.c
+++ b/arch/arm/src/gd32f4/gd32f4xx_serial.c
@@ -2105,6 +2105,8 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
{
ie &= ~(USART_CFG_CTL0_INT_RBNEIE | USART_CFG_CTL0_INT_PERRIE |
USART_CFG_CTL2_INT_ERRIE);
+ ie |= ((USART_CFG_CTL0_INT << USART_CFG_SHIFT) |
+ (USART_CFG_CTL2_INT << USART_CFG_SHIFT));
}
/* Then set the new interrupt state */
diff --git a/arch/arm/src/gd32f4/gd32f4xx_usart.h b/arch/arm/src/gd32f4/gd32f4xx_usart.h
index 3fade45d76..eb29c5a1ad 100644
--- a/arch/arm/src/gd32f4/gd32f4xx_usart.h
+++ b/arch/arm/src/gd32f4/gd32f4xx_usart.h
@@ -516,13 +516,13 @@
/* USART interrupt in CTL1 register */
#define USART_CFG_CTL1_INT_SHIFT (1)
-# define USART_CFG_CTL1_INT_LBDIE ((USART_CFG_CTL1_INT << USART_CFG_SHIFT) | (USART_CTL1_LBDIE >> USART_CFG_CTL0_INT_SHIFT))
+# define USART_CFG_CTL1_INT_LBDIE ((USART_CFG_CTL1_INT << USART_CFG_SHIFT) | (USART_CTL1_LBDIE >> USART_CFG_CTL1_INT_SHIFT))
/* USART interrupt in CTL2 register */
#define USART_CFG_CTL2_INT_SHIFT (8)
-# define USART_CFG_CTL2_INT_ERRIE ((USART_CFG_CTL2_INT << USART_CFG_SHIFT) | (USART_CTL2_ERRIE << USART_CFG_CTL0_INT_SHIFT))
-# define USART_CFG_CTL2_INT_CTSIE ((USART_CFG_CTL2_INT << USART_CFG_SHIFT) | (USART_CTL2_CTSIE << USART_CFG_CTL0_INT_SHIFT))
+# define USART_CFG_CTL2_INT_ERRIE ((USART_CFG_CTL2_INT << USART_CFG_SHIFT) | (USART_CTL2_ERRIE << USART_CFG_CTL2_INT_SHIFT))
+# define USART_CFG_CTL2_INT_CTSIE ((USART_CFG_CTL2_INT << USART_CFG_SHIFT) | (USART_CTL2_CTSIE << USART_CFG_CTL2_INT_SHIFT))
/* USART interrupt in CTL3 register */
diff --git a/boards/Kconfig b/boards/Kconfig
index b70fef6e35..12e122259e 100644
--- a/boards/Kconfig
+++ b/boards/Kconfig
@@ -650,6 +650,15 @@ config ARCH_BOARD_GD32F470ZK_EVAL
---help---
GD32 MCU GD32F470ZK-EVAL board based on the GD32F4 GD32F470ZKT6 MCU.
+config ARCH_BOARD_GD32F470IK_EVAL
+ bool "GD32 MCU GD32F470IK"
+ depends on ARCH_CHIP_GD32F470IK
+ select ARCH_HAVE_LEDS
+ select ARCH_HAVE_BUTTONS
+ select ARCH_HAVE_IRQBUTTONS
+ ---help---
+ GD32 MCU GD32F470IK-EVAL board based on the GD32F4 GD32F470IKT6 MCU.
+
config ARCH_BOARD_HIFIVE1_REVB
bool "HiFive1 Rev B board"
depends on ARCH_CHIP_FE310
@@ -3060,6 +3069,7 @@ config ARCH_BOARD
default "freedom-kl26z" if ARCH_BOARD_FREEDOM_KL26Z
default "gd32f450zk-eval" if ARCH_BOARD_GD32F450ZK_EVAL
default "gd32f470zk-eval" if ARCH_BOARD_GD32F470ZK_EVAL
+ default "gd32f470ik-eval" if ARCH_BOARD_GD32F470IK_EVAL
default "hifive1-revb" if ARCH_BOARD_HIFIVE1_REVB
default "hymini-stm32v" if ARCH_BOARD_HYMINI_STM32V
default "imxrt1020-evk" if ARCH_BOARD_IMXRT1020_EVK
@@ -3465,6 +3475,9 @@ endif
if ARCH_BOARD_GD32F470ZK_EVAL
source "boards/arm/gd32f4/gd32f470zk-eval/Kconfig"
endif
+if ARCH_BOARD_GD32F470IK_EVAL
+source "boards/arm/gd32f4/gd32f470ik-eval/Kconfig"
+endif
if ARCH_BOARD_TEENSY_LC
source "boards/arm/kl/teensy-lc/Kconfig"
endif
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/Kconfig b/boards/arm/gd32f4/gd32f470ik-eval/Kconfig
new file mode 100644
index 0000000000..1ebfc70f7a
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/Kconfig
@@ -0,0 +1,138 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+if ARCH_BOARD_GD32F470IK_EVAL
+
+choice
+ prompt "Select Console wiring."
+ default GD32F470IK_EVAL_CONSOLE_BOARD
+ ---help---
+ Select where you will connect the console.
+
+ Eval COM Port:
+
+ BOARD USART Connector:
+
+ Advantage: You have a shield so it is easy.
+
+ Disadvantage: You loose the use of the
+ other functions on PA9, PA10
+
+ GD32F470IK_EVAL
+ USART0 GPIO
+ -- ----- --------- ----
+ RX USART0_RX PA10
+ TX USART0_TX PA9
+ -- ----- --------- ---
+
+config GD32F470IK_EVAL_CONSOLE_BOARD
+ bool "Eval Com Connector"
+ select GD32_USART0
+ select USART0_SERIALDRIVER
+
+config GD32F470IK_EVAL_CONSOLE_VIRTUAL
+ bool "Virtual ComPort"
+ select GD32_USART3
+ select USART3_SERIALDRIVER
+
+config GD32F470IK_EVAL_CONSOLE_NONE
+ bool "No Serial Console"
+
+endchoice # "Select Console wiring"
+
+
+choice
+ prompt "GD32F470I MCU Crystal Selected"
+ default GD32F470I_BOARD_USE_HXTAL
+
+config GD32F470I_BOARD_USE_HXTAL
+ bool "Use Hxtal as clock source"
+ # select GD32F470I_BOARD_HXTAL_VALUE
+
+config GD32F470I_BOARD_USE_IRC16
+ bool "Use IRC16M as clock source"
+
+endchoice # CPU Frequency
+
+config GD32F470I_BOARD_HXTAL_VALUE
+ int "GD32F470I Eval Board Hxtal Value"
+ default 25000000
+ depends on GD32F470I_BOARD_USE_HXTAL
+ ---help---
+ GD32F470I Eval Board Hxtal Value, default is 25MHz.
+
+choice
+ prompt "GD32F470 MCU System Frequency"
+ default GD32F470I_200MHZ
+
+config GD32F470I_240MHZ
+ bool "240 MHz"
+
+config GD32F470I_200MHZ
+ bool "200 MHz"
+
+config GD32F470I_168MHZ
+ bool "168 MHz"
+
+config GD32F470I_120MHZ
+ bool "120 MHz"
+
+endchoice # CPU Frequency
+
+
+config GD32F470IK_EVAL_GD25_BLOCKMOUNT
+ bool "GD25 serial FLASH auto-mount"
+ default n
+ depends on GD32F4_SPI5 && MTD_GD25
+ ---help---
+ Automatically initialize the GD25 SPI FLASH driver when NSH starts.
+
+choice
+ prompt "GD25 SPI FLASH configuration"
+ default GD32F470IK_EVAL_GD25_NXFFS
+ depends on GD32F470IK_EVAL_GD25_BLOCKMOUNT
+
+config GD32F470IK_EVAL_GD25_FTL
+ bool "Create GD25 SPI FLASH block driver"
+ ---help---
+ Create the MTD driver for the GD25 and "wrap" the GD25 as a standard
+ block driver that could then, for example, be mounted using FAT or
+ any other file system. Any file system may be used, but there will
+ be no wear-leveling.
+
+config GD32F470IK_EVAL_GD25_NXFFS
+ bool "Create GD25 serial FLASH NXFFS file system"
+ depends on FS_NXFFS
+ ---help---
+ Create the MTD driver for the GD25 and mount the GD25 device as
+ a wear-leveling, NuttX FLASH file system (NXFFS). The downside of
+ NXFFS is that it can be very slow.
+
+config GD32F470IK_EVAL_GD25_LITTLEFS
+ bool "Create GD25 serial FLASH LFS file system"
+ depends on FS_LITTLEFS
+ ---help---
+ Create the MTD driver for the GD25 and mount the GD25 device as
+ a wear-leveling, LittleFS FLASH file system (LFS).
+
+endchoice # GD25 serial FLASH configuration
+
+config GD32F470IK_EVAL_AT24_TEST
+ bool "I2C0 EEPROM AT2402 write and read test"
+ default n
+ depends on NSH_ARCHINIT && GD32F4_I2C0 && MTD_AT24XX
+ ---help---
+ Automatically initialize and test the AT24 I2C EEPROM driver when
+ NSH starts. After test the I2C0 will be released.
+
+config AT24XX_MTD_BLOCKSIZE
+ int "AT24xx MTD block size"
+ default 8
+ depends on GD32F470IK_EVAL_AT24_TEST
+ ---help---
+ The block size must be an even multiple of the pages.
+ The page size of AT2402 on the board is 8 Byte.
+
+endif # ARCH_BOARD_GD32F470IK_EVAL
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/configs/fmclfsnsh/defconfig b/boards/arm/gd32f4/gd32f470ik-eval/configs/fmclfsnsh/defconfig
new file mode 100644
index 0000000000..ebf287c42b
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/configs/fmclfsnsh/defconfig
@@ -0,0 +1,89 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_FPU is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="gd32f470ik-eval"
+CONFIG_ARCH_BOARD_GD32F470IK_EVAL=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="gd32f4"
+CONFIG_ARCH_CHIP_GD32F470IK=y
+CONFIG_ARCH_CHIP_GD32F4=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_CUSTOMOPT=y
+CONFIG_DEBUG_OPTLEVEL="-O0"
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ETH0_PHY_DP83848C=y
+CONFIG_FS_LITTLEFS=y
+CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_FS_TMPFS=y
+CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+CONFIG_GD32F4_ENETMAC=y
+CONFIG_GD32F4_FLASH_CONFIG_K=y
+CONFIG_GD32F4_FMC=y
+CONFIG_GD32F4_MTD=y
+CONFIG_GD32F4_PHY_SR=16
+CONFIG_GD32F4_PHY_SR_100FD=0x0004
+CONFIG_GD32F4_PHY_SR_100HD=0x0000
+CONFIG_GD32F4_PHY_SR_10FD=0x0006
+CONFIG_GD32F4_PHY_SR_10HD=0x0002
+CONFIG_GD32F4_PHY_SR_ALTCONFIG=y
+CONFIG_GD32F4_PHY_SR_ALTMODE=0x006
+CONFIG_GD32F4_PROGMEM=y
+CONFIG_GD32F4_RMII_EXTCLK=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=2
+CONFIG_NET=y
+CONFIG_NETDB_DNSCLIENT=y
+CONFIG_NETINIT_DRIPADDR=0x0a320301
+CONFIG_NETINIT_IPADDR=0x0a320336
+CONFIG_NETINIT_MACADDR_1=0x20304050
+CONFIG_NETINIT_MACADDR_2=0x6080
+CONFIG_NETINIT_NOMAC=y
+CONFIG_NETUTILS_DISCOVER=y
+CONFIG_NETUTILS_WEBCLIENT=y
+CONFIG_NET_ARP_IPIN=y
+CONFIG_NET_ARP_SEND=y
+CONFIG_NET_BROADCAST=y
+CONFIG_NET_ETH_PKTSIZE=1500
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_SOCKET=y
+CONFIG_NET_IGMP=y
+CONFIG_NET_LOOPBACK=y
+CONFIG_NET_ROUTE=y
+CONFIG_NET_STATISTICS=y
+CONFIG_NET_TCP=y
+CONFIG_NET_UDP=y
+CONFIG_NET_UDP_CHECKSUMS=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_PING=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/configs/i2c0testnsh/defconfig b/boards/arm/gd32f4/gd32f470ik-eval/configs/i2c0testnsh/defconfig
new file mode 100644
index 0000000000..28c81126c0
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/configs/i2c0testnsh/defconfig
@@ -0,0 +1,60 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_FPU is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="gd32f470ik-eval"
+CONFIG_ARCH_BOARD_GD32F470IK_EVAL=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="gd32f4"
+CONFIG_ARCH_CHIP_GD32F470IK=y
+CONFIG_ARCH_CHIP_GD32F4=y
+CONFIG_ARCH_INTERRUPTSTACK=256
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_AT24XX_SIZE=2
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_CUSTOMOPT=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_IRQ=y
+CONFIG_DEBUG_LEDS=y
+CONFIG_DEBUG_OPTLEVEL="-O0"
+CONFIG_DEBUG_SCHED=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_FS_NXFFS=y
+CONFIG_FS_PROCFS=y
+CONFIG_GD32F470IK_EVAL_AT24_TEST=y
+CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+CONFIG_GD32F4_FLASH_CONFIG_K=y
+CONFIG_GD32F4_I2C0=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_I2C_DRIVER=y
+CONFIG_I2C_POLLED=y
+CONFIG_I2C_RESET=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=2
+CONFIG_MTD=y
+CONFIG_MTD_AT24XX=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_NXFFS_PACKTHRESHOLD=8
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/configs/netnsh/defconfig b/boards/arm/gd32f4/gd32f470ik-eval/configs/netnsh/defconfig
new file mode 100644
index 0000000000..60db893247
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/configs/netnsh/defconfig
@@ -0,0 +1,83 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_FPU is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="gd32f470ik-eval"
+CONFIG_ARCH_BOARD_GD32F470IK_EVAL=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="gd32f4"
+CONFIG_ARCH_CHIP_GD32F470IK=y
+CONFIG_ARCH_CHIP_GD32F4=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_CUSTOMOPT=y
+CONFIG_DEBUG_OPTLEVEL="-O0"
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ETH0_PHY_DP83848C=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_FS_TMPFS=y
+CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+CONFIG_GD32F4_ENETMAC=y
+CONFIG_GD32F4_FLASH_CONFIG_K=y
+CONFIG_GD32F4_PHY_SR=16
+CONFIG_GD32F4_PHY_SR_100FD=0x0004
+CONFIG_GD32F4_PHY_SR_100HD=0x0000
+CONFIG_GD32F4_PHY_SR_10FD=0x0006
+CONFIG_GD32F4_PHY_SR_10HD=0x0002
+CONFIG_GD32F4_PHY_SR_ALTCONFIG=y
+CONFIG_GD32F4_PHY_SR_ALTMODE=0x006
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=2
+CONFIG_NET=y
+CONFIG_NETDB_DNSCLIENT=y
+CONFIG_NETINIT_DRIPADDR=0x0a320301
+CONFIG_NETINIT_IPADDR=0x0a320336
+CONFIG_NETINIT_MACADDR_1=0x20304050
+CONFIG_NETINIT_MACADDR_2=0x6080
+CONFIG_NETINIT_NOMAC=y
+CONFIG_NETUTILS_DISCOVER=y
+CONFIG_NETUTILS_WEBCLIENT=y
+CONFIG_NET_ARP_IPIN=y
+CONFIG_NET_ARP_SEND=y
+CONFIG_NET_BROADCAST=y
+CONFIG_NET_ETH_PKTSIZE=1500
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_SOCKET=y
+CONFIG_NET_IGMP=y
+CONFIG_NET_LOOPBACK=y
+CONFIG_NET_ROUTE=y
+CONFIG_NET_STATISTICS=y
+CONFIG_NET_TCP=y
+CONFIG_NET_UDP=y
+CONFIG_NET_UDP_CHECKSUMS=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_PING=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/configs/nsh/defconfig b/boards/arm/gd32f4/gd32f470ik-eval/configs/nsh/defconfig
new file mode 100644
index 0000000000..120e6f5750
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/configs/nsh/defconfig
@@ -0,0 +1,49 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_FPU is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="gd32f470ik-eval"
+CONFIG_ARCH_BOARD_GD32F470IK_EVAL=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="gd32f4"
+CONFIG_ARCH_CHIP_GD32F470IK=y
+CONFIG_ARCH_CHIP_GD32F4=y
+CONFIG_ARCH_INTERRUPTSTACK=256
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_CUSTOMOPT=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_IRQ=y
+CONFIG_DEBUG_LEDS=y
+CONFIG_DEBUG_OPTLEVEL="-O0"
+CONFIG_DEBUG_SCHED=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_FS_PROCFS=y
+CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+CONFIG_GD32F4_FLASH_CONFIG_K=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=2
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/include/board.h b/boards/arm/gd32f4/gd32f470ik-eval/include/board.h
new file mode 100644
index 0000000000..a851271e0c
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/include/board.h
@@ -0,0 +1,394 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/include/board.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_ARM_GD32F470IK_EVAL_INCLUDE_BOARD_H
+#define __BOARDS_ARM_GD32F470IK_EVAL_INCLUDE_BOARD_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <stdint.h>
+#endif
+
+#define GD32_BOARD_SYSCLK_PLL_HXTAL
+
+/* Do not include GD32F4 header files here */
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Clocking *****************************************************************/
+
+/* The GD32F470IK-EVAL board features a single 25MHz crystal.
+ *
+ * This is the default configuration:
+ * System clock source : PLL (HXTAL)
+ * SYSCLK(Hz) : 200000000 Determined by PLL config
+ * HCLK(Hz) : 200000000 (GD32_SYSCLK_FREQUENCY)
+ * AHB Prescaler : 1 (GD32_RCU_CFG0_AHB_PSC)
+ * APB2 Prescaler : 2 (GD32_RCU_CFG0_APB2_PSC)
+ * APB1 Prescaler : 4 (GD32_RCU_CFG0_APB1_PSC)
+ * HXTAL value(Hz) : 25000000 (GD32_BOARD_XTAL)
+ * PLLM : 25 (GD32_PLL_PLLM)
+ * PLLN : 400 (RCU_PLL_PLLN)
+ * PLLP : 2 (GD32_PLL_PLLP)
+ * PLLQ : 7 (GD32_PLL_PLLQ)
+ */
+
+/* IRC16M - 16 MHz RC factory-trimmed
+ * IRC32K - 32 KHz RC
+ * HXTAL - On-board crystal frequency is 25MHz
+ * LXTAL - 32.768 kHz
+ */
+
+#ifndef CONFIG_GD32F470I_BOARD_HXTAL_VALUE
+# define GD32_BOARD_HXTAL 25000000ul
+#else
+# define GD32_BOARD_HXTAL CONFIG_GD32F470I_BOARD_HXTAL_VALUE
+#endif
+
+#define GD32_IRC16M_VALUE 16000000ul
+#define GD32_IRC32K_VALUE 32000u
+#define GD32_HXTAL_VALUE GD32_BOARD_HXTAL
+#define GD32_LXTAL_VALUE 32768u
+
+#if defined(CONFIG_GD32F470I_200MHZ)
+
+/* Main PLL Configuration.
+ *
+ * PLL source is HXTAL
+ * PLL_VCO = (GD32_HXTAL_VALUE / PLLM) * PLLN
+ * = (25,000,000 / 25) * 400
+ * = 400,000,000
+ * SYSCLK = PLL_VCO / PLLP
+ * = 400,000,000 / 2 = 168,000,000
+ * USB, SDIO and RNG Clock
+ * = PLL_VCO / PLLQ
+ * = 48,000,000
+ */
+
+#define GD32_PLL_PLLPSC RCU_PLL_PLLPSC(25)
+#define GD32_PLL_PLLN RCU_PLL_PLLN(400)
+#define GD32_PLL_PLLP RCU_PLL_PLLP(2)
+#define GD32_PLL_PLLQ RCU_PLL_PLLQ(7)
+
+#define GD32_SYSCLK_FREQUENCY 200000000ul
+
+#elif defined(CONFIG_GD32F470I_168MHZ)
+
+/* Main PLL Configuration.
+ *
+ * PLL source is HXTAL
+ * PLL_VCO = (GD32_HXTAL_VALUE / PLLM) * PLLN
+ * = (25,000,000 / 25) * 336
+ * = 336,000,000
+ * SYSCLK = PLL_VCO / PLLP
+ * = 336,000,000 / 2 = 168,000,000
+ * USB, SDIO and RNG Clock
+ * = PLL_VCO / PLLQ
+ * = 48,000,000
+ */
+
+#define GD32_PLL_PLLPSC RCU_PLL_PLLPSC(25)
+#define GD32_PLL_PLLN RCU_PLL_PLLN(336)
+#define GD32_PLL_PLLP RCU_PLL_PLLP(2)
+#define GD32_PLL_PLLQ RCU_PLL_PLLQ(7)
+
+#define GD32_SYSCLK_FREQUENCY 168000000ul
+
+#elif defined(CONFIG_GD32F470I_240MHZ)
+
+/* Main PLL Configuration.
+ *
+ * PLL source is HXTAL
+ * PLL_VCO = (GD32_HXTAL_VALUE / PLLM) * PLLN
+ * = (25,000,000 / 25) * 336
+ * = 336,000,000
+ * SYSCLK = PLL_VCO / PLLP
+ * = 336,000,000 / 2 = 168,000,000
+ * USB, SDIO and RNG Clock
+ * = PLL_VCO / PLLQ
+ * = 48,000,000
+ */
+
+#define GD32_PLL_PLLPSC RCU_PLL_PLLPSC(25)
+#define GD32_PLL_PLLN RCU_PLL_PLLN(480)
+#define GD32_PLL_PLLP RCU_PLL_PLLP(2)
+#define GD32_PLL_PLLQ RCU_PLL_PLLQ(7)
+
+#define GD32_SYSCLK_FREQUENCY 240000000ul
+
+#endif
+
+/* AHB clock (HCLK) is SYSCLK */
+
+#define GD32_RCU_CFG0_AHB_PSC RCU_CFG0_AHBPSC_CKSYS_DIV1 /* HCLK = SYSCLK / 1 */
+#define GD32_HCLK_FREQUENCY GD32_SYSCLK_FREQUENCY
+
+/* APB2 clock (PCLK2) is HCLK/2 */
+
+#define GD32_RCU_CFG0_APB2_PSC RCU_CFG0_APB2PSC_CKAHB_DIV2 /* PCLK2 = HCLK / 2 */
+#define GD32_PCLK2_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+
+/* APB1 clock (PCLK1) is HCLK/4 */
+
+#define GD32_RCU_CFG0_APB1_PSC RCU_CFG0_APB1PSC_CKAHB_DIV4 /* PCLK1 = HCLK / 4 */
+#define GD32_PCLK1_FREQUENCY (GD32_HCLK_FREQUENCY / 4)
+
+/* Timers driven from APB1 will be twice PCLK1 */
+
+#define GD32_APB1_TIMER2_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER3_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER4_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER5_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER6_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER7_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER12_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER13_CLKIN (2*GD32_PCLK1_FREQUENCY)
+#define GD32_APB1_TIMER14_CLKIN (2*GD32_PCLK1_FREQUENCY)
+
+/* Timers driven from APB2 will be twice PCLK2 */
+
+#define GD32_APB2_TIMER1_CLKIN (2*GD32_PCLK2_FREQUENCY)
+#define GD32_APB2_TIMER8_CLKIN (2*GD32_PCLK2_FREQUENCY)
+#define GD32_APB2_TIMER9_CLKIN (2*GD32_PCLK2_FREQUENCY)
+#define GD32_APB2_TIMER10_CLKIN (2*GD32_PCLK2_FREQUENCY)
+#define GD32_APB2_TIMER11_CLKIN (2*GD32_PCLK2_FREQUENCY)
+
+/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
+ * otherwise frequency is 2xAPBx.
+ * Note: TIMER1,8 are on APB2, others on APB1
+ */
+
+#define BOARD_TIMER1_FREQUENCY GD32_HCLK_FREQUENCY
+#define BOARD_TIMER2_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+#define BOARD_TIMER3_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+#define BOARD_TIMER4_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+#define BOARD_TIMER5_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+#define BOARD_TIMER6_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+#define BOARD_TIMER7_FREQUENCY (GD32_HCLK_FREQUENCY/2)
+#define BOARD_TIMER8_FREQUENCY GD32_HCLK_FREQUENCY
+
+/* LED definitions **********************************************************/
+
+/* The GD32F470IK_EVAL board has board has three LEDs. The LED1, LED2 and
+ * LED3 are controlled by GPIO. LED1 is connected to PD4, LED2 is connected
+ * to PD5, LED3 is connected to PG3
+ *
+ * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs
+ * in any way.
+ * The following definitions are used to access individual LEDs.
+ */
+
+/* LED index values */
+
+typedef enum
+{
+ BOARD_LED1 = 0,
+ BOARD_LED2 = 1,
+ BOARD_LED3 = 2,
+ BOARD_LEDS
+} led_typedef_enum;
+
+/* LED bits */
+
+#define BOARD_LED1_BIT (1 << BOARD_LED1)
+#define BOARD_LED2_BIT (1 << BOARD_LED2)
+#define BOARD_LED3_BIT (1 << BOARD_LED3)
+
+/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in
+ * include/board.h and src/gd32f4xx_autoleds.c. The LEDs are used to encode
+ * OS-related events as follows:
+ *
+ *
+ * SYMBOL Meaning LED state
+ * LED1 LED2 LED3
+ * ---------------------- -------------------------- ------ ------ ---
+ */
+
+#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */
+#define LED_HEAPALLOCATE 1 /* Heap has been allocated ON OFF OFF */
+#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */
+#define LED_STACKCREATED 3 /* Idle stack created OFF OFF ON */
+#define LED_INIRQ 4 /* In an interrupt ON ON OFF */
+#define LED_SIGNAL 5 /* In a signal handler ON OFF ON */
+#define LED_ASSERTION 6 /* An assertion failed OFF ON ON */
+#define LED_PANIC 7 /* The system has crashed FLASH ON ON */
+#define LED_IDLE 8 /* MCU is is sleep mode OFF FLASH OFF */
+
+/* Button definitions *******************************************************/
+
+/* The GD32F470I Eval supports three user buttons: Wakeup, Tamper and
+ * User key, they are connected to GPIO PA0, PC13, PB14.
+ * A low value will be sensed when the button is depressed.
+ */
+
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+ BUTTON_TAMPER = 1,
+ BUTTON_USER = 2,
+ NUM_BUTTONS
+} key_typedef_enum;
+
+#define BUTTON_WAKEUP_BIT (1 << BUTTON_WAKEUP)
+#define BUTTON_TAMPER_BIT (1 << BUTTON_TAMPER)
+#define BUTTON_USER_BIT (1 << BUTTON_USER)
+
+/* Alternate function pin selections ****************************************/
+
+#if defined(CONFIG_GD32F470IK_EVAL_CONSOLE_BOARD)
+
+/* USART0:
+ *
+ * These configurations assume that you are using a standard RS-232
+ * shield with the serial interface with RX on PA10 and TX on PA10:
+ *
+ * -------- ---------------
+ * GD32F470IK-EVAL
+ * -- ----- --------- -----
+ * RX USART0_RX PA10
+ * TX USART0_TX PA9
+ * -- ----- --------- -----
+ */
+
+# define GPIO_USART0_RX GPIO_USART0_RX_1
+# define GPIO_USART0_TX GPIO_USART0_TX_1
+
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART0_IFLOWCONTROL)
+# define GPIO_USART0_RTS GPIO_USART0_RTS_1
+# endif
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART0_OFLOWCONTROL)
+# define GPIO_USART0_CTS GPIO_USART0_CTS_1
+# endif
+#endif
+
+#if CONFIG_GD32F4_USART0_TXDMA
+# define DMA_CHANNEL_USART0_TX DMA_REQ_USART0_TX
+#endif
+#if CONFIG_GD32F4_USART0_RXDMA
+# define DMA_CHANNEL_USART0_RX DMA_REQ_USART0_RX_1
+#endif
+
+#if defined(CONFIG_GD32F4_USART_RXDMA) || defined(CONFIG_GD32F4_USART_TXDMA)
+# define USART_DMA_INTEN (DMA_CHXCTL_SDEIE | DMA_CHXCTL_TAEIE | DMA_CHXCTL_FTFIE)
+#endif
+
+/* USART3:
+ * Use USART3 and the USB virtual COM port
+ */
+
+#if defined(GD32F470IK_EVAL_CONSOLE_VIRTUAL)
+# define GPIO_USART3_RX GPIO_USART3_RX_3
+# define GPIO_USART3_TX GPIO_USART3_TX_3
+#endif
+
+/* I2C0 gpios:
+ *
+ * PB6 I2C0_SCL
+ * PB7 I2C0_SDA
+ *
+ */
+
+#define GPIO_I2C0_SCL GPIO_I2C0_SCL_1
+#define GPIO_I2C0_SDA GPIO_I2C0_SDA_1
+
+/* SPI flash
+ *
+ * PG12 SPI5_MISO
+ * PG14 SPI5_MOSI
+ * PG13 SPI5_SCK
+ *
+ * PG9 SPI5_CS
+ *
+ */
+
+#define GPIO_SPI5_CSPIN (GPIO_CFG_PORT_G | GPIO_PIN9_OUTPUT)
+
+#define GPIO_SPI5_MISO_PIN ((GPIO_SPI5_MISO & ~GPIO_CFG_SPEED_MASK) | GPIO_CFG_SPEED_25MHZ)
+#define GPIO_SPI5_MOSI_PIN ((GPIO_SPI5_MOSI & ~GPIO_CFG_SPEED_MASK) | GPIO_CFG_SPEED_25MHZ)
+#define GPIO_SPI5_SCK_PIN ((GPIO_SPI5_SCK & ~GPIO_CFG_SPEED_MASK) | GPIO_CFG_SPEED_25MHZ)
+
+#define GPIO_SPI5_IO2_PIN ((GPIO_SPI5_IO2 & ~GPIO_CFG_SPEED_MASK) | GPIO_CFG_SPEED_25MHZ)
+#define GPIO_SPI5_IO3_PIN ((GPIO_SPI5_IO3 & ~GPIO_CFG_SPEED_MASK) | GPIO_CFG_SPEED_25MHZ)
+
+/* The GD32 F4 connects to a DP83848 PHY using these pins:
+ *
+ * GD32F470I Eval BOARD DP83848
+ * GPIO SIGNAL PIN NAME
+ * -------- ------------ -------------
+ * PG11 RMII_TX_EN TXEN
+ * PG13 RMII_TXD0 TXD0
+ * PG14 RMII_TXD1 TXD1
+ * PC4 RMII_RXD0 RXD_0/PHYAD1
+ * PC5 RMII_RXD1 RXD_1/PHYAD2
+ * PA7 RMII_CRS_DV RX_DV/MII_MODE
+ * PC1 RMII_MDC MDC
+ * PA2 RMII_MDIO MDIO
+ * NRST NRST RESET_N
+ * PA1 RMII_REF_CLK X1
+ * PB15 RMII_INT PWR_DOWN/INT
+ *
+ * The PHY address is 1.
+ */
+
+#define GPIO_ENET_RMII_TX_EN GPIO_ENET_RMII_TX_EN_2
+#define GPIO_ENET_RMII_TXD0 GPIO_ENET_RMII_TXD0_2
+#define GPIO_ENET_RMII_TXD1 GPIO_ENET_RMII_TXD1_2
+
+#ifdef CONFIG_GD32F4_ENET_PTP
+ /* Enable pulse-per-second (PPS) output signal */
+
+# define GPIO_ENET_PPS_OUT GPIO_ENET_PPS_OUT_1
+#endif
+
+#ifdef CONFIG_GD32F4_RMII_CKOUT0
+# define BOARD_CFG_CKOUT0_SOURCE RCU_CFG0_CKOUT0SEL_PLLP
+# define BOARD_CFG_CKOUT0_DIVIDER RCU_CFG0_CKOUT0_DIV4
+#endif
+
+/* SDIO gpios
+ *
+ * PD2 SDIO_CMD
+ * PC12 SDIO_CLK
+ * PC8 SDIO_DAT0
+ * PC9 SDIO_DAT1
+ * PC10 SDIO_DAT2
+ * PC11 SDIO_DAT3
+ *
+ */
+
+#define GPIO_SDIO_CMD_PIN GPIO_SDIO_CMD_2
+#define GPIO_SDIO_CLK_PIN GPIO_SDIO_CK_2
+#define GPIO_SDIO_DAT0_PIN GPIO_SDIO_D0_2
+#define GPIO_SDIO_DAT1_PIN GPIO_SDIO_D1_3
+#define GPIO_SDIO_DAT2_PIN GPIO_SDIO_D2_3
+#define GPIO_SDIO_DAT3_PIN GPIO_SDIO_D3
+
+#ifdef CONFIG_GD32F4_SDIO_DMA
+# define SDIO_DMA_INTEN (DMA_CHXCTL_SDEIE | DMA_CHXCTL_TAEIE | DMA_CHXCTL_FTFIE)
+#endif
+
+#endif /* __BOARDS_ARM_GD32F470IK_EVAL_INCLUDE_BOARD_H */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/scripts/Make.defs b/boards/arm/gd32f4/gd32f470ik-eval/scripts/Make.defs
new file mode 100644
index 0000000000..068515ee40
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/scripts/Make.defs
@@ -0,0 +1,41 @@
+############################################################################
+# boards/arm/gd32f4/gd32f470zk-eval/scripts/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(TOPDIR)/.config
+include $(TOPDIR)/tools/Config.mk
+include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs
+
+LDSCRIPT = ld.script
+ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
+
+ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
+
+CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
+AFLAGS := $(CFLAGS) -D__ASSEMBLY__
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+EXEEXT = .elf
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/scripts/gnu-elf.ld b/boards/arm/gd32f4/gd32f470ik-eval/scripts/gnu-elf.ld
new file mode 100644
index 0000000000..62e05a822e
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/scripts/gnu-elf.ld
@@ -0,0 +1,116 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/scripts/gnu-elf.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+SECTIONS
+{
+ .text 0x00000000 :
+ {
+ _stext = . ;
+ *(.text)
+ *(.text.*)
+ *(.gnu.warning)
+ *(.stub)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.jcr)
+
+ /* C++ support: The .init and .fini sections contain specific logic
+ * to manage static constructors and destructors.
+ */
+
+ *(.gnu.linkonce.t.*)
+ *(.init) /* Old ABI */
+ *(.fini) /* Old ABI */
+ _etext = . ;
+ }
+
+ .rodata :
+ {
+ _srodata = . ;
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.*)
+ *(.gnu.linkonce.r*)
+ _erodata = . ;
+ }
+
+ .data :
+ {
+ _sdata = . ;
+ *(.data)
+ *(.data1)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ . = ALIGN(4);
+ _edata = . ;
+ }
+
+ /* C++ support. For each global and static local C++ object,
+ * GCC creates a small subroutine to construct the object. Pointers
+ * to these routines (not the routines themselves) are stored as
+ * simple, linear arrays in the .ctors section of the object file.
+ * Similarly, pointers to global/static destructor routines are
+ * stored in .dtors.
+ */
+
+ .ctors :
+ {
+ _sctors = . ;
+ *(.ctors) /* Old ABI: Unallocated */
+ *(.init_array) /* New ABI: Allocated */
+ _edtors = . ;
+ }
+
+ .dtors :
+ {
+ _sdtors = . ;
+ *(.dtors) /* Old ABI: Unallocated */
+ *(.fini_array) /* New ABI: Allocated */
+ _edtors = . ;
+ }
+
+ .bss :
+ {
+ _sbss = . ;
+ *(.bss)
+ *(.bss.*)
+ *(.sbss)
+ *(.sbss.*)
+ *(.gnu.linkonce.b*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = . ;
+ }
+
+ /* Stabs debugging sections. */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/scripts/kernel-space.ld b/boards/arm/gd32f4/gd32f470ik-eval/scripts/kernel-space.ld
new file mode 100644
index 0000000000..0050c28e80
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/scripts/kernel-space.ld
@@ -0,0 +1,97 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/scripts/kernel-space.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* NOTE: This depends on the memory.ld script having been included prior to
+ * this script.
+ */
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+ENTRY(_stext)
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > kflash
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > kflash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > kflash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > kflash
+
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ . = ALIGN(4);
+ _edata = ABSOLUTE(.);
+ } > ksram AT > kflash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > ksram
+
+ /* Stabs debugging sections */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/scripts/ld.script b/boards/arm/gd32f4/gd32f470ik-eval/scripts/ld.script
new file mode 100644
index 0000000000..b97d056380
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/scripts/ld.script
@@ -0,0 +1,130 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/scripts/ld.script
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* The GD32F470ZKT6 has 3072Kb of FLASH beginning at address 0x0800:0000 and
+ * 256Kb of SRAM. SRAM is split up into four blocks:
+ *
+ * 1) 112Kb of SRAM beginning at address 0x2000:0000
+ * 2) 16Kb of SRAM beginning at address 0x2001:c000
+ * 3) 64Kb of SRAM beginning at address 0x2002:0000
+ * 4) 64Kb of TCMSRAM beginning at address 0x1000:0000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address
+ * range.
+ */
+
+MEMORY
+{
+ flash (rx) : ORIGIN = 0x08000000, LENGTH = 3072K
+ sram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+ENTRY(_stext)
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > flash
+
+ .init_section : ALIGN(4) {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > flash
+
+ .ARM.extab : ALIGN(4) {
+ *(.ARM.extab*)
+ } > flash
+
+ .ARM.exidx : ALIGN(4) {
+ __exidx_start = ABSOLUTE(.);
+ *(.ARM.exidx*)
+ __exidx_end = ABSOLUTE(.);
+ } > flash
+
+ .tdata : {
+ _stdata = ABSOLUTE(.);
+ *(.tdata .tdata.* .gnu.linkonce.td.*);
+ _etdata = ABSOLUTE(.);
+ } > flash
+
+ .tbss : {
+ _stbss = ABSOLUTE(.);
+ *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+ _etbss = ABSOLUTE(.);
+ } > flash
+
+ _eronly = ABSOLUTE(.);
+
+ /* The RAM vector table (if present) should lie at the beginning of SRAM */
+
+ .ram_vectors : {
+ *(.ram_vectors)
+ } > sram
+
+ .data : ALIGN(4) {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ . = ALIGN(4);
+ _edata = ABSOLUTE(.);
+ } > sram AT > flash
+
+ .bss : ALIGN(4) {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > sram
+
+ /* Stabs debugging sections. */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/scripts/memory.ld b/boards/arm/gd32f4/gd32f470ik-eval/scripts/memory.ld
new file mode 100644
index 0000000000..756f9879ae
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/scripts/memory.ld
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470zk-eval/scripts/memory.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* The GD32F470ZKT6 has 3072Kb of FLASH beginning at address 0x0800:0000 and
+ * 256Kb of SRAM. SRAM is split up into four blocks:
+ *
+ * 1) 112KB of SRAM beginning at address 0x2000:0000
+ * 2) 16KB of SRAM beginning at address 0x2001:c000
+ * 3) 64KB of SRAM beginning at address 0x2002:0000
+ * 4) 64KB of TCMSRAM beginning at address 0x1000:0000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address range.
+ *
+ * For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
+ * FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
+ * should fit into 64KB and, of course, can be optimized as needed. Allowing the
+ * additional does permit addition debug instrumentation to be added to the
+ * kernel space without overflowing the partition.
+ *
+ * Alignment of the user space FLASH partition is also a critical factor:
+ * The user space FLASH partition will be spanned with a single region of
+ * size 2**n bytes. The alignment of the user-space region must be the same.
+ * As a consequence, as the user-space increases in size, the alignment
+ * requirement also increases.
+ *
+ * This alignment requirement means that the largest user space FLASH region
+ * you can have will be 512KB at it would have to be positioned at
+ * 0x08800000. If you change this address, don't forget to change the
+ * CONFIG_NUTTX_USERSPACE configuration setting to match and to modify
+ * the check in kernel/userspace.c.
+ *
+ * For the same reasons, the maximum size of the SRAM mapping is limited to
+ * 4KB. Both of these alignment limitations could be reduced by using
+ * multiple regions to map the FLASH/SDRAM range or perhaps with some
+ * clever use of subregions.
+ *
+ * A detailed memory map for the 112KB SRAM region is as follows:
+ *
+ * 0x20000 0000: Kernel .data region. Typical size: 0.1KB
+ * ------- ---- Kernel .bss region. Typical size: 1.8KB
+ * 0x20000 0800: Kernel IDLE thread stack (approximate). Size is
+ * determined by CONFIG_IDLETHREAD_STACKSIZE and
+ * adjustments for alignment. Typical is 1KB.
+ * ------- ---- Padded to 4KB
+ * 0x20000 1000: User .data region. Size is variable.
+ * ------- ---- User .bss region Size is variable.
+ * 0x20000 2000: Beginning of kernel heap. Size determined by
+ * CONFIG_MM_KERNEL_HEAPSIZE.
+ * ------- ---- Beginning of user heap. Can vary with other settings.
+ * 0x20001 c000: End+1 of CPU RAM
+ */
+
+MEMORY
+{
+ /* 1024Kb FLASH */
+
+ kflash (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+ uflash (rx) : ORIGIN = 0x08020000, LENGTH = 128K
+ xflash (rx) : ORIGIN = 0x08040000, LENGTH = 768K
+
+ /* 112Kb of contiguous SRAM */
+
+ ksram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
+ usram (rwx) : ORIGIN = 0x20001000, LENGTH = 4K
+ xsram (rwx) : ORIGIN = 0x20002000, LENGTH = 104K
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/scripts/user-space.ld b/boards/arm/gd32f4/gd32f470ik-eval/scripts/user-space.ld
new file mode 100644
index 0000000000..0eea6e3323
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/scripts/user-space.ld
@@ -0,0 +1,111 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470zk-eval/scripts/user-space.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* NOTE: This depends on the memory.ld script having been included prior to
+ * this script.
+ */
+
+/* Make sure that the critical memory management functions are in user-space.
+ * the user heap memory manager will reside in user-space but be usable both
+ * by kernel- and user-space code
+ */
+
+EXTERN(umm_initialize)
+EXTERN(umm_addregion)
+
+EXTERN(malloc)
+EXTERN(realloc)
+EXTERN(zalloc)
+EXTERN(free)
+
+OUTPUT_ARCH(arm)
+SECTIONS
+{
+ .userspace : {
+ *(.userspace)
+ } > uflash
+
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > uflash
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > uflash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > uflash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > uflash
+
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ . = ALIGN(4);
+ _edata = ABSOLUTE(.);
+ } > usram AT > uflash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > usram
+
+ /* Stabs debugging sections */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/Makefile b/boards/arm/gd32f4/gd32f470ik-eval/src/Makefile
new file mode 100644
index 0000000000..0d28f25545
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/Makefile
@@ -0,0 +1,64 @@
+############################################################################
+# boards/arm/gd32f4/gd32f470zk-eval/src/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(TOPDIR)/Make.defs
+
+CSRCS = gd32f4xx_boot.c
+
+ifeq ($(CONFIG_BOARDCTL),y)
+CSRCS += gd32f4xx_appinit.c
+endif
+# ifeq ($(CONFIG_BOARDCTL),y)
+# CSRCS += gd32f4xx_appinit.c gd32f4xx_bringup.c
+# else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y)
+# CSRCS += gd32f4xx_bringup.c
+# endif
+
+ifeq ($(CONFIG_ARCH_LEDS),y)
+CSRCS += gd32f4xx_autoleds.c
+else
+CSRCS += gd32f4xx_userleds.c
+endif
+
+ifeq ($(CONFIG_DEV_GPIO),y)
+CSRCS += gd32f4xx_gpio.c
+endif
+
+ifeq ($(CONFIG_ARCH_BUTTONS),y)
+CSRCS += gd32f4xx_buttons.c
+endif
+
+ifeq ($(CONFIG_SPI),y)
+CSRCS += gd32f4xx_spi.c
+endif
+
+ifeq ($(CONFIG_MMCSD),y)
+CSRCS += gd32f4xx_sdio.c
+endif
+
+ifeq ($(CONFIG_MTD_GD25),y)
+CSRCS += gd32f4xx_gd25.c
+endif
+
+ifeq ($(CONFIG_MTD_AT24XX), y)
+CSRCS += gd32f4xx_at24.c
+endif
+
+include $(TOPDIR)/boards/Board.mk
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f470i_eval.h b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f470i_eval.h
new file mode 100644
index 0000000000..b6cd49c957
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f470i_eval.h
@@ -0,0 +1,264 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f470i_eval.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_ARM_GD32F4_GD32F470IK_EVAL_SRC_GD32F470I_EVAL_H
+#define __BOARDS_ARM_GD32F4_GD32F470IK_EVAL_SRC_GD32F470I_EVAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* procfs File System */
+
+#ifdef CONFIG_FS_PROCFS
+# ifdef CONFIG_NSH_PROC_MOUNTPOINT
+# define GD32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
+# else
+# define GD32_PROCFS_MOUNTPOINT "/proc"
+# endif
+#endif
+
+#ifdef CONFIG_FS_NXFFS
+# ifndef CONFIG_GD32F4_NXFFS_MOUNTPT
+# define CONFIG_GD32F4_NXFFS_MOUNTPT "/mnt/gd32nxffs"
+# endif
+#endif
+
+/* GD32F470IK GPIO Pin Definitions ******************************************/
+
+/* LED
+ *
+ * The GD32F470IK-EVAL board has three LEDs, LED1, LED2 and LED3, that can be
+ * controlled by software.
+ * The following definitions assume the default Solder Bridges are installed.
+ */
+
+#define GPIO_LED1 (GPIO_CFG_PORT_E | GPIO_CFG_OUTPUT_RESET | GPIO_PIN2_OUTPUT)
+#define GPIO_LED2 (GPIO_CFG_PORT_E | GPIO_CFG_OUTPUT_RESET | GPIO_PIN3_OUTPUT)
+#define GPIO_LED3 (GPIO_CFG_PORT_F | GPIO_CFG_OUTPUT_RESET | GPIO_PIN10_OUTPUT)
+
+#define LED1 GPIO_LED1
+#define LED2 GPIO_LED2
+#define LED3 GPIO_LED3
+
+#define LED_DRIVER_PATH "/dev/userleds"
+
+/* BUTTONS
+ *
+ * The GD32F470I Eval board has User, Tamper, and Wakeup key, the are
+ * connected to GPIO PB14, PC13 and PA0.
+ * A low value will be sensed when the button is depressed.
+ *
+ * Note:
+ * That the EXTI is included in the definition to enable
+ * an interrupt on this IO.
+ */
+
+#define GPIO_BTN_USER (GPIO_CFG_PORT_B | GPIO_CFG_EXTI | GPIO_PIN14_INPUT)
+#define GPIO_BTN_TAMPER (GPIO_CFG_PORT_C | GPIO_CFG_EXTI | GPIO_PIN13_INPUT)
+#define GPIO_BTN_WAKEUP (GPIO_CFG_PORT_A | GPIO_CFG_EXTI | GPIO_PIN0_INPUT)
+
+/* SPI Flash ****************************************************************/
+
+/* SPI FLASH (GD25Q40)
+ *
+ * PG12 SPI5_MISO
+ * PG14 SPI5_MOSI
+ * PG13 SPI5_SCK
+ *
+ * PI8 SPI5_CS
+ */
+
+#define GPIO_SPI5_CS (GPIO_CFG_PORT_I | GPIO_PIN8_OUTPUT)
+#define SPI_FLASH_CSNUM 5
+
+#define HAVE_GD25 1
+
+#if !defined(CONFIG_MTD_GD25) || !defined(CONFIG_GD32F4_SPI5)
+# undef HAVE_GD25
+#endif
+
+/* Can't support AT24 features if mountpoints are disabled or if we were not
+ * asked to mount the AT25 part
+ */
+
+#if defined(CONFIG_DISABLE_MOUNTPOINT) || \
+ !defined(CONFIG_GD32F470IK_EVAL_GD25_BLOCKMOUNT)
+# undef HAVE_GD25
+#endif
+
+#define HAVE_AT24 1
+
+/* AT24 Serial EEPROM
+ *
+ * A AT24C02C Serial EEPPROM was used for tested I2C0.
+ */
+
+#define AT24_BUS 0
+#define AT24_MINOR 0
+
+#if !defined(CONFIG_MTD_AT24XX) || !defined(CONFIG_GD32F4_I2C0)
+# undef HAVE_AT24
+#endif
+
+/* Can't support AT24 features if mountpoints are disabled or if we were not
+ * asked to mount the AT25 part
+ */
+
+#ifndef CONFIG_GD32F470IK_EVAL_AT24_TEST
+# undef HAVE_AT24
+#endif
+
+/* GPIO pins used by the GPIO Subsystem */
+
+#define BOARD_NGPIOIN 1 /* Amount of GPIO Input pins */
+#define BOARD_NGPIOOUT 1 /* Amount of GPIO Output pins */
+#define BOARD_NGPIOINT 1 /* Amount of GPIO Input w/ Interruption pins */
+
+#define GPIO_IN1 (GPIO_CFG_MODE_INPUT | GPIO_CFG_PUPD_NONE | GPIO_CFG_PORT_B | GPIO_CFG_PIN_0)
+#define GPIO_OUT1 (GPIO_CFG_MODE_OUTPUT | GPIO_CFG_OUTPUT_SET | GPIO_CFG_SPEED_50MHZ | \
+ GPIO_CFG_PORT_B | GPIO_CFG_PIN_1)
+#define GPIO_INT1 (GPIO_CFG_MODE_INPUT | GPIO_CFG_PUPD_NONE | GPIO_CFG_PORT_B | GPIO_CFG_PIN_2)
+
+/* Can't support MMC/SD features if mountpoints are disabled or if SDIO
+ * support is not enabled.
+ */
+
+#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_GD32_SDIO)
+# undef HAVE_SDIO
+#endif
+
+#define SDIO_MINOR 0 /* Any minor number, default 0 */
+#define SDIO_SLOTNO 0 /* Only one slot */
+
+#ifdef HAVE_SDIO
+# if !defined(CONFIG_NSH_MMCSDSLOTNO)
+# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO
+# elif CONFIG_NSH_MMCSDSLOTNO != 0
+# warning "Only one MMC/SD slot, slot 0"
+# undef CONFIG_NSH_MMCSDSLOTNO
+# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO
+# endif
+
+# if defined(CONFIG_NSH_MMCSDMINOR)
+# define SDIO_MINOR CONFIG_NSH_MMCSDMINOR
+# else
+# define SDIO_MINOR 0
+# endif
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Name: gd32_spidev_initialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins for the GD32F470I
+ * Eval board.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_SPI)
+void gd32_spidev_initialize(void);
+#endif
+
+/****************************************************************************
+ * Name: gd32_gd25_automount
+ *
+ * Description:
+ * Initialize, configure, and mount the GD25 SPI FLASH. The FLASH will
+ * be mounted at /dev/gd25.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_GD25
+int gd32_gd25_automount(int minor);
+#endif
+
+/****************************************************************************
+ * Name: gd32_at24_wr_test
+ *
+ * Description:
+ * Write and read the AT24 serial EEPROM test.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_AT24
+int gd32_at24_wr_test(int minor);
+#endif
+
+/****************************************************************************
+ * Name: gd32_gpio_initialize
+ *
+ * Description:
+ * Initialize GPIO drivers for use with /apps/examples/gpio
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_GPIO
+int gd32_gpio_initialize(void);
+#endif
+
+/****************************************************************************
+ * Name: gd32_dma_alloc_init
+ *
+ * Description:
+ * Called to create a FAT DMA allocator
+ *
+ * Returned Value:
+ * 0 on success or -ENOMEM
+ *
+ ****************************************************************************/
+
+void gd32_dma_alloc_init(void);
+
+#if defined (CONFIG_FAT_DMAMEMORY)
+int gd32_dma_alloc_init(void);
+#endif
+
+/****************************************************************************
+ * Name: gd32_sdio_initialize
+ *
+ * Description:
+ * Called at application startup time to initialize the SCMMC
+ * functionality.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_MMCSD
+int gd32_sdio_initialize(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __BOARDS_ARM_GD32F4_GD32F470IK_EVAL_SRC_GD32F470I_EVAL_H */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_appinit.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_appinit.c
new file mode 100644
index 0000000000..bc3f216c4c
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_appinit.c
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_appinit.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <debug.h>
+#include <syslog.h>
+
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/nxffs.h>
+#include <nuttx/leds/userled.h>
+#include <nuttx/fs/nxffs.h>
+
+#ifdef CONFIG_INPUT_BUTTONS
+# include <nuttx/input/buttons.h>
+#endif
+
+#ifdef CONFIG_GD32F4_ROMFS
+#include "gd32f4xx_romfs.h"
+#endif
+
+#include "gd32f470i_eval.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_app_initialize
+ *
+ * Description:
+ * Perform application specific initialization. This function is never
+ * called directly from application code, but only indirectly via the
+ * (non-standard) boardctl() interface using the command BOARDIOC_INIT.
+ *
+ * Input Parameters:
+ * arg - The boardctl() argument is passed to the board_app_initialize()
+ * implementation without modification. The argument has no
+ * meaning to NuttX; the meaning of the argument is a contract
+ * between the board-specific initialization logic and the
+ * matching application logic. The value could be such things as a
+ * mode enumeration value, a set of DIP switch switch settings, a
+ * pointer to configuration data read from a file or serial FLASH,
+ * or whatever you would like to do with it. Every implementation
+ * should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int board_app_initialize(uintptr_t arg)
+{
+ int ret;
+ static bool initialized = false;
+
+ /* Have we already initialized? */
+
+ if (!initialized)
+ {
+#ifdef CONFIG_FS_PROCFS
+ /* Mount the procfs file system */
+
+ ret = nx_mount(NULL, GD32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to mount procfs at %s: %d\n",
+ GD32_PROCFS_MOUNTPOINT, ret);
+ }
+#endif
+
+#ifdef CONFIG_GD32F4_ROMFS
+ /* Mount the romfs partition */
+
+ ret = gd32_romfs_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to mount romfs at %s: %d\n",
+ CONFIG_GD32F4_ROMFS_MOUNTPOINT, ret);
+ }
+#endif
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+
+# ifdef CONFIG_GD32F4_PROGMEM
+
+ /* Create an instance of the GD32F4 FLASH program memory
+ * device driver
+ */
+
+ struct mtd_dev_s *mtd = progmem_initialize();
+ if (!mtd)
+ {
+ syslog(LOG_ERR, "ERROR: progmem_initialize failed\n");
+ }
+
+# if defined(CONFIG_FS_NXFFS)
+ /* Initialize to provide NXFFS on the MTD interface */
+
+ ret = nxffs_initialize(mtd);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: NXFFS initialization failed: %d\n",
+ ret);
+ }
+
+ /* Mount the file system */
+
+ ret = nx_mount(NULL, CONFIG_GD32F4_NXFFS_MOUNTPT, "nxffs", 0, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to mount the NXFFS volume: %d\n",
+ ret);
+ }
+# elif defined(CONFIG_FS_LITTLEFS)
+ /* Initialize to provide LittleFS on the MTD interface */
+
+ ret = register_mtddriver("/dev/fmc", mtd, 0755, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
+ return ret;
+ }
+
+ /* Mount the file system at /mnt/fmc */
+
+ ret = nx_mount("/dev/fmc", "/mnt/fmc", "littlefs", 0, NULL);
+ if (ret < 0)
+ {
+ ret = nx_mount("/dev/fmc", "/mnt/fmc", "littlefs", 0,
+ "forceformat");
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to mount the FS volume: %d\n", ret);
+ return ret;
+ }
+ }
+
+ syslog(LOG_INFO, "INFO: LittleFS volume /mnt/fmc mount " \
+ "on chip flash success: %d\n", ret);
+# endif
+# endif
+
+# ifdef HAVE_GD25
+
+ ret = gd32_gd25_automount(0);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to mount the LittleFS \
+ volume on spi flash: %d\n", ret);
+ }
+
+# endif
+
+# ifdef HAVE_AT24
+
+ ret = gd32_at24_wr_test(AT24_MINOR);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: I2C EEPROM write and read test fail: \
+ %d\n", ret);
+ }
+
+# endif
+
+#endif /* CONFIG_FS_NXFFS */
+
+#ifdef CONFIG_DEV_GPIO
+ /* Register the GPIO driver */
+
+ ret = gd32_gpio_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret);
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_INPUT_BUTTONS
+#ifdef CONFIG_INPUT_BUTTONS_LOWER
+ /* Register the BUTTON driver */
+
+ ret = btn_lower_initialize("/dev/buttons");
+ if (ret != OK)
+ {
+ syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
+ return ret;
+ }
+#else
+ /* Enable BUTTON support for some other purpose */
+
+ board_button_initialize();
+#endif /* CONFIG_INPUT_BUTTONS_LOWER */
+#endif /* CONFIG_INPUT_BUTTONS */
+
+#if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER)
+ /* Register the LED driver */
+
+ ret = userled_lower_initialize(LED_DRIVER_PATH);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n",
+ ret);
+ }
+#endif
+
+ /* Configure SDIO chip selects */
+
+#ifdef CONFIG_ARCH_HAVE_SDIO
+ ret = gd32_sdio_initialize();
+ if (ret != OK)
+ {
+ syslog(LOG_ERR, "ERROR: gd32_sdio_initialize() failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Mount the file system at /mnt/sd */
+
+ ret = nx_mount("/dev/mmcsd0", "/mnt/sd", "vfat", 0, NULL);
+ if (ret < 0)
+ {
+ ret = nx_mount("/dev/mmcsd0", "/mnt/sd", "vfat", 0,
+ "forceformat");
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to mount the SD card: %d\n", ret);
+ return ret;
+ }
+ }
+
+ syslog(LOG_INFO, "INFO: FAT volume /mnt/sd mount " \
+ "sd card success: %d\n", ret);
+#endif
+
+ /* Now we are initialized */
+
+ initialized = true;
+ }
+
+ UNUSED(ret);
+ return OK;
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_at24.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_at24.c
new file mode 100644
index 0000000000..b7e5473500
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_at24.c
@@ -0,0 +1,155 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_at24.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/i2c/i2c_master.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/kmalloc.h>
+
+#include "gd32f4xx.h"
+#include "gd32f470i_eval.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_at24_wr_test
+ *
+ * Description:
+ * Write and read the AT24 serial EEPROM test.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_AT24
+
+#define BUFFSIZE 16
+#define START_BLOCK 0
+
+#if BUFFSIZE>=CONFIG_AT24XX_MTD_BLOCKSIZE
+# define NBLOCK (BUFFSIZE/CONFIG_AT24XX_MTD_BLOCKSIZE)
+#else
+# error "BUFFSIZE should bigger than CONFIG_AT24XX_MTD_BLOCKSIZE"
+#endif
+
+const uint8_t write_buf[BUFFSIZE] =
+{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
+};
+
+int gd32_at24_wr_test(int minor)
+{
+ struct i2c_master_s *i2c;
+ struct mtd_dev_s *at24;
+ static bool initialized = false;
+ int ret;
+ ssize_t nblocks;
+ uint8_t *read_buf;
+
+ /* Have we already initialized? */
+
+ if (!initialized)
+ {
+ /* No.. Get the I2C port driver */
+
+ finfo("Initialize TWI%d\n", AT24_BUS);
+ i2c = gd32_i2cbus_initialize(AT24_BUS);
+ if (!i2c)
+ {
+ ferr("ERROR: Failed to initialize TWI%d\n", AT24_BUS);
+ return -ENODEV;
+ }
+
+ /* Now bind the I2C interface to the AT24 I2C EEPROM driver */
+
+ finfo("Bind the AT24 EEPROM driver to TWI%d\n", AT24_BUS);
+ at24 = at24c_initialize(i2c);
+ if (!at24)
+ {
+ ferr("ERROR: Failed to bind TWI%d to the AT24 EEPROM driver\n",
+ AT24_BUS);
+ return -ENODEV;
+ }
+
+ /* Now we are initializeed */
+
+ initialized = true;
+ }
+
+ /* Write start block is START_BLOCK, number of block is 2 */
+
+ nblocks = at24->bwrite(at24, START_BLOCK, NBLOCK, write_buf);
+ if (nblocks < NBLOCK)
+ {
+ ferr("ERROR: AT24 write failed: %zd\n", nblocks);
+ gd32_i2cbus_uninitialize(i2c);
+ return (int)nblocks;
+ }
+
+ read_buf = kmm_malloc(BUFFSIZE);
+
+ /* Read the data write before */
+
+ nblocks = at24->bread(at24, START_BLOCK, NBLOCK, read_buf);
+ if (nblocks < NBLOCK)
+ {
+ ferr("ERROR: AT24 read failed: %zd\n", nblocks);
+ gd32_i2cbus_uninitialize(i2c);
+ return (int)nblocks;
+ }
+
+ if (memcmp(read_buf, write_buf, BUFFSIZE) != 0)
+ {
+ ferr("ERROR: Read buffer does not match write buffer\n");
+ return -1;
+ }
+
+ /* Release the I2C instance.
+ * REVISIT: Need an interface to release the AT24 instance too
+ */
+
+ ret = gd32_i2cbus_uninitialize(i2c);
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to release the I2C interface: %d\n", ret);
+ }
+
+ syslog(LOG_INFO, "INFO: I2C EEPROM write and read success: \
+ %d\n", ret);
+
+ return OK;
+}
+
+#endif /* HAVE_AT24 */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_autoleds.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_autoleds.c
new file mode 100644
index 0000000000..1aaa8e2621
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_autoleds.c
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_autoleds.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <debug.h>
+
+#include <sys/param.h>
+
+#include <nuttx/board.h>
+#include <arch/board/board.h>
+
+#include "gd32f4xx_gpio.h"
+#include "gd32f470i_eval.h"
+#ifdef CONFIG_ARCH_LEDS
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* LED index */
+
+static const uint32_t g_led_map[BOARD_LEDS] =
+{
+ LED1,
+ LED2,
+ LED3
+};
+
+static bool g_initialized;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Turn on selected led */
+
+static void gd32_eval_led_on(led_typedef_enum led_num)
+{
+ gd32_gpio_write(g_led_map[led_num], true);
+}
+
+/* Turn off selected led */
+
+static void gd32_eval_led_off(led_typedef_enum led_num)
+{
+ gd32_gpio_write(g_led_map[led_num], false);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_autoled_initialize
+ ****************************************************************************/
+
+void board_autoled_initialize(void)
+{
+ int i;
+
+ /* Configure the LED GPIO for output. */
+
+ for (i = 0; i < nitems(g_led_map); i++)
+ {
+ gd32_gpio_config(g_led_map[i]);
+ }
+}
+
+/****************************************************************************
+ * Name: board_autoled_on
+ ****************************************************************************/
+
+void board_autoled_on(int led)
+{
+ switch (led)
+ {
+ default:
+ break;
+
+ case LED_HEAPALLOCATE:
+ gd32_eval_led_on(BOARD_LED1);
+ break;
+
+ case LED_IRQSENABLED:
+ gd32_eval_led_on(BOARD_LED2);
+ break;
+
+ case LED_STACKCREATED:
+ gd32_eval_led_on(BOARD_LED3);
+ g_initialized = true;
+ break;
+
+ case LED_INIRQ:
+ gd32_eval_led_on(BOARD_LED1);
+ gd32_eval_led_on(BOARD_LED2);
+ break;
+
+ case LED_SIGNAL:
+ gd32_eval_led_on(BOARD_LED1);
+ gd32_eval_led_on(BOARD_LED3);
+ break;
+
+ case LED_ASSERTION:
+ gd32_eval_led_on(BOARD_LED2);
+ gd32_eval_led_on(BOARD_LED3);
+ break;
+
+ case LED_PANIC:
+ gd32_eval_led_on(BOARD_LED1);
+ break;
+
+ case LED_IDLE : /* IDLE */
+ gd32_eval_led_on(BOARD_LED2);
+ break;
+ }
+}
+
+/****************************************************************************
+ * Name: board_autoled_off
+ ****************************************************************************/
+
+void board_autoled_off(int led)
+{
+ switch (led)
+ {
+ default:
+ break;
+
+ case LED_SIGNAL:
+ gd32_eval_led_off(BOARD_LED1);
+ gd32_eval_led_off(BOARD_LED3);
+ break;
+
+ case LED_INIRQ:
+ gd32_eval_led_off(BOARD_LED1);
+ gd32_eval_led_off(BOARD_LED2);
+ break;
+
+ case LED_ASSERTION:
+ gd32_eval_led_off(BOARD_LED2);
+ gd32_eval_led_off(BOARD_LED3);
+ break;
+
+ case LED_PANIC:
+ gd32_eval_led_off(BOARD_LED1);
+ break;
+
+ case LED_IDLE : /* IDLE */
+ gd32_eval_led_off(BOARD_LED2);
+ break;
+ }
+}
+
+#endif /* CONFIG_ARCH_LEDS */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_boot.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_boot.c
new file mode 100644
index 0000000000..6500db7179
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_boot.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_boot.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+
+#include <nuttx/board.h>
+#include <arch/board/board.h>
+
+#include "gd32f470i_eval.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_boardinitialize
+ *
+ * Description:
+ * All GD32F4xx architectures must provide the following entry point.
+ * This entry point is called early in the initialization
+ * after all memory has been configured and mapped but
+ * before any devices have been initialized.
+ *
+ ****************************************************************************/
+
+void gd32_boardinitialize(void)
+{
+#ifdef CONFIG_ARCH_LEDS
+ /* Configure on-board LEDs if LED support has been selected. */
+
+ board_autoled_initialize();
+#endif
+
+#if defined(CONFIG_SPI)
+ /* Configure SPI chip selects */
+
+ gd32_spidev_initialize();
+#endif
+}
+
+/****************************************************************************
+ * Name: board_late_initialize
+ *
+ * Description:
+ * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
+ * initialization call will be performed in the boot-up sequence to a
+ * function called board_late_initialize(). board_late_initialize()
+ * will be called immediately after up_initialize() is called and
+ * just before the initial application is started. This additional
+ * initialization phase may be used, for example, to initialize
+ * board-specific device drivers.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BOARD_LATE_INITIALIZE
+void board_late_initialize(void)
+{
+#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_BOARDCTL)
+ /* Perform NSH initialization here instead of from the NSH. This
+ * alternative NSH initialization is necessary when NSH is ran in
+ * user-space but the initialization function must run in kernel space.
+ */
+
+ board_app_initialize(0);
+#endif
+}
+#endif
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_bringup.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_bringup.c
new file mode 100644
index 0000000000..79e93e5b80
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_bringup.c
@@ -0,0 +1,184 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_bringup.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/board.h>
+#include <nuttx/clock.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/nxffs.h>
+#include <nuttx/fs/rpmsgfs.h>
+#include <nuttx/spi/spi_transfer.h>
+#include <nuttx/rc/dummy.h>
+
+#include "gd32f470i_eval.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_bringup
+ *
+ * Description:
+ * Perform architecture-specific initialization
+ *
+ * CONFIG_BOARD_LATE_INITIALIZE=y :
+ * Called from board_late_initialize().
+ *
+ * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y :
+ * Called from the NSH library via boardctl()
+ *
+ ****************************************************************************/
+
+int gd32_bringup(void)
+{
+#ifdef CONFIG_RAMMTD
+ uint8_t *ramstart;
+#endif
+
+ int ret = OK;
+
+#ifdef CONFIG_FS_PROCFS
+ /* Mount the procfs file system */
+
+ ret = nx_mount(NULL, GD32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to mount procfs at %s: %d\n",
+ GD32_PROCFS_MOUNTPOINT, ret);
+ }
+#endif
+
+#ifdef CONFIG_RAMMTD
+ /* Create a RAM MTD device if configured */
+
+ ramstart = kmm_malloc(64 * 1024);
+ if (ramstart == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: Allocation for RAM MTD failed\n");
+ }
+ else
+ {
+ /* Initialized the RAM MTD */
+
+ struct mtd_dev_s *mtd = rammtd_initialize(ramstart, 64 * 1024);
+ if (mtd == NULL)
+ {
+ syslog(LOG_ERR, "ERROR: rammtd_initialize failed\n");
+ kmm_free(ramstart);
+ }
+ else
+ {
+ /* Erase the RAM MTD */
+
+ ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: IOCTL MTDIOC_BULKERASE failed\n");
+ }
+
+#if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS)
+ /* Initialize a SMART Flash block device and bind it to the MTD
+ * device.
+ */
+
+ smart_initialize(0, mtd, NULL);
+
+#elif defined(CONFIG_FS_SPIFFS)
+ /* Register the MTD driver so that it can be accessed from the
+ * VFS.
+ */
+
+ ret = register_mtddriver("/dev/rammtd", mtd, 0755, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to register MTD driver: %d\n",
+ ret);
+ }
+
+ /* Mount the SPIFFS file system */
+
+ ret = nx_mount("/dev/rammtd", "/mnt/spiffs", "spiffs", 0, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR,
+ "ERROR: Failed to mount SPIFFS at /mnt/spiffs: %d\n",
+ ret);
+ }
+
+#elif defined(CONFIG_FS_LITTLEFS)
+ /* Register the MTD driver so that it can be accessed from the
+ * VFS.
+ */
+
+ ret = register_mtddriver("/dev/rammtd", mtd, 0755, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to register MTD driver: %d\n",
+ ret);
+ }
+
+ /* Mount the LittleFS file system */
+
+ ret = nx_mount("/dev/rammtd", "/mnt/lfs", "littlefs", 0,
+ "forceformat");
+ if (ret < 0)
+ {
+ syslog(LOG_ERR,
+ "ERROR: Failed to mount LittleFS at /mnt/lfs: %d\n",
+ ret);
+ }
+
+#elif defined(CONFIG_FS_NXFFS)
+ /* Initialize to provide NXFFS on the MTD interface */
+
+ ret = nxffs_initialize(mtd);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: NXFFS initialization failed: %d\n",
+ ret);
+ }
+#endif
+ }
+ }
+#endif
+
+#if defined(CONFIG_INPUT_BUTTONS_LOWER)
+ ret = btn_lower_initialize("/dev/buttons");
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
+ }
+#endif
+
+ return ret;
+}
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_buttons.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_buttons.c
new file mode 100644
index 0000000000..c48debefed
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_buttons.c
@@ -0,0 +1,190 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_buttons.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stddef.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/board.h>
+
+#include <arch/board/board.h>
+
+#include "gd32f4xx.h"
+#include "gd32f470i_eval.h"
+
+#ifdef CONFIG_ARCH_BUTTONS
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const uint32_t g_button_boards[NUM_BUTTONS] =
+{
+ GPIO_BTN_USER, GPIO_BTN_TAMPER, GPIO_BTN_WAKEUP
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_button_initialize
+ *
+ * Description:
+ * board_button_initialize() must be called to initialize button resources.
+ * After that, board_buttons() may be called to collect the current state
+ * of all buttons or board_button_irq() may be called to register button
+ * interrupt handlers.
+ *
+ ****************************************************************************/
+
+uint32_t board_button_initialize(void)
+{
+ int i;
+
+ /* Configure each button */
+
+ for (i = 0; i < NUM_BUTTONS; i++)
+ {
+ gd32_gpio_config(g_button_boards[i]);
+ }
+
+ return NUM_BUTTONS;
+}
+
+/****************************************************************************
+ * Name: board_buttons
+ * After board_button_initialize() has been called, board_buttons() may be
+ * called to collect the state of all buttons. board_buttons() returns an
+ * 32-bit bit set with each bit associated with a button. See the BUTTON*
+ * definitions above for the meaning of each bit in the returned value.
+ *
+ ****************************************************************************/
+
+uint32_t board_buttons(void)
+{
+ uint32_t ret;
+ int i;
+
+ /* Check each button */
+
+ for (i = 0, ret = 0; i < NUM_BUTTONS; i++)
+ {
+ /* The low value is sensed when the button is pressed */
+
+ if (!gd32_gpio_read(g_button_boards[i]))
+ {
+ ret |= (1 << i);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Button support.
+ *
+ * Description:
+ * board_button_initialize() must be called to initialize button resources.
+ * After that, board_buttons() may be called to collect the current
+ * state of all buttons or board_button_irq() may be called to register
+ * button interrupt handlers.
+ *
+ * After board_button_initialize() has been called, board_buttons()
+ * may be called to collect the state of all buttons. board_buttons()
+ * returns an 32-bit bit set with each bit associated with a button.
+ * See the BUTTON_*_BIT definitions in board.h for the meaning of each
+ * bit.
+ *
+ * board_button_irq() may be called to register an interrupt handler that
+ * will be called when a button is depressed or released. The ID value
+ * is a button enumeration value that uniquely identifies a button
+ * resource. See the BUTTON_* definitions in board.h for the meaning of
+ * enumeration value.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+int board_button_irq(int id, xcpt_t irqhandler, void *arg)
+{
+ if (id >= 0 && id < NUM_BUTTONS)
+ {
+ uint8_t gpio_irq;
+ uint8_t gpio_irqnum;
+ irqstate_t flags;
+ int ret;
+
+ /* Disable interrupts until we are done. This guarantees that the
+ * following operations are atomic.
+ */
+
+ flags = enter_critical_section();
+
+ /* Get gpio irq numbers */
+
+ ret = gd32_gpio_exti_irqnum_get(g_button_boards[id], &gpio_irqnum);
+
+ if (ret < 0)
+ {
+ leave_critical_section(flags);
+ return ret;
+ }
+
+ /* Are we attaching or detaching? */
+
+ if (irqhandler != NULL)
+ {
+ ret = gd32_exti_gpioirq_init(g_button_boards[id], EXTI_INTERRUPT,
+ EXTI_TRIG_RISING, &gpio_irq);
+
+ if (ret < 0)
+ {
+ leave_critical_section(flags);
+ return ret;
+ }
+
+ /* Attach and enable the interrupt */
+
+ gd32_exti_gpio_irq_attach(gpio_irq, irqhandler, arg);
+ up_enable_irq(gpio_irqnum);
+ }
+ else
+ {
+ /* Disable and detach the interrupt */
+
+ up_disable_irq(gpio_irqnum);
+ irq_detach(gpio_irqnum);
+ }
+
+ leave_critical_section(flags);
+ }
+
+ /* Return the old button handler (so that it can be restored) */
+
+ return OK;
+}
+#endif
+#endif /* CONFIG_ARCH_BUTTONS */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gd25.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gd25.c
new file mode 100644
index 0000000000..54c90b492b
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gd25.c
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gd25.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/spi/spi.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/nxffs.h>
+
+#include "gd32f4xx.h"
+#include "gd32f470i_eval.h"
+
+#ifdef HAVE_GD25
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_gd25_automount
+ *
+ * Description:
+ * Initialize, configure, and mount the GD25 SPI FLASH. The FLASH will
+ * be mounted at /dev/gd25.
+ *
+ ****************************************************************************/
+
+int gd32_gd25_automount(int minor)
+{
+ struct spi_dev_s *spi;
+ struct mtd_dev_s *mtd;
+ static bool initialized = false;
+ int ret;
+
+ /* Have we already initialized? */
+
+ if (!initialized)
+ {
+ /* No.. Get the SPI port driver */
+
+ spi = gd32_spibus_initialize(SPI_FLASH_CSNUM);
+ if (!spi)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize SPI port %d\n",
+ SPI_FLASH_CSNUM);
+ return -ENODEV;
+ }
+
+ /* Now bind the SPI interface to the GD25 SPI FLASH driver */
+
+ mtd = gd25_initialize(spi, 0);
+ if (!mtd)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to bind SPI port to the \
+ GD25 FLASH driver\n");
+ return -ENODEV;
+ }
+
+#if defined(CONFIG_GD32F470ZK_EVAL_GD25_FTL)
+ /* And finally, use the FTL layer to wrap the MTD driver as a block
+ * driver at /dev/mtdblockN, where N=minor device number.
+ */
+
+ ret = ftl_initialize(minor, mtd);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize the FTL layer: %d\n",
+ ret);
+ return ret;
+ }
+
+#elif defined(CONFIG_GD32F470ZK_EVAL_GD25_NXFFS)
+ /* Initialize to provide NXFFS on the MTD interface */
+
+ ret = nxffs_initialize(mtd);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: NXFFS initialization failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Mount the file system at /mnt/gd25 */
+
+ ret = nx_mount(NULL, "/mnt/gd25", "nxffs", 0, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to mount the NXFFS volume: %d\n",
+ ret);
+ return ret;
+ }
+
+ syslog(LOG_INFO, "INFO: NXFFS volume /mnt/gd25 mount \
+ spi flash success: %d\n", ret);
+
+#elif defined(CONFIG_GD32F470ZK_EVAL_GD25_LITTLEFS)
+ /* Initialize to provide LittleFS on the MTD interface */
+
+ ret = register_mtddriver("/dev/spiflash", mtd, 0755, NULL);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to register MTD: %d\n", ret);
+ return ret;
+ }
+
+ /* Mount the file system at /mnt/gd25 */
+
+ ret = nx_mount("/dev/spiflash", "/mnt/gd25", "littlefs", 0, NULL);
+ if (ret < 0)
+ {
+ ret = nx_mount("/dev/spiflash", "/mnt/gd25", "littlefs", 0,
+ "forceformat");
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to mount the FS volume: %d\n", ret);
+ return ret;
+ }
+ }
+
+ syslog(LOG_INFO, "INFO: LittleFS volume /mnt/gd25 mount \
+ spi flash success: %d\n", ret);
+#endif
+
+ /* Now we are initialized */
+
+ initialized = true;
+ }
+
+ UNUSED(ret);
+
+ return OK;
+}
+
+#endif /* HAVE_GD25 */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gpio.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gpio.c
new file mode 100644
index 0000000000..9a2ecb855c
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gpio.c
@@ -0,0 +1,397 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_gpio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/wdog.h>
+#include <nuttx/ioexpander/gpio.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+
+#include "gd32f4xx.h"
+#include "gd32f470i_eval.h"
+
+#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct gd32gpio_dev_s
+{
+ struct gpio_dev_s gpio;
+ uint8_t id;
+};
+
+struct gd32gpint_dev_s
+{
+ struct gd32gpio_dev_s gd32gpio;
+ pin_interrupt_t callback;
+};
+
+irqstate_t flags;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int gpio_setpintype(struct gpio_dev_s *dev,
+ enum gpio_pintype_e gp_pintype);
+
+#if BOARD_NGPIOIN > 0
+static int gpin_read(struct gpio_dev_s *dev, bool *value);
+#endif
+
+#if BOARD_NGPIOOUT > 0
+static int gpout_read(struct gpio_dev_s *dev, bool *value);
+static int gpout_write(struct gpio_dev_s *dev, bool value);
+#endif
+
+#if BOARD_NGPIOINT > 0
+static int gpint_read(struct gpio_dev_s *dev, bool *value);
+static int gpint_attach(struct gpio_dev_s *dev,
+ pin_interrupt_t callback);
+static int gpint_enable(struct gpio_dev_s *dev, bool enable);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+ #if BOARD_NGPIOIN > 0
+static const struct gpio_operations_s gpin_ops =
+{
+ .go_read = gpin_read,
+ .go_write = NULL,
+ .go_attach = NULL,
+ .go_enable = NULL,
+ .go_setpintype = gpio_setpintype,
+};
+
+/* This array maps the GPIO pins used as INPUT */
+
+static const uint32_t g_gpioinputs[BOARD_NGPIOIN] =
+{
+ GPIO_IN1,
+};
+
+static struct gd32gpio_dev_s g_gpin[BOARD_NGPIOIN];
+#endif
+
+#if BOARD_NGPIOOUT > 0
+
+static const struct gpio_operations_s gpout_ops =
+{
+ .go_read = gpout_read,
+ .go_write = gpout_write,
+ .go_attach = NULL,
+ .go_enable = NULL,
+ .go_setpintype = gpio_setpintype,
+};
+
+/* This array maps the GPIO pins used as OUTPUT */
+
+static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] =
+{
+ GPIO_OUT1,
+};
+
+static struct gd32gpio_dev_s g_gpout[BOARD_NGPIOOUT];
+#endif
+
+#if BOARD_NGPIOINT > 0
+
+static const struct gpio_operations_s gpint_ops =
+{
+ .go_read = gpint_read,
+ .go_write = NULL,
+ .go_attach = gpint_attach,
+ .go_enable = gpint_enable,
+ .go_setpintype = gpio_setpintype,
+};
+
+/* This array maps the GPIO pins used as INTERRUPT INPUTS */
+
+static const uint32_t g_gpiointinputs[BOARD_NGPIOINT] =
+{
+ GPIO_INT1,
+};
+
+static struct gd32gpint_dev_s g_gpint[BOARD_NGPIOINT];
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gpio_setpintype
+ *
+ * Description:
+ * set gpio pintype.
+ *
+ ****************************************************************************/
+
+static int gpio_setpintype(struct gpio_dev_s *dev,
+ enum gpio_pintype_e gpio_pintype)
+{
+ struct gd32gpint_dev_s *gd32gpint = (struct gd32gpint_dev_s *)dev;
+
+ UNUSED(gd32gpint);
+ UNUSED(gpio_pintype);
+
+ gpioinfo("setpintype is not supported. \n");
+
+ return 0;
+}
+
+#if BOARD_NGPIOIN > 0
+static int gpin_read(struct gpio_dev_s *dev, bool *value)
+{
+ struct gd32gpio_dev_s *gd32gpio = (struct gd32gpio_dev_s *)dev;
+
+ DEBUGASSERT(gd32gpio != NULL && value != NULL);
+ DEBUGASSERT(gd32gpio->id < BOARD_NGPIOIN);
+ gpioinfo("Reading...\n");
+
+ *value = gd32_gpio_read(g_gpioinputs[gd32gpio->id]);
+ return OK;
+}
+#endif
+
+#if BOARD_NGPIOOUT > 0
+static int gpout_read(struct gpio_dev_s *dev, bool *value)
+{
+ struct gd32gpio_dev_s *gd32gpio = (struct gd32gpio_dev_s *)dev;
+
+ DEBUGASSERT(gd32gpio != NULL && value != NULL);
+ DEBUGASSERT(gd32gpio->id < BOARD_NGPIOOUT);
+ gpioinfo("Reading...\n");
+
+ *value = gd32_gpio_read(g_gpiooutputs[gd32gpio->id]);
+ return OK;
+}
+
+static int gpout_write(struct gpio_dev_s *dev, bool value)
+{
+ struct gd32gpio_dev_s *gd32gpio = (struct gd32gpio_dev_s *)dev;
+
+ DEBUGASSERT(gd32gpio != NULL);
+ DEBUGASSERT(gd32gpio->id < BOARD_NGPIOOUT);
+ gpioinfo("Writing %d\n", (int)value);
+
+ gd32_gpio_write(g_gpiooutputs[gd32gpio->id], value);
+ return OK;
+}
+#endif
+
+#if BOARD_NGPIOINT > 0
+
+static int gd32gpio_interrupt(int irq, void *context, void *arg)
+{
+ struct gd32gpint_dev_s *gd32gpint = (struct gd32gpint_dev_s *)arg;
+
+ DEBUGASSERT(gd32gpint != NULL && gd32gpint->callback != NULL);
+ gpioinfo("Interrupt! callback=%p\n", gd32gpint->callback);
+
+ gd32gpint->callback(&gd32gpint->gd32gpio.gpio, gd32gpint->gd32gpio.id);
+ return OK;
+}
+
+static int gpint_read(struct gpio_dev_s *dev, bool *value)
+{
+ struct gd32gpint_dev_s *gd32gpint = (struct gd32gpint_dev_s *)dev;
+
+ DEBUGASSERT(gd32gpint != NULL && value != NULL);
+ DEBUGASSERT(gd32gpint->gd32gpio.id < BOARD_NGPIOINT);
+ gpioinfo("Reading int pin...\n");
+
+ *value = gd32_gpio_read(g_gpiointinputs[gd32gpint->gd32gpio.id]);
+ return OK;
+}
+
+static int gpint_attach(struct gpio_dev_s *dev, pin_interrupt_t callback)
+{
+ struct gd32gpint_dev_s *gd32gpint = (struct gd32gpint_dev_s *)dev;
+ int ret;
+ uint8_t gpio_irq;
+ uint8_t gpio_irqnum;
+
+ gpioinfo("Attaching the callback\n");
+
+ flags = enter_critical_section();
+
+ /* Make sure the interrupt is disabled */
+
+ ret = gd32_exti_gpioirq_init(g_gpiointinputs[gd32gpint->gd32gpio.id],
+ EXTI_INTERRUPT, EXTI_TRIG_RISING, &gpio_irq);
+
+ if (ret < 0)
+ {
+ leave_critical_section(flags);
+ return ret;
+ }
+
+ gd32_gpio_exti_irqnum_get(g_gpiointinputs[gd32gpint->gd32gpio.id],
+ &gpio_irqnum);
+
+ /* Attach and disable the interrupt */
+
+ gd32_exti_gpio_irq_attach(gpio_irq, gd32gpio_interrupt,
+ &g_gpint[gd32gpint->gd32gpio.id]);
+
+ /* Disable and the interrupt */
+
+ up_disable_irq(gpio_irqnum);
+
+ leave_critical_section(flags);
+ gpioinfo("Attach %p\n", callback);
+ gd32gpint->callback = callback;
+ return OK;
+}
+
+static int gpint_enable(struct gpio_dev_s *dev, bool enable)
+{
+ struct gd32gpint_dev_s *gd32gpint = (struct gd32gpint_dev_s *)dev;
+ int ret;
+ uint8_t gpio_irqnum;
+
+ flags = enter_critical_section();
+
+ /* Get gpio irq numbers */
+
+ ret = gd32_gpio_exti_irqnum_get(g_gpiointinputs[gd32gpint->gd32gpio.id],
+ &gpio_irqnum);
+ if (ret < 0)
+ {
+ leave_critical_section(flags);
+ return ret;
+ }
+
+ if (enable)
+ {
+ if (gd32gpint->callback != NULL)
+ {
+ gpioinfo("Enabling the interrupt\n");
+
+ /* Enable the interrupt */
+
+ up_disable_irq(gpio_irqnum);
+ }
+ }
+ else
+ {
+ up_disable_irq(gpio_irqnum);
+ gpioinfo("Disable the interrupt\n");
+ }
+
+ leave_critical_section(flags);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_gpio_initialize
+ *
+ * Description:
+ * Initialize GPIO drivers for use with /apps/examples/gpio
+ *
+ ****************************************************************************/
+
+int gd32_gpio_initialize(void)
+{
+ int pincount = 0;
+ int i;
+
+#if BOARD_NGPIOIN > 0
+ for (i = 0; i < BOARD_NGPIOIN; i++)
+ {
+ /* Setup and register the GPIO pin */
+
+ g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN;
+ g_gpin[i].gpio.gp_ops = &gpin_ops;
+ g_gpin[i].id = i;
+
+ gpio_pin_register(&g_gpin[i].gpio, pincount);
+
+ /* Configure the pin that will be used as input */
+
+ gd32_gpio_config(g_gpioinputs[i]);
+
+ pincount++;
+ }
+#endif
+
+#if BOARD_NGPIOOUT > 0
+ for (i = 0; i < BOARD_NGPIOOUT; i++)
+ {
+ /* Setup and register the GPIO pin */
+
+ g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
+ g_gpout[i].gpio.gp_ops = &gpout_ops;
+ g_gpout[i].id = i;
+
+ gpio_pin_register(&g_gpout[i].gpio, pincount);
+
+ /* Configure the pin that will be used as output */
+
+ gd32_gpio_write(g_gpiooutputs[i], 0);
+ gd32_gpio_config(g_gpiooutputs[i]);
+
+ pincount++;
+ }
+#endif
+
+#if BOARD_NGPIOINT > 0
+ for (i = 0; i < BOARD_NGPIOINT; i++)
+ {
+ /* Setup and register the GPIO pin */
+
+ g_gpint[i].gd32gpio.gpio.gp_pintype = GPIO_INTERRUPT_PIN;
+ g_gpint[i].gd32gpio.gpio.gp_ops = &gpint_ops;
+ g_gpint[i].gd32gpio.id = i;
+ (void)gpio_pin_register(&g_gpint[i].gd32gpio.gpio, pincount);
+
+ /* Configure the pin that will be used as interrupt input */
+
+ gd32_gpio_config(g_gpiointinputs[i]);
+
+ pincount++;
+ }
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c
new file mode 100644
index 0000000000..40b0e69daa
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c
@@ -0,0 +1,137 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/drivers/ramdisk.h>
+#include "gd32f4xx_romfs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_GD32F4_ROMFS
+# error "CONFIG_GD32F4_ROMFS must be defined"
+#else
+
+#ifndef CONFIG_GD32F4_ROMFS_IMAGEFILE
+# error "CONFIG_GD32F4_ROMFS_IMAGEFILE must be defined"
+#endif
+
+#ifndef CONFIG_GD32F4_ROMFS_DEV_MINOR
+# error "CONFIG_GD32F4_ROMFS_DEV_MINOR must be defined"
+#endif
+
+#ifndef CONFIG_GD32F4_ROMFS_MOUNTPOINT
+# error "CONFIG_GD32F4_ROMFS_MOUNTPOINT must be defined"
+#endif
+
+#define NSECTORS(size) (((size) + ROMFS_SECTOR_SIZE - 1)/ROMFS_SECTOR_SIZE)
+
+#define STR2(m) #m
+#define STR(m) STR2(m)
+
+#define MKMOUNT_DEVNAME(m) "/dev/ram" STR(m)
+#define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_GD32F4_ROMFS_DEV_MINOR)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+__asm__ (
+ " .section .rodata \n"
+ " .balign 16 \n"
+ " .globl romfs_data_begin \n"
+ "romfs_data_begin: \n"
+ " .incbin " STR(CONFIG_GD32F4_ROMFS_IMAGEFILE)"\n"
+ " .balign " STR(ROMFS_SECTOR_SIZE) "\n"
+ " .globl romfs_data_end \n"
+ "romfs_data_end: \n"
+ );
+
+extern const uint8_t romfs_data_begin[];
+extern const uint8_t romfs_data_end[];
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_romfs_initialize
+ *
+ * Description:
+ * Registers the aboveincluded binary file as block device.
+ * Then mounts the block device as ROMFS filesystems.
+ *
+ * Returned Value:
+ * Zero (OK) on success, a negated errno value on error.
+ *
+ * Assumptions/Limitations:
+ * Memory addresses [romfs_data_begin .. romfs_data_end) should contain
+ * ROMFS volume data, as included in the assembly snippet above.
+ *
+ ****************************************************************************/
+
+int gd32_romfs_initialize(void)
+{
+ uintptr_t romfs_data_len;
+ int ret;
+
+ /* Create a ROM disk for the /etc filesystem */
+
+ romfs_data_len = romfs_data_end - romfs_data_begin;
+
+ ret = romdisk_register(CONFIG_GD32F4_ROMFS_DEV_MINOR, romfs_data_begin,
+ NSECTORS(romfs_data_len), ROMFS_SECTOR_SIZE);
+ if (ret < 0)
+ {
+ ferr("ERROR: romdisk_register failed: %d\n", -ret);
+ return ret;
+ }
+
+ /* Mount the file system */
+
+ finfo("Mounting ROMFS filesystem at target=%s with source=%s\n",
+ CONFIG_GD32F4_ROMFS_MOUNTPOINT, MOUNT_DEVNAME);
+
+ ret = nx_mount(MOUNT_DEVNAME, CONFIG_GD32F4_ROMFS_MOUNTPOINT,
+ "romfs", MS_RDONLY, NULL);
+ if (ret < 0)
+ {
+ ferr("ERROR: nx_mount(%s,%s,romfs) failed: %d\n",
+ MOUNT_DEVNAME, CONFIG_GD32F4_ROMFS_MOUNTPOINT, ret);
+ return ret;
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_GD32F4_ROMFS */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.h b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.h
new file mode 100644
index 0000000000..9dfd6304d0
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_ARM_GD32F4_GD32F470IK_EVAL_SRC_GD32F4XX_ROMFS_H
+#define __BOARDS_ARM_GD32F4_GD32F470IK_EVAL_SRC_GD32F4XX_ROMFS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifdef CONFIG_GD32F4_ROMFS
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ROMFS_SECTOR_SIZE 64
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_romfs_initialize
+ *
+ * Description:
+ * Registers built-in ROMFS image as block device and mounts it.
+ *
+ * Returned Value:
+ * Zero (OK) on success, a negated errno value on error.
+ *
+ * Assumptions/Limitations:
+ * Memory addresses [romfs_data_begin .. romfs_data_end) should contain
+ * ROMFS volume data, as included in the assembly snippet in
+ * gd32f4xx_romfs.c.
+ *
+ ****************************************************************************/
+
+int gd32_romfs_initialize(void);
+
+#endif /* CONFIG_GD32F4_ROMFS */
+
+#endif /* __BOARDS_ARM_GD32F4_GD32F470IK_EVAL_SRC_GD32F4XX_ROMFS_H */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_sdio.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_sdio.c
new file mode 100644
index 0000000000..5bf9016105
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_sdio.c
@@ -0,0 +1,149 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_sdio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/sdio.h>
+#include <nuttx/mmcsd.h>
+
+#include "chip.h"
+#include "gd32f4xx.h"
+#include "gd32f470i_eval.h"
+
+#ifdef CONFIG_MMCSD
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* Card detections requires card support and a card detection GPIO */
+
+#define HAVE_NCD 1
+#if !defined(GPIO_SDMMC1_NCD)
+# undef HAVE_NCD
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct sdio_dev_s *g_sdio_dev;
+#ifdef HAVE_NCD
+static bool g_sd_inserted;
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_ncd_interrupt
+ *
+ * Description:
+ * Card detect interrupt handler.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_NCD
+static int gd32_ncd_interrupt(int irq, void *context)
+{
+ bool present;
+
+ present = !gd32_gpio_read(GPIO_SDMMC1_NCD);
+ if (g_sdio_dev && present != g_sd_inserted)
+ {
+ sdio_mediachange(g_sdio_dev, present);
+ g_sd_inserted = present;
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_sdio_initialize
+ *
+ * Description:
+ * Initialize SDIO-based MMC/SD card support
+ *
+ ****************************************************************************/
+
+int gd32_sdio_initialize(void)
+{
+ int ret;
+
+ /* Mount the SDIO-based MMC/SD block driver
+ * First, get an instance of the SDIO interface
+ */
+
+ finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO);
+
+ g_sdio_dev = sdio_initialize(SDIO_SLOTNO);
+ if (!g_sdio_dev)
+ {
+ ferr("ERROR: Failed to initialize SDIO slot %d\n", SDIO_SLOTNO);
+ return -ENODEV;
+ }
+
+ /* Now bind the SDIO interface to the MMC/SD driver */
+
+ finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR);
+
+ ret = mmcsd_slotinitialize(SDIO_MINOR, g_sdio_dev);
+ if (ret != OK)
+ {
+ ferr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
+ return ret;
+ }
+
+ finfo("Successfully bound SDIO to the MMC/SD driver\n");
+
+#ifdef HAVE_NCD
+ /* Use SD card detect pin to check if a card is g_sd_inserted */
+
+ g_sd_inserted = !gd32_gpio_read(GPIO_SDMMC1_NCD);
+ finfo("Card detect : %d\n", g_sd_inserted);
+
+ sdio_mediachange(g_sdio_dev, g_sd_inserted);
+#else
+ /* Assume that the SD card is inserted. What choice do we have? */
+
+ sdio_mediachange(g_sdio_dev, true);
+#endif
+
+ return OK;
+}
+
+#endif /* CONFIG_MMCSD */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_spi.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_spi.c
new file mode 100644
index 0000000000..8b46c8a42d
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_spi.c
@@ -0,0 +1,283 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_spi.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/spi/spi.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "gd32f4xx.h"
+#include "gd32f470i_eval.h"
+
+#if defined(CONFIG_SPI)
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gd32_spidev_initialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins for the GD32F470Z-EVAL.
+ *
+ ****************************************************************************/
+
+void weak_function gd32_spidev_initialize(void)
+{
+#ifdef CONFIG_GD32F4_SPI0
+ /* Configure SPI0 CS GPIO for output */
+
+ gd32_gpio_config(GPIO_SPI0_CSPIN);
+ gd32_gpio_write(GPIO_SPI0_CSPIN, 1);
+#endif
+#ifdef CONFIG_GD32F4_SPI1
+ /* Configure SPI1 CS GPIO for output */
+
+ gd32_gpio_config(GPIO_SPI1_CSPIN);
+ gd32_gpio_write(GPIO_SPI1_CSPIN, 1);
+#endif
+#ifdef CONFIG_GD32F4_SPI2
+ /* Configure SPI2 CS GPIO for output */
+
+ gd32_gpio_config(GPIO_SPI2_CSPIN);
+ gd32_gpio_write(GPIO_SPI2_CSPIN, 1);
+#endif
+#ifdef CONFIG_GD32F4_SPI3
+ /* Configure SPI3 CS GPIO for output */
+
+ gd32_gpio_config(GPIO_SPI3_CSPIN);
+ gd32_gpio_write(GPIO_SPI3_CSPIN, 1);
+#endif
+#ifdef CONFIG_GD32F4_SPI4
+ /* Configure SPI4 CS GPIO for output */
+
+ gd32_gpio_config(GPIO_SPI4_CSPIN);
+ gd32_gpio_write(GPIO_SPI4_CSPIN, 1);
+#endif
+#ifdef CONFIG_GD32F4_SPI5
+ /* Configure SPI5 CS GPIO for output */
+
+ gd32_gpio_config(GPIO_SPI5_CSPIN);
+ gd32_gpio_write(GPIO_SPI5_CSPIN, 1);
+#endif
+}
+
+/****************************************************************************
+ * Name: gd32_spi[n]select and gd32_spi[n]status
+ *
+ * Description:
+ * The external functions, gd32_spi0-5select and gd32_spi0-5 status
+ * must be provided by board-specific logic. They are implementations of the
+ * select and status methods of the SPI interface defined by struct spi_ops_s
+ * (see include/nuttx/spi/spi.h).
+ * All other methods (including gd32_spibus_initialize()) are provided by
+ * common GD32F4 logic. To use this common SPI logic on your board:
+ *
+ * 1. Provide logic in gd32_boardinitialize() to configure SPI chip select
+ * pins.
+ * 2. Provide gd32_spi[n]select() and gd32_spi[n]status() functions
+ * in your board-specific logic. These functions will perform chip
+ * selection and status operations using GPIOs in the way your board is
+ * configured.
+ * 3. Add a calls to gd32_spibus_initialize() in your low level
+ * application initialization logic
+ * 4. The handle returned by gd32_spibus_initialize() may then be used to
+ * bind the SPI driver to higher level logic (e.g., calling
+ * mmcsd_spislotinitialize(), for example, will bind the SPI driver to
+ * the SPI MMC/SD driver).
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_GD32F4_SPI0
+void gd32_spi0select(struct spi_dev_s *dev, uint32_t devid,
+ bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid,
+ selected ? "assert" : "de-assert");
+
+ gd32_gpio_write(GPIO_SPI0_CSPIN, !selected);
+}
+
+uint8_t gd32_spi0status(struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI1
+void gd32_spi1select(struct spi_dev_s *dev, uint32_t devid,
+ bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid,
+ selected ? "assert" : "de-assert");
+
+ gd32_gpio_write(GPIO_SPI1_CSPIN, !selected);
+}
+
+uint8_t gd32_spi1status(struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI2
+void gd32_spi2select(struct spi_dev_s *dev, uint32_t devid,
+ bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid,
+ selected ? "assert" : "de-assert");
+
+ gd32_gpio_write(GPIO_SPI2_CSPIN, !selected);
+}
+
+uint8_t gd32_spi2status(struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI3
+void gd32_spi3select(struct spi_dev_s *dev, uint32_t devid,
+ bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid,
+ selected ? "assert" : "de-assert");
+
+ gd32_gpio_write(GPIO_SPI3_CSPIN, !selected);
+}
+
+uint8_t gd32_spi3status(struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI4
+void gd32_spi4select(struct spi_dev_s *dev, uint32_t devid,
+ bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid,
+ selected ? "assert" : "de-assert");
+
+ gd32_gpio_write(GPIO_SPI4_CSPIN, !selected);
+}
+
+uint8_t gd32_spi4status(struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI5
+void gd32_spi5select(struct spi_dev_s *dev, uint32_t devid,
+ bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid,
+ selected ? "assert" : "de-assert");
+
+ gd32_gpio_write(GPIO_SPI5_CSPIN, !selected);
+}
+
+uint8_t gd32_spi5status(struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: gd32_spi[n]cmddata
+ *
+ * Description:
+ * Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true)
+ * or command (false). This function must be provided by platform-specific
+ * logic. This is an implementation of the cmddata method of the SPI
+ * interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h).
+ *
+ * Input Parameters:
+ *
+ * spi - SPI device that controls the bus the device that requires the CMD/
+ * DATA selection.
+ * devid - If there are multiple devices on the bus, this selects which one
+ * to select cmd or data. NOTE: This design restricts, for example,
+ * one one SPI display per SPI bus.
+ * cmd - true: select command; false: select data
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SPI_CMDDATA
+#ifdef CONFIG_GD32F4_SPI0
+int gd32_spi0cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI1
+int gd32_spi1cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI2
+int gd32_spi2cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI3
+int gd32_spi3cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI5
+int gd32_spi4cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_GD32F4_SPI5
+int gd32_spi5cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#endif /* CONFIG_SPI_CMDDATA */
+
+#endif /* defined(CONFIG_SPI) */
diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_userleds.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_userleds.c
new file mode 100644
index 0000000000..5ef2649b52
--- /dev/null
+++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_userleds.c
@@ -0,0 +1,149 @@
+/****************************************************************************
+ * boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_userleds.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <debug.h>
+
+#include <sys/param.h>
+
+#include <nuttx/board.h>
+#include <arch/board/board.h>
+
+#include "gd32f4xx_gpio.h"
+#include "gd32f470i_eval.h"
+
+#ifndef CONFIG_ARCH_LEDS
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* LED index */
+
+static const uint32_t g_led_map[BOARD_LEDS] =
+{
+ LED1,
+ LED2,
+ LED3
+};
+
+static const uint32_t g_led_setmap[BOARD_LEDS] =
+{
+ BOARD_LED1_BIT,
+ BOARD_LED2_BIT,
+ BOARD_LED3_BIT
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Turn on selected led */
+
+static void gd32_eval_led_on(led_typedef_enum led_num)
+{
+ gd32_gpio_write(g_led_map[led_num], true);
+}
+
+/* Turn off selected led */
+
+static void gd32_eval_led_off(led_typedef_enum led_num)
+{
+ gd32_gpio_write(g_led_map[led_num], false);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_userled_initialize
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
+ * LEDs. If CONFIG_ARCH_LEDS is not defined, then the
+ * board_userled_initialize() is available to initialize the LED from user
+ * application logic.
+ *
+ ****************************************************************************/
+
+uint32_t board_userled_initialize(void)
+{
+ int i;
+
+ /* Configure the LED GPIO for output. */
+
+ for (i = 0; i < nitems(g_led_map); i++)
+ {
+ gd32_gpio_config(g_led_map[i]);
+ }
+
+ return BOARD_LEDS;
+}
+
+/****************************************************************************
+ * Name: board_userled
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
+ * LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled() is
+ * available to control the LED from user application logic.
+ *
+ ****************************************************************************/
+
+void board_userled(int led, bool ledon)
+{
+ if ((unsigned)led < nitems(g_led_map))
+ {
+ gd32_gpio_write(g_led_map[led], ledon);
+ }
+}
+
+/****************************************************************************
+ * Name: board_userled_all
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
+ * LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled_all()
+ * is available to control the LED from user application logic.
+ * NOTE: since there is only a single LED on-board, this is function
+ * is not very useful.
+ *
+ ****************************************************************************/
+
+void board_userled_all(uint32_t ledset)
+{
+ int i;
+
+ /* Configure LED1-3 GPIOs for output */
+
+ for (i = 0; i < nitems(g_led_map); i++)
+ {
+ gd32_gpio_write(g_led_map[i], (ledset & g_led_setmap[i]) != 0);
+ }
+}
+
+#endif /* !CONFIG_ARCH_LEDS */