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 */