Sfoglia il codice sorgente

[bsp][gd32e230k-start] Add GD32E230K-START BSP port

xuzhuoyi 6 anni fa
parent
commit
5d166c389d
76 ha cambiato i file con 25580 aggiunte e 0 eliminazioni
  1. 288 0
      bsp/gd32e230k-start/.config
  2. 72 0
      bsp/gd32e230k-start/Kconfig
  3. 212 0
      bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h
  4. 58 0
      bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h
  5. 256 0
      bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s
  6. 303 0
      bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s
  7. 371 0
      bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c
  8. 351 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h
  9. 162 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h
  10. 120 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h
  11. 123 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h
  12. 264 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h
  13. 278 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h
  14. 272 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h
  15. 119 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h
  16. 388 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h
  17. 389 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h
  18. 86 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h
  19. 146 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h
  20. 672 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h
  21. 561 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h
  22. 424 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h
  23. 187 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h
  24. 760 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h
  25. 614 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h
  26. 88 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h
  27. 844 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c
  28. 180 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c
  29. 206 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c
  30. 140 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c
  31. 562 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c
  32. 254 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c
  33. 814 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c
  34. 252 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c
  35. 399 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c
  36. 797 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c
  37. 142 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c
  38. 301 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c
  39. 1034 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c
  40. 965 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c
  41. 1003 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c
  42. 207 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c
  43. 2059 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c
  44. 1318 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c
  45. 148 0
      bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c
  46. 33 0
      bsp/gd32e230k-start/Libraries/SConscript
  47. 14 0
      bsp/gd32e230k-start/SConscript
  48. 39 0
      bsp/gd32e230k-start/SConstruct
  49. 11 0
      bsp/gd32e230k-start/applications/SConscript
  50. 27 0
      bsp/gd32e230k-start/applications/main.c
  51. 33 0
      bsp/gd32e230k-start/drivers/SConscript
  52. 87 0
      bsp/gd32e230k-start/drivers/board.c
  53. 47 0
      bsp/gd32e230k-start/drivers/board.h
  54. 539 0
      bsp/gd32e230k-start/drivers/drv_gpio.c
  55. 18 0
      bsp/gd32e230k-start/drivers/drv_gpio.h
  56. 381 0
      bsp/gd32e230k-start/drivers/drv_i2c.c
  57. 29 0
      bsp/gd32e230k-start/drivers/drv_i2c.h
  58. 290 0
      bsp/gd32e230k-start/drivers/drv_spi.c
  59. 19 0
      bsp/gd32e230k-start/drivers/drv_spi.h
  60. 381 0
      bsp/gd32e230k-start/drivers/drv_usart.c
  61. 19 0
      bsp/gd32e230k-start/drivers/drv_usart.h
  62. 60 0
      bsp/gd32e230k-start/drivers/gd32e230_libopt.h
  63. 40 0
      bsp/gd32e230k-start/gd32_rom.icf
  64. 142 0
      bsp/gd32e230k-start/gd32_rom.ld
  65. 15 0
      bsp/gd32e230k-start/gd32_rom.sct
  66. 1301 0
      bsp/gd32e230k-start/project.uvoptx
  67. 952 0
      bsp/gd32e230k-start/project.uvprojx
  68. 158 0
      bsp/gd32e230k-start/rtconfig.h
  69. 126 0
      bsp/gd32e230k-start/rtconfig.py
  70. 185 0
      bsp/gd32e230k-start/template.uvoptx
  71. 400 0
      bsp/gd32e230k-start/template.uvprojx
  72. 23 0
      libcpu/arm/cortex-m23/SConscript
  73. 210 0
      libcpu/arm/cortex-m23/context_gcc.S
  74. 202 0
      libcpu/arm/cortex-m23/context_iar.S
  75. 207 0
      libcpu/arm/cortex-m23/context_rvds.S
  76. 403 0
      libcpu/arm/cortex-m23/cpuport.c

+ 288 - 0
bsp/gd32e230k-start/.config

@@ -0,0 +1,288 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_DEBUG=y
+CONFIG_RT_DEBUG_COLOR=y
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_DEBUG_INIT=0
+CONFIG_RT_DEBUG_THREAD=0
+CONFIG_RT_USING_HOOK=y
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+# CONFIG_RT_USING_TIMER_SOFT is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+CONFIG_RT_USING_MEMPOOL=y
+# CONFIG_RT_USING_MEMHEAP is not set
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+
+#
+# C++ features
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
+CONFIG_DFS_FD_MAX=4
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+CONFIG_RT_DFS_ELM_USE_LFN_0=y
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+CONFIG_RT_DFS_ELM_USE_LFN=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_NET is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+# CONFIG_RT_USING_DFS_JFFS2 is not set
+# CONFIG_RT_USING_DFS_NFS is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_SERIAL_USING_DMA=y
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+CONFIG_RT_USING_I2C=y
+# CONFIG_RT_USING_I2C_BITOPS is not set
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_RTC is not set
+# CONFIG_RT_USING_SDIO is not set
+CONFIG_RT_USING_SPI=y
+# CONFIG_RT_USING_SPI_MSD is not set
+CONFIG_RT_USING_SFUD=y
+# CONFIG_RT_SFUD_USING_SFDP is not set
+CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y
+# CONFIG_RT_SFUD_DEBUG is not set
+# CONFIG_RT_USING_W25QXX is not set
+# CONFIG_RT_USING_GD is not set
+# CONFIG_RT_USING_ENC28J60 is not set
+# CONFIG_RT_USING_SPI_WIFI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+# CONFIG_RT_USING_PTHREADS is not set
+# CONFIG_RT_USING_POSIX is not set
+# CONFIG_HAVE_SYS_SIGNALS is not set
+
+#
+# Network stack
+#
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+# CONFIG_RT_USING_LWIP141 is not set
+# CONFIG_RT_USING_LWIP202 is not set
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# system packages
+#
+
+#
+# RT-Thread GUI Engine
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_ONENET is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_IPERF is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_SAMPLES is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+CONFIG_RT_USING_USART0=y
+CONFIG_RT_USING_USART1=y
+# CONFIG_RT_USING_USART2 is not set
+# CONFIG_RT_USING_UART3 is not set
+# CONFIG_RT_USING_UART4 is not set
+CONFIG_RT_USING_SPI0=y
+CONFIG_RT_USING_SPI1=y
+# CONFIG_RT_USING_SPI2 is not set
+CONFIG_RT_USING_I2C0=y
+# CONFIG_RT_USING_I2C1 is not set

+ 72 - 0
bsp/gd32e230k-start/Kconfig

@@ -0,0 +1,72 @@
+mainmenu "RT-Thread Configuration"
+
+config BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../.."
+
+config PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+
+config RT_USING_USART0
+    bool "Using USART0"
+    select RT_USING_SERIAL
+    default y
+    
+config RT_USING_USART1
+    bool "Using USART1"
+    select RT_USING_SERIAL
+    default n
+
+config RT_USING_USART2
+    bool "Using USART2"
+    select RT_USING_SERIAL
+    default n
+
+config RT_USING_UART3
+    bool "Using UART3"
+    select RT_USING_SERIAL
+    default n
+    
+config RT_USING_UART4
+    bool "Using UART4"
+    select RT_USING_SERIAL
+    default n
+
+config RT_USING_SPI0
+    bool "Using SPI0"
+    select RT_USING_SPI
+    default y 
+
+config RT_USING_SPI1
+    bool "Using SPI1"
+    select RT_USING_SPI
+    default n  
+
+config RT_USING_SPI2
+    bool "Using SPI2"
+    select RT_USING_SPI
+    default n 
+
+config RT_USING_I2C0
+    bool "Using I2C0"
+    select RT_USING_I2C
+    default n 
+
+config RT_USING_I2C1
+    bool "Using I2C1"
+    select RT_USING_I2C
+    default n  
+
+
+

+ 212 - 0
bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h

@@ -0,0 +1,212 @@
+/*!
+    \file    gd32e230.h
+    \brief   general definitions for GD32E230
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_H
+#define GD32E230_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* define GD32E230 */
+#if !defined (GD32E230)
+ #define GD32E230
+#endif /* define GD32E230 */
+#if !defined (GD32E230)
+ #error "Please select the target GD32E230 device used in your application (in gd32e230.h file)"
+#endif /* undefine GD32E230 tip */
+
+/* define value of high speed crystal oscillator (HXTAL) in Hz */
+#if !defined  (HXTAL_VALUE)
+#define HXTAL_VALUE    ((uint32_t)8000000)
+#endif /* high speed crystal oscillator value */
+
+/* define startup timeout value of high speed crystal oscillator (HXTAL) */
+#if !defined  (HXTAL_STARTUP_TIMEOUT)
+#define HXTAL_STARTUP_TIMEOUT   ((uint16_t)0x0800)
+#endif /* high speed crystal oscillator startup timeout */
+
+/* define value of internal 8MHz RC oscillator (IRC8M) in Hz */
+#if !defined  (IRC8M_VALUE) 
+#define IRC8M_VALUE  ((uint32_t)8000000)
+#endif /* internal 8MHz RC oscillator value */
+
+/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */
+#if !defined  (IRC8M_STARTUP_TIMEOUT)
+#define IRC8M_STARTUP_TIMEOUT   ((uint16_t)0x0500)
+#endif /* internal 8MHz RC oscillator startup timeout */
+
+/* define value of internal RC oscillator for ADC in Hz */
+#if !defined  (IRC28M_VALUE) 
+#define IRC28M_VALUE ((uint32_t)28000000)
+#endif /* IRC28M_VALUE */
+
+#if !defined  (IRC48M_VALUE) 
+#define IRC48M_VALUE ((uint32_t)48000000)
+#endif /* IRC48M_VALUE */
+
+/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */
+#if !defined  (IRC40K_VALUE) 
+#define IRC40K_VALUE  ((uint32_t)40000)
+#endif /* internal 40KHz RC oscillator value */
+
+/* define value of low speed crystal oscillator (LXTAL)in Hz */
+#if !defined  (LXTAL_VALUE) 
+#define LXTAL_VALUE  ((uint32_t)32768)
+#endif /* low speed crystal oscillator value */
+
+/* GD32E1x0 firmware library version number V1.0 */
+#define __GD32E230_STDPERIPH_VERSION_MAIN   (0x01) /*!< [31:24] main version     */
+#define __GD32E230_STDPERIPH_VERSION_SUB1   (0x00) /*!< [23:16] sub1 version     */
+#define __GD32E230_STDPERIPH_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version     */
+#define __GD32E230_STDPERIPH_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
+#define __GD32E230_STDPERIPH_VERSION        ((__GD32E230_STDPERIPH_VERSION_MAIN << 24)\
+                                            |(__GD32E230_STDPERIPH_VERSION_SUB1 << 16)\
+                                            |(__GD32E230_STDPERIPH_VERSION_SUB2 << 8)\
+                                            |(__GD32E230_STDPERIPH_VERSION_RC))
+
+/* configuration of the Cortex-M23 processor and core peripherals                                        */
+#define __CM23_REV                0x0100U   /*!< Core revision r1p0                                      */
+#define __SAUREGION_PRESENT       0U        /*!< SAU regions are not present                             */
+#define __MPU_PRESENT             0U        /*!< MPU is present                                          */
+#define __VTOR_PRESENT            1U        /*!< VTOR is present                                         */
+#define __NVIC_PRIO_BITS          2U        /*!< Number of Bits used for Priority Levels                 */
+#define __Vendor_SysTickConfig    0U        /*!< Set to 1 if different SysTick Config is used            */
+
+/* define interrupt number */
+typedef enum IRQn
+{
+    /* Cortex-M23 processor exceptions numbers */
+    NonMaskableInt_IRQn          = -14,    /*!< non maskable interrupt                                   */
+    HardFault_IRQn               = -13,    /*!< hardfault interrupt                                      */
+
+    SVCall_IRQn                  = -5,     /*!< sv call interrupt                                        */
+
+    PendSV_IRQn                  = -2,     /*!< pend sv interrupt                                        */
+    SysTick_IRQn                 = -1,     /*!< system tick interrupt                                    */
+    /* interruput numbers */
+    WWDGT_IRQn                   = 0,      /*!< window watchdog timer interrupt                          */
+    LVD_IRQn                     = 1,      /*!< LVD through EXTI line detect interrupt                   */
+    RTC_IRQn                     = 2,      /*!< RTC through EXTI line interrupt                          */
+    FMC_IRQn                     = 3,      /*!< FMC interrupt                                            */
+    RCU_IRQn                     = 4,      /*!< RCU interrupt                                            */
+    EXTI0_1_IRQn                 = 5,      /*!< EXTI line 0 and 1 interrupts                             */
+    EXTI2_3_IRQn                 = 6,      /*!< EXTI line 2 and 3 interrupts                             */
+    EXTI4_15_IRQn                = 7,      /*!< EXTI line 4 to 15 interrupts                             */
+    DMA_Channel0_IRQn            = 9,      /*!< DMA channel 0 interrupt                                  */
+    DMA_Channel1_2_IRQn          = 10,     /*!< DMA channel 1 and channel 2 interrupts                   */
+    DMA_Channel3_4_IRQn          = 11,     /*!< DMA channel 3 and channel 4 interrupts                   */
+    ADC_CMP_IRQn                 = 12,     /*!< ADC, CMP interrupts                            */
+    TIMER0_BRK_UP_TRG_COM_IRQn   = 13,     /*!< TIMER0 break, update, trigger and commutation interrupts */
+    TIMER0_Channel_IRQn          = 14,     /*!< TIMER0 channel capture compare interrupts                */
+    TIMER2_IRQn                  = 16,     /*!< TIMER2 interrupt                                         */
+    TIMER5_IRQn                  = 17,     /*!< TIMER5 interrupt                                         */
+    TIMER13_IRQn                 = 19,     /*!< TIMER13 interrupt                                        */
+    TIMER14_IRQn                 = 20,     /*!< TIMER14 interrupt                                        */
+    TIMER15_IRQn                 = 21,     /*!< TIMER15 interrupt                                        */
+    TIMER16_IRQn                 = 22,     /*!< TIMER16 interrupt                                        */
+    I2C0_EV_IRQn                 = 23,     /*!< I2C0 event interrupt                                     */
+    I2C1_EV_IRQn                 = 24,     /*!< I2C1 event interrupt                                     */
+    SPI0_IRQn                    = 25,     /*!< SPI0 interrupt                                           */
+    SPI1_IRQn                    = 26,     /*!< SPI1 interrupt                                           */
+    USART0_IRQn                  = 27,     /*!< USART0 interrupt                                         */
+    USART1_IRQn                  = 28,     /*!< USART1 interrupt                                         */
+    I2C0_ER_IRQn                 = 32,     /*!< I2C0 error interrupt                                     */
+    I2C1_ER_IRQn                 = 34,     /*!< I2C1 error interrupt                                     */
+} IRQn_Type;
+
+/* includes */
+#include "core_cm23.h"
+#include "system_gd32e230.h"
+#include <stdint.h>
+
+/* enum definitions */
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
+typedef enum {RESET = 0, SET = !RESET} FlagStatus;
+typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus;
+
+/* bit operations */
+#define REG32(addr)                  (*(volatile uint32_t *)(uint32_t)(addr))
+#define REG16(addr)                  (*(volatile uint16_t *)(uint32_t)(addr))
+#define REG8(addr)                   (*(volatile uint8_t *)(uint32_t)(addr))
+#define BIT(x)                       ((uint32_t)((uint32_t)0x01U<<(x)))
+#define BITS(start, end)             ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) 
+#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start))
+
+/* main flash and SRAM memory map */
+#define FLASH_BASE            ((uint32_t)0x08000000U)       /*!< main FLASH base address          */
+#define SRAM_BASE             ((uint32_t)0x20000000U)       /*!< SRAM base address                */
+/* SRAM and peripheral base bit-band region */
+#define SRAM_BB_BASE          ((uint32_t)0x22000000U)       /*!< SRAM bit-band base address       */
+#define PERIPH_BB_BASE        ((uint32_t)0x42000000U)       /*!< peripheral bit-band base address */
+/* peripheral memory map */
+#define APB1_BUS_BASE         ((uint32_t)0x40000000U)       /*!< apb1 base address                */
+#define APB2_BUS_BASE         ((uint32_t)0x40010000U)       /*!< apb2 base address                */
+#define AHB1_BUS_BASE         ((uint32_t)0x40020000U)       /*!< ahb1 base address                */
+#define AHB2_BUS_BASE         ((uint32_t)0x48000000U)       /*!< ahb2 base address                */
+/* advanced peripheral bus 1 memory map */
+#define TIMER_BASE            (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address               */
+#define RTC_BASE              (APB1_BUS_BASE + 0x00002800U) /*!< RTC base address                 */
+#define WWDGT_BASE            (APB1_BUS_BASE + 0x00002C00U) /*!< WWDGT base address               */
+#define FWDGT_BASE            (APB1_BUS_BASE + 0x00003000U) /*!< FWDGT base address               */
+#define SPI_BASE              (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address                 */
+#define USART_BASE            (APB1_BUS_BASE + 0x00004400U) /*!< USART base address               */
+#define I2C_BASE              (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address                 */
+#define PMU_BASE              (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address                 */
+/* advanced peripheral bus 2 memory map */
+#define SYSCFG_BASE           (APB2_BUS_BASE + 0x00000000U) /*!< SYSCFG base address              */
+#define CMP_BASE              (APB2_BUS_BASE + 0x0000001CU) /*!< CMP base address                 */
+#define EXTI_BASE             (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address                */
+#define ADC_BASE              (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address                 */
+/* advanced high performance bus 1 memory map */
+#define DMA_BASE              (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address                 */
+#define DMA_CHANNEL_BASE      (DMA_BASE + 0x00000008U)      /*!< DMA channel base address         */
+#define RCU_BASE              (AHB1_BUS_BASE + 0x00001000U) /*!< RCU base address                 */
+#define FMC_BASE              (AHB1_BUS_BASE + 0x00002000U) /*!< FMC base address                 */
+#define CRC_BASE              (AHB1_BUS_BASE + 0x00003000U) /*!< CRC base address                 */
+/* advanced high performance bus 2 memory map */
+#define GPIO_BASE             (AHB2_BUS_BASE + 0x00000000U) /*!< GPIO base address                */
+/* option byte and debug memory map */
+#define OB_BASE               ((uint32_t)0x1FFFF800U)       /*!< OB base address                  */
+#define DBG_BASE              ((uint32_t)0x40015800U)       /*!< DBG base address                 */
+
+#include "gd32e230_libopt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GD32E230_H */

+ 58 - 0
bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h

@@ -0,0 +1,58 @@
+/*!
+    \file  system_gd32e230.h
+    \brief CMSIS Cortex-M23 Device Peripheral Access Layer Header File for
+           GD32E230 Device Series
+*/
+
+/* Copyright (c) 2012 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
+
+#ifndef SYSTEM_GD32E230_H
+#define SYSTEM_GD32E230_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/* system clock frequency (core clock) */
+extern uint32_t SystemCoreClock;
+
+/* function declarations */
+/* initialize the system and update the SystemCoreClock variable */
+extern void SystemInit (void);
+/* update the SystemCoreClock with current core clock retrieved from cpu registers */
+extern void SystemCoreClockUpdate (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_GD32E230_H */

+ 256 - 0
bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s

@@ -0,0 +1,256 @@
+;/*!
+;    \file    startup_gd32e230.s
+;    \brief   start up file
+;
+;    \version 2018-6-19, V1.0.0, firmware for GD32E230
+;*/
+;
+;/*
+;    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+;
+;    All rights reserved.
+;
+;    Redistribution and use in source and binary forms, with or without modification, 
+;are permitted provided that the following conditions are met:
+;
+;    1. Redistributions of source code must retain the above copyright notice, this 
+;       list of conditions and the following disclaimer.
+;    2. Redistributions in binary form must reproduce the above copyright notice, 
+;       this list of conditions and the following disclaimer in the documentation 
+;       and/or other materials provided with the distribution.
+;    3. Neither the name of the copyright holder nor the names of its contributors 
+;       may be used to endorse or promote products derived from this software without 
+;       specific prior written permission.
+;
+;    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+;IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+;INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+;WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+;ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+;OF SUCH DAMAGE.
+;*/
+
+; <h> Stack Configuration
+;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Stack_Size      EQU     0x00000400
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem       SPACE   Stack_Size
+__initial_sp
+
+
+; <h> Heap Configuration
+;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Heap_Size       EQU     0x00000400
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+                PRESERVE8
+                THUMB
+
+;               /* reset Vector Mapped to at Address 0 */
+                AREA    RESET, DATA, READONLY
+                EXPORT  __Vectors
+                EXPORT  __Vectors_End
+                EXPORT  __Vectors_Size
+
+__Vectors       DCD     __initial_sp                      ; Top of Stack
+                DCD     Reset_Handler                     ; Reset Handler
+                DCD     NMI_Handler                       ; NMI Handler
+                DCD     HardFault_Handler                 ; Hard Fault Handler
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     SVC_Handler                       ; SVCall Handler
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     PendSV_Handler                    ; PendSV Handler
+                DCD     SysTick_Handler                   ; SysTick Handler
+
+;               /* external interrupts handler */
+                DCD     WWDGT_IRQHandler                  ; 16:Window Watchdog Timer
+                DCD     LVD_IRQHandler                    ; 17:LVD through EXTI Line detect
+                DCD     RTC_IRQHandler                    ; 18:RTC through EXTI Line
+                DCD     FMC_IRQHandler                    ; 19:FMC
+                DCD     RCU_IRQHandler                    ; 20:RCU
+                DCD     EXTI0_1_IRQHandler                ; 21:EXTI Line 0 and EXTI Line 1
+                DCD     EXTI2_3_IRQHandler                ; 22:EXTI Line 2 and EXTI Line 3
+                DCD     EXTI4_15_IRQHandler               ; 23:EXTI Line 4 to EXTI Line 15
+                DCD     0                                 ; Reserved
+                DCD     DMA_Channel0_IRQHandler           ; 25:DMA Channel 0 
+                DCD     DMA_Channel1_2_IRQHandler         ; 26:DMA Channel 1 and DMA Channel 2
+                DCD     DMA_Channel3_4_IRQHandler         ; 27:DMA Channel 3 and DMA Channel 4
+                DCD     ADC_CMP_IRQHandler                ; 28:ADC and Comparator
+                DCD     TIMER0_BRK_UP_TRG_COM_IRQHandler  ; 29:TIMER0 Break,Update,Trigger and Commutation
+                DCD     TIMER0_Channel_IRQHandler         ; 30:TIMER0 Channel Capture Compare
+                DCD     0                                 ; Reserved
+                DCD     TIMER2_IRQHandler                 ; 32:TIMER2
+                DCD     TIMER5_IRQHandler                 ; 33:TIMER5
+                DCD     0                                 ; Reserved
+                DCD     TIMER13_IRQHandler                ; 35:TIMER13
+                DCD     TIMER14_IRQHandler                ; 36:TIMER14
+                DCD     TIMER15_IRQHandler                ; 37:TIMER15
+                DCD     TIMER16_IRQHandler                ; 38:TIMER16
+                DCD     I2C0_EV_IRQHandler                ; 39:I2C0 Event
+                DCD     I2C1_EV_IRQHandler                ; 40:I2C1 Event
+                DCD     SPI0_IRQHandler                   ; 41:SPI0
+                DCD     SPI1_IRQHandler                   ; 42:SPI1
+                DCD     USART0_IRQHandler                 ; 43:USART0
+                DCD     USART1_IRQHandler                 ; 44:USART1
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     0                                 ; Reserved
+                DCD     I2C0_ER_IRQHandler                ; 48:I2C0 Error
+                DCD     0                                 ; Reserved
+                DCD     I2C1_ER_IRQHandler                ; 50:I2C1 Error
+__Vectors_End
+
+__Vectors_Size  EQU     __Vectors_End - __Vectors
+
+                AREA    |.text|, CODE, READONLY
+
+;/* reset Handler */
+Reset_Handler   PROC
+                EXPORT  Reset_Handler                     [WEAK]
+                IMPORT  SystemInit
+                IMPORT  __main
+                LDR     R0, =SystemInit
+                BLX     R0
+                LDR     R0, =__main
+                BX      R0
+                ENDP
+
+;/* dummy Exception Handlers */
+NMI_Handler\
+                PROC
+                EXPORT  NMI_Handler                       [WEAK]
+                B       .
+                ENDP
+HardFault_Handler\
+                PROC
+                EXPORT  HardFault_Handler                 [WEAK]
+                B       .
+                ENDP
+SVC_Handler\
+                PROC
+                EXPORT  SVC_Handler                       [WEAK]
+                B       .
+                ENDP
+PendSV_Handler\
+                PROC
+                EXPORT  PendSV_Handler                    [WEAK]
+                B       .
+                ENDP
+SysTick_Handler\
+                PROC
+                EXPORT  SysTick_Handler                   [WEAK]
+                B       .
+                ENDP
+
+Default_Handler PROC
+;               /* external interrupts handler */
+                EXPORT  WWDGT_IRQHandler                  [WEAK]
+                EXPORT  LVD_IRQHandler                    [WEAK]
+                EXPORT  RTC_IRQHandler                    [WEAK]
+                EXPORT  FMC_IRQHandler                    [WEAK]
+                EXPORT  RCU_IRQHandler                    [WEAK]
+                EXPORT  EXTI0_1_IRQHandler                [WEAK]
+                EXPORT  EXTI2_3_IRQHandler                [WEAK]
+                EXPORT  EXTI4_15_IRQHandler               [WEAK]
+                EXPORT  DMA_Channel0_IRQHandler           [WEAK]
+                EXPORT  DMA_Channel1_2_IRQHandler         [WEAK]
+                EXPORT  DMA_Channel3_4_IRQHandler         [WEAK]
+                EXPORT  ADC_CMP_IRQHandler                [WEAK]
+                EXPORT  TIMER0_BRK_UP_TRG_COM_IRQHandler  [WEAK]
+                EXPORT  TIMER0_Channel_IRQHandler         [WEAK]
+                EXPORT  TIMER2_IRQHandler                 [WEAK]
+                EXPORT  TIMER5_IRQHandler                 [WEAK]
+                EXPORT  TIMER13_IRQHandler                [WEAK]
+                EXPORT  TIMER14_IRQHandler                [WEAK]
+                EXPORT  TIMER15_IRQHandler                [WEAK]
+                EXPORT  TIMER16_IRQHandler                [WEAK]
+                EXPORT  I2C0_EV_IRQHandler                [WEAK]
+                EXPORT  I2C1_EV_IRQHandler                [WEAK]
+                EXPORT  SPI0_IRQHandler                   [WEAK]
+                EXPORT  SPI1_IRQHandler                   [WEAK]
+                EXPORT  USART0_IRQHandler                 [WEAK]
+                EXPORT  USART1_IRQHandler                 [WEAK]
+                EXPORT  I2C0_ER_IRQHandler                [WEAK]
+                EXPORT  I2C1_ER_IRQHandler                [WEAK]
+
+;/* external interrupts handler */
+WWDGT_IRQHandler
+LVD_IRQHandler
+RTC_IRQHandler
+FMC_IRQHandler
+RCU_IRQHandler
+EXTI0_1_IRQHandler
+EXTI2_3_IRQHandler
+EXTI4_15_IRQHandler
+DMA_Channel0_IRQHandler
+DMA_Channel1_2_IRQHandler
+DMA_Channel3_4_IRQHandler
+ADC_CMP_IRQHandler
+TIMER0_BRK_UP_TRG_COM_IRQHandler
+TIMER0_Channel_IRQHandler
+TIMER2_IRQHandler
+TIMER5_IRQHandler
+TIMER13_IRQHandler
+TIMER14_IRQHandler
+TIMER15_IRQHandler
+TIMER16_IRQHandler
+I2C0_EV_IRQHandler
+I2C1_EV_IRQHandler
+SPI0_IRQHandler
+SPI1_IRQHandler
+USART0_IRQHandler
+USART1_IRQHandler
+I2C0_ER_IRQHandler
+I2C1_ER_IRQHandler
+
+                B       .
+                ENDP
+
+                ALIGN
+
+; user Initial Stack & Heap
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __initial_sp
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+
+__user_initial_stackheap PROC
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + Stack_Size)
+                LDR     R2, = (Heap_Mem +  Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDP
+
+                ALIGN
+
+                ENDIF
+
+                END

+ 303 - 0
bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s

@@ -0,0 +1,303 @@
+;/*!
+;    \file    startup_gd32e230.s
+;    \brief   start up file
+;
+;    \version 2018-06-19, V1.0.0, firmware for GD32E230
+;*/
+;
+;/*
+;    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+;
+;    All rights reserved.
+;
+;    Redistribution and use in source and binary forms, with or without modification, 
+;are permitted provided that the following conditions are met:
+;
+;    1. Redistributions of source code must retain the above copyright notice, this 
+;       list of conditions and the following disclaimer.
+;    2. Redistributions in binary form must reproduce the above copyright notice, 
+;       this list of conditions and the following disclaimer in the documentation 
+;       and/or other materials provided with the distribution.
+;    3. Neither the name of the copyright holder nor the names of its contributors 
+;       may be used to endorse or promote products derived from this software without 
+;       specific prior written permission.
+;
+;    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+;IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+;INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+;WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+;ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+;OF SUCH DAMAGE.
+;*/
+
+        MODULE  ?cstartup
+
+        ;; Forward declaration of sections.
+        SECTION CSTACK:DATA:NOROOT(3)
+
+        SECTION .intvec:CODE:NOROOT(2)
+
+        EXTERN  __iar_program_start
+        EXTERN  SystemInit
+        PUBLIC  __vector_table
+
+        DATA
+__vector_table
+        DCD     sfe(CSTACK)                         ; top of stack
+        DCD     Reset_Handler                       ; Vector Number 1,Reset Handler
+
+        DCD     NMI_Handler                         ; Vector Number 2,NMI Handler
+        DCD     HardFault_Handler                   ; Vector Number 3,Hard Fault Handler
+        DCD     MemManage_Handler                   ; Vector Number 4,MPU Fault Handler
+        DCD     BusFault_Handler                    ; Vector Number 5,Bus Fault Handler
+        DCD     UsageFault_Handler                  ; Vector Number 6,Usage Fault Handler
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     SVC_Handler                         ; Vector Number 11,SVCall Handler
+        DCD     DebugMon_Handler                    ; Vector Number 12,Debug Monitor Handler
+        DCD     0                                   ; Reserved
+        DCD     PendSV_Handler                      ; Vector Number 14,PendSV Handler
+        DCD     SysTick_Handler                     ; Vector Number 15,SysTick Handler
+
+        ; External Interrupts
+        DCD     WWDGT_IRQHandler                    ; 16:Window Watchdog Timer
+        DCD     LVD_IRQHandler                      ; 17:LVD through EXTI Line detect
+        DCD     RTC_IRQHandler                      ; 18:RTC through EXTI Line
+        DCD     FMC_IRQHandler                      ; 19:FMC
+        DCD     RCU_IRQHandler                      ; 20:RCU
+        DCD     EXTI0_1_IRQHandler                  ; 21:EXTI Line 0 and EXTI Line 1
+        DCD     EXTI2_3_IRQHandler                  ; 22:EXTI Line 2 and EXTI Line 3
+        DCD     EXTI4_15_IRQHandler                 ; 23:EXTI Line 4 to EXTI Line 15
+        DCD     0                                   ; Reserved
+        DCD     DMA_Channel0_IRQHandler             ; 25:DMA Channel 0 
+        DCD     DMA_Channel1_2_IRQHandler           ; 26:DMA Channel 1 and DMA Channel 2
+        DCD     DMA_Channel3_4_IRQHandler           ; 27:DMA Channel 3 and DMA Channel 4
+        DCD     ADC_CMP_IRQHandler                  ; 28:ADC and Comparator
+        DCD     TIMER0_BRK_UP_TRG_COM_IRQHandler    ; 29:TIMER0 Break,Update,Trigger and Commutation
+        DCD     TIMER0_Channel_IRQHandler           ; 30:TIMER0 Channel Capture Compare
+        DCD     0                                   ; Reserved
+        DCD     TIMER2_IRQHandler                   ; 32:TIMER2
+        DCD     TIMER5_IRQHandler                   ; 33:TIMER5
+        DCD     0                                   ; Reserved
+        DCD     TIMER13_IRQHandler                  ; 35:TIMER13
+        DCD     TIMER14_IRQHandler                  ; 36:TIMER14
+        DCD     TIMER15_IRQHandler                  ; 37:TIMER15
+        DCD     TIMER16_IRQHandler                  ; 38:TIMER16
+        DCD     I2C0_EV_IRQHandler                  ; 39:I2C0 Event
+        DCD     I2C1_EV_IRQHandler                  ; 40:I2C1 Event
+        DCD     SPI0_IRQHandler                     ; 41:SPI0
+        DCD     SPI1_IRQHandler                     ; 42:SPI1
+        DCD     USART0_IRQHandler                   ; 43:USART0
+        DCD     USART1_IRQHandler                   ; 44:USART1
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     0                                   ; Reserved
+        DCD     I2C0_ER_IRQHandler                  ; 48:I2C0 Error
+        DCD     0                                   ; Reserved
+        DCD     I2C1_ER_IRQHandler                  ; 50:I2C1 Error
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+        THUMB
+
+        PUBWEAK Reset_Handler
+        SECTION .text:CODE:NOROOT:REORDER(2)
+Reset_Handler
+        LDR     R0, =SystemInit
+        BLX     R0
+        LDR     R0, =__iar_program_start
+        BX      R0
+        
+        PUBWEAK NMI_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+NMI_Handler
+        B NMI_Handler
+       
+        PUBWEAK HardFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+HardFault_Handler
+        B HardFault_Handler
+       
+        PUBWEAK MemManage_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+MemManage_Handler
+        B MemManage_Handler
+
+        PUBWEAK BusFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+BusFault_Handler
+        B BusFault_Handler
+
+        PUBWEAK UsageFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UsageFault_Handler
+        B UsageFault_Handler
+        
+        PUBWEAK SVC_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SVC_Handler
+        B SVC_Handler
+       
+        PUBWEAK DebugMon_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DebugMon_Handler
+        B DebugMon_Handler
+        
+        PUBWEAK PendSV_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+PendSV_Handler
+        B PendSV_Handler
+        
+        PUBWEAK SysTick_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SysTick_Handler
+        B SysTick_Handler
+        
+        PUBWEAK WWDGT_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+WWDGT_IRQHandler
+        B WWDGT_IRQHandler
+        
+        PUBWEAK LVD_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+LVD_IRQHandler
+        B LVD_IRQHandler
+        
+        PUBWEAK RTC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+RTC_IRQHandler
+        B RTC_IRQHandler
+        
+        PUBWEAK FMC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+FMC_IRQHandler
+        B FMC_IRQHandler
+        
+        PUBWEAK RCU_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+RCU_IRQHandler
+        B RCU_IRQHandler
+        
+        PUBWEAK EXTI0_1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI0_1_IRQHandler
+        B EXTI0_1_IRQHandler
+        
+        PUBWEAK EXTI2_3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI2_3_IRQHandler
+        B EXTI2_3_IRQHandler
+        
+        PUBWEAK EXTI4_15_IRQHandler                  
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI4_15_IRQHandler                  
+        B EXTI4_15_IRQHandler                  
+        
+        PUBWEAK DMA_Channel0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA_Channel0_IRQHandler
+        B DMA_Channel0_IRQHandler
+        
+        PUBWEAK DMA_Channel1_2_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA_Channel1_2_IRQHandler          
+        B DMA_Channel1_2_IRQHandler          
+        
+        PUBWEAK DMA_Channel3_4_IRQHandler          
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DMA_Channel3_4_IRQHandler          
+        B DMA_Channel3_4_IRQHandler                 
+        
+        PUBWEAK ADC_CMP_IRQHandler                    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+ADC_CMP_IRQHandler                    
+        B ADC_CMP_IRQHandler                    
+        
+        PUBWEAK TIMER0_BRK_UP_TRG_COM_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_BRK_UP_TRG_COM_IRQHandler                
+        B TIMER0_BRK_UP_TRG_COM_IRQHandler                
+        
+        PUBWEAK TIMER0_Channel_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER0_Channel_IRQHandler               
+        B TIMER0_Channel_IRQHandler               
+        
+        PUBWEAK TIMER2_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER2_IRQHandler               
+        B TIMER2_IRQHandler               
+      
+        PUBWEAK TIMER5_IRQHandler               
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER5_IRQHandler               
+        B TIMER5_IRQHandler               
+        
+        PUBWEAK TIMER13_IRQHandler                
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER13_IRQHandler                
+        B TIMER13_IRQHandler                
+        
+        PUBWEAK TIMER14_IRQHandler    
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER14_IRQHandler    
+        B TIMER14_IRQHandler    
+        
+        PUBWEAK TIMER15_IRQHandler   
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER15_IRQHandler   
+        B TIMER15_IRQHandler   
+        
+        PUBWEAK TIMER16_IRQHandler 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIMER16_IRQHandler 
+        B TIMER16_IRQHandler 
+        
+        PUBWEAK I2C0_EV_IRQHandler         
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C0_EV_IRQHandler         
+        B I2C0_EV_IRQHandler         
+        
+        PUBWEAK I2C1_EV_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C1_EV_IRQHandler                 
+        B I2C1_EV_IRQHandler                 
+        
+        PUBWEAK SPI0_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI0_IRQHandler
+        B SPI0_IRQHandler                 
+
+        PUBWEAK SPI1_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI1_IRQHandler                 
+        B SPI1_IRQHandler
+
+        PUBWEAK USART0_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART0_IRQHandler                 
+        B USART0_IRQHandler                 
+
+        PUBWEAK USART1_IRQHandler                 
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART1_IRQHandler                 
+        B USART1_IRQHandler                 
+        
+        PUBWEAK I2C0_ER_IRQHandler              
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C0_ER_IRQHandler              
+        B I2C0_ER_IRQHandler              
+
+        PUBWEAK I2C1_ER_IRQHandler             
+        SECTION .text:CODE:NOROOT:REORDER(1)
+I2C1_ER_IRQHandler             
+        B I2C1_ER_IRQHandler                      
+        END

+ 371 - 0
bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c

@@ -0,0 +1,371 @@
+/*!
+    \file  system_gd32e230.c
+    \brief CMSIS Cortex-M23 Device Peripheral Access Layer Source File for
+           GD32E1x0 Device Series
+*/
+
+/* Copyright (c) 2012 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
+
+#include "gd32e230.h"
+
+/* system frequency define */
+#define __IRC8M           (IRC8M_VALUE)            /* internal 8 MHz RC oscillator frequency */
+#define __HXTAL           (HXTAL_VALUE)            /* high speed crystal oscillator frequency */
+#define __SYS_OSC_CLK     (__IRC8M)                /* main oscillator frequency */
+
+#define VECT_TAB_OFFSET  (uint32_t)0x00            /* vector table base offset */
+
+/* select a system clock by uncommenting the following line */
+//#define __SYSTEM_CLOCK_8M_HXTAL              (__HXTAL)
+//#define __SYSTEM_CLOCK_8M_IRC8M              (__IRC8M)
+#define __SYSTEM_CLOCK_72M_PLL_HXTAL         (uint32_t)(72000000)
+//#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2    (uint32_t)(72000000)
+
+#define SEL_IRC8M       0x00
+#define SEL_HXTAL       0x01
+#define SEL_PLL         0x02
+
+/* set the system clock frequency and declare the system clock configuration function */
+#ifdef __SYSTEM_CLOCK_8M_HXTAL
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_HXTAL;
+static void system_clock_8m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL;
+static void system_clock_72m_hxtal(void);
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2)
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2;
+static void system_clock_72m_irc8m(void);
+
+#else
+uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_IRC8M;
+static void system_clock_8m_irc8m(void);
+#endif /* __SYSTEM_CLOCK_8M_HXTAL */
+
+/* configure the system clock */
+static void system_clock_config(void);
+
+/*!
+    \brief      setup the microcontroller system, initialize the system
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void SystemInit (void)
+{
+    /* enable IRC8M */
+    RCU_CTL0 |= RCU_CTL0_IRC8MEN;
+    while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){
+    }
+    /* reset RCU */
+    RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\
+                  RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV);
+    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+    RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS);
+    RCU_CFG1 &= ~(RCU_CFG1_PREDV);
+    RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL);
+    RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
+    RCU_CFG2 &= ~RCU_CFG2_ADCPSC2;
+    RCU_CTL1 &= ~RCU_CTL1_IRC28MEN;
+    RCU_INT = 0x00000000U;
+
+    /* configure system clock */
+    system_clock_config();
+    
+#ifdef VECT_TAB_SRAM
+    nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET);
+#else
+    nvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET);
+#endif
+}
+
+/*!
+    \brief      configure the system clock
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_config(void)
+{
+#ifdef __SYSTEM_CLOCK_8M_HXTAL
+    system_clock_8m_hxtal();
+#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
+    system_clock_72m_hxtal();
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2)
+    system_clock_72m_irc8m();
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2)
+    system_clock_72m_irc48m();
+#else
+    system_clock_8m_irc8m();
+#endif /* __SYSTEM_CLOCK_8M_HXTAL */
+}
+
+#ifdef __SYSTEM_CLOCK_8M_HXTAL
+/*!
+    \brief      configure the system clock to 8M by HXTAL
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_8m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+
+    /* enable HXTAL */
+    RCU_CTL0 |= RCU_CTL0_HXTALEN;
+    
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));    
+    /* if fail */
+    if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){
+        while(1){
+        }
+    }
+    
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
+    
+    /* select HXTAL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
+    
+    /* wait until HXTAL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_HXTAL)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
+/*!
+    \brief      configure the system clock to 72M by PLL which selects HXTAL as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_72m_hxtal(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+
+    /* enable HXTAL */
+    RCU_CTL0 |= RCU_CTL0_HXTALEN;
+
+    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB);
+    }
+    while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
+    /* if fail */
+    if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){
+        while(1){
+        }
+    }
+    
+    FMC_WS &= ~FMC_WS_WSCNT;
+    FMC_WS |= WS_WSCNT_2;
+    
+    /* HXTAL is stable */
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
+
+    /* PLL = HXTAL * 9 = 72 MHz */
+    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV);
+    RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9);
+
+    /* enable PLL */
+    RCU_CTL0 |= RCU_CTL0_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){
+    }
+
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
+    }
+}
+
+#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2)
+/*!
+    \brief      configure the system clock to 72M by PLL which selects IRC8M/2 as its clock source
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_72m_irc8m(void)
+{
+    uint32_t timeout = 0U;
+    uint32_t stab_flag = 0U;
+    
+    /* enable IRC8M */
+    RCU_CTL0 |= RCU_CTL0_IRC8MEN;
+
+    /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
+    do{
+        timeout++;
+        stab_flag = (RCU_CTL0 & RCU_CTL0_IRC8MSTB);
+    }
+    while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
+
+    /* if fail */
+    if(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){
+        while(1){
+        }
+    }
+
+    FMC_WS &= ~FMC_WS_WSCNT;
+    FMC_WS |= WS_WSCNT_2;
+    
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
+    /* PLL = (IRC8M/2) * 18 = 72 MHz */
+    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+    RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18);
+    
+    /* enable PLL */
+    RCU_CTL0 |= RCU_CTL0_PLLEN;
+
+    /* wait until PLL is stable */
+    while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){
+    }
+
+    /* select PLL as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_PLL;
+
+    /* wait until PLL is selected as system clock */
+    while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
+    }
+}
+
+#else
+/*!
+    \brief      configure the system clock to 8M by IRC8M
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+static void system_clock_8m_irc8m(void)
+{
+    /* AHB = SYSCLK */
+    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
+    /* APB2 = AHB */
+    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
+    /* APB1 = AHB */
+    RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
+    
+    /* select IRC8M as system clock */
+    RCU_CFG0 &= ~RCU_CFG0_SCS;
+    RCU_CFG0 |= RCU_CKSYSSRC_IRC8M;
+    
+    /* wait until IRC8M is selected as system clock */
+    while(0U != (RCU_CFG0 & RCU_SCSS_IRC8M)){
+    }
+}
+#endif /* __SYSTEM_CLOCK_8M_HXTAL */
+
+/*!
+    \brief      update the SystemCoreClock with current core clock retrieved from cpu registers
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void SystemCoreClockUpdate (void)
+{
+    uint32_t sws = 0U;
+    uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U;
+    /* exponent of AHB clock divider */
+    const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+    sws = GET_BITS(RCU_CFG0, 2, 3);
+    switch(sws){
+    /* IRC8M is selected as CK_SYS */
+    case SEL_IRC8M:
+        SystemCoreClock = IRC8M_VALUE;
+        break;
+    /* HXTAL is selected as CK_SYS */
+    case SEL_HXTAL:
+        SystemCoreClock = HXTAL_VALUE;
+        break;
+    /* PLL is selected as CK_SYS */
+    case SEL_PLL:
+        /* get the value of PLLMF[3:0] */
+        pllmf = GET_BITS(RCU_CFG0, 18, 21);
+        pllmf4 = GET_BITS(RCU_CFG0, 27, 27);
+        /* high 16 bits */
+        if(1U == pllmf4){
+            pllmf += 17U;
+        }else if(15U == pllmf){
+            pllmf = 16U;
+        }else{
+            pllmf += 2U;
+        }
+        
+        /* PLL clock source selection, HXTAL or IRC8M/2 */
+        pllsel = GET_BITS(RCU_CFG0, 16, 16);
+        if(0U != pllsel){
+            prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U);
+            SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf;
+        }else{
+            SystemCoreClock = (IRC8M_VALUE >> 1) * pllmf;
+        }
+        break;
+    /* IRC8M is selected as CK_SYS */
+    default:
+        SystemCoreClock = IRC8M_VALUE;
+        break;
+    }
+    /* calculate AHB clock frequency */
+    idx = GET_BITS(RCU_CFG0, 4, 7);
+    clk_exp = ahb_exp[idx];
+    SystemCoreClock >>= clk_exp;
+}

+ 351 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h

@@ -0,0 +1,351 @@
+/*!
+    \file  gd32e230_adc.h
+    \brief definitions for the ADC
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_ADC_H
+#define GD32E230_ADC_H
+
+#include "gd32e230.h"
+
+/* ADC definitions */
+#define ADC                              ADC_BASE
+
+/* registers definitions */
+#define ADC_STAT                         REG32(ADC + 0x00U)               /*!< ADC status register */
+#define ADC_CTL0                         REG32(ADC + 0x04U)               /*!< ADC control register 0 */
+#define ADC_CTL1                         REG32(ADC + 0x08U)               /*!< ADC control register 1 */
+#define ADC_SAMPT0                       REG32(ADC + 0x0CU)               /*!< ADC sampling time register 0 */
+#define ADC_SAMPT1                       REG32(ADC + 0x10U)               /*!< ADC sampling time register 1 */
+#define ADC_IOFF0                        REG32(ADC + 0x14U)               /*!< ADC inserted channel data offset register 0 */
+#define ADC_IOFF1                        REG32(ADC + 0x18U)               /*!< ADC inserted channel data offset register 1 */
+#define ADC_IOFF2                        REG32(ADC + 0x1CU)               /*!< ADC inserted channel data offset register 2 */
+#define ADC_IOFF3                        REG32(ADC + 0x20U)               /*!< ADC inserted channel data offset register 3 */
+#define ADC_WDHT                         REG32(ADC + 0x24U)               /*!< ADC watchdog high threshold register */
+#define ADC_WDLT                         REG32(ADC + 0x28U)               /*!< ADC watchdog low threshold register */
+#define ADC_RSQ0                         REG32(ADC + 0x2CU)               /*!< ADC regular sequence register 0 */
+#define ADC_RSQ1                         REG32(ADC + 0x30U)               /*!< ADC regular sequence register 1 */
+#define ADC_RSQ2                         REG32(ADC + 0x34U)               /*!< ADC regular sequence register 2 */
+#define ADC_ISQ                          REG32(ADC + 0x38U)               /*!< ADC inserted sequence register */
+#define ADC_IDATA0                       REG32(ADC + 0x3CU)               /*!< ADC inserted data register 0 */
+#define ADC_IDATA1                       REG32(ADC + 0x40U)               /*!< ADC inserted data register 1 */
+#define ADC_IDATA2                       REG32(ADC + 0x44U)               /*!< ADC inserted data register 2 */
+#define ADC_IDATA3                       REG32(ADC + 0x48U)               /*!< ADC inserted data register 3 */
+#define ADC_RDATA                        REG32(ADC + 0x4CU)               /*!< ADC regular data register */
+#define ADC_OVSAMPCTL                    REG32(ADC + 0x80U)               /*!< ADC oversampling control register */
+
+/* bits definitions */
+/* ADC_STAT */
+#define ADC_STAT_WDE                     BIT(0)                           /*!< analog watchdog event flag */
+#define ADC_STAT_EOC                     BIT(1)                           /*!< end of conversion flag */
+#define ADC_STAT_EOIC                    BIT(2)                           /*!< inserted channel end of conversion flag */
+#define ADC_STAT_STIC                    BIT(3)                           /*!< inserted channel start flag */
+#define ADC_STAT_STRC                    BIT(4)                           /*!< regular channel start flag */
+
+/* ADC_CTL0 */
+#define ADC_CTL0_WDCHSEL                 BITS(0,4)                        /*!< analog watchdog channel select bits */
+#define ADC_CTL0_EOCIE                   BIT(5)                           /*!< interrupt enable for EOC */
+#define ADC_CTL0_WDEIE                   BIT(6)                           /*!< analog watchdog interrupt enable */
+#define ADC_CTL0_EOICIE                  BIT(7)                           /*!< interrupt enable for inserted channels */
+#define ADC_CTL0_SM                      BIT(8)                           /*!< scan mode */
+#define ADC_CTL0_WDSC                    BIT(9)                           /*!< when in scan mode, analog watchdog is effective on a single channel */
+#define ADC_CTL0_ICA                     BIT(10)                          /*!< automatic inserted group conversion */
+#define ADC_CTL0_DISRC                   BIT(11)                          /*!< discontinuous mode on regular channels */
+#define ADC_CTL0_DISIC                   BIT(12)                          /*!< discontinuous mode on inserted channels */
+#define ADC_CTL0_DISNUM                  BITS(13,15)                      /*!< discontinuous mode channel count */
+#define ADC_CTL0_IWDEN                   BIT(22)                          /*!< analog watchdog enable on inserted channels */
+#define ADC_CTL0_RWDEN                   BIT(23)                          /*!< analog watchdog enable on regular channels */
+#define ADC_CTL0_DRES                    BITS(24,25)                      /*!< ADC data resolution */
+
+/* ADC_CTL1 */
+#define ADC_CTL1_ADCON                   BIT(0)                           /*!< ADC converter on */
+#define ADC_CTL1_CTN                     BIT(1)                           /*!< continuous conversion */
+#define ADC_CTL1_CLB                     BIT(2)                           /*!< ADC calibration */
+#define ADC_CTL1_RSTCLB                  BIT(3)                           /*!< reset calibration */
+#define ADC_CTL1_DMA                     BIT(8)                           /*!< direct memory access mode */
+#define ADC_CTL1_DAL                     BIT(11)                          /*!< data alignment */
+#define ADC_CTL1_ETSIC                   BITS(12,14)                      /*!< external trigger select for inserted channel */
+#define ADC_CTL1_ETEIC                   BIT(15)                          /*!< external trigger enable for inserted channel */
+#define ADC_CTL1_ETSRC                   BITS(17,19)                      /*!< external trigger select for regular channel */
+#define ADC_CTL1_ETERC                   BIT(20)                          /*!< external trigger enable for regular channel */
+#define ADC_CTL1_SWICST                  BIT(21)                          /*!< start on inserted channel */
+#define ADC_CTL1_SWRCST                  BIT(22)                          /*!< start on regular channel */
+#define ADC_CTL1_TSVREN                  BIT(23)                          /*!< enable channel 16 and 17 */
+
+/* ADC_SAMPTx x=0,1 */
+#define ADC_SAMPTX_SPTN                  BITS(0,2)                        /*!< channel n(n=0..9,16 and 17) sample time selection */
+
+/* ADC_IOFFx x=0..3 */
+#define ADC_IOFFX_IOFF                   BITS(0,11)                       /*!< data offset for inserted channel x */
+
+/* ADC_WDHT */
+#define ADC_WDHT_WDHT                    BITS(0,11)                       /*!< analog watchdog high threshold */
+
+/* ADC_WDLT */
+#define ADC_WDLT_WDLT                    BITS(0,11)                       /*!< analog watchdog low threshold */
+
+/* ADC_RSQx x=0..2 */
+#define ADC_RSQX_RSQN                    BITS(0,4)                        /*!< n conversion in regular sequence */
+#define ADC_RSQ0_RL                      BITS(20,23)                      /*!< regular channel sequence length */
+
+/* ADC_ISQ */
+#define ADC_ISQ_ISQN                     BITS(0,4)                        /*!< n conversion in regular sequence */
+#define ADC_ISQ_IL                       BITS(20,21)                      /*!< inserted sequence length */
+
+/* ADC_IDATAx x=0..3*/
+#define ADC_IDATAX_IDATAN                BITS(0,15)                       /*!< inserted channel x conversion data  */
+
+/* ADC_RDATA */
+#define ADC_RDATA_RDATA                  BITS(0,15)                       /*!< regular channel data */
+
+/* ADC_OVSAMPCTL */
+#define ADC_OVSAMPCTL_OVSEN              BIT(0)                           /*!< oversampling enable */
+#define ADC_OVSAMPCTL_OVSR               BITS(2,4)                        /*!< oversampling ratio */
+#define ADC_OVSAMPCTL_OVSS               BITS(5,8)                        /*!< oversampling shift */
+#define ADC_OVSAMPCTL_TOVS               BIT(9)                           /*!< triggered oversampling */
+
+/* constants definitions */
+/* ADC flag definitions */
+#define ADC_FLAG_WDE                     ADC_STAT_WDE                                /*!< analog watchdog event flag */
+#define ADC_FLAG_EOC                     ADC_STAT_EOC                                /*!< end of group conversion flag */
+#define ADC_FLAG_EOIC                    ADC_STAT_EOIC                               /*!< end of inserted channel group conversion flag */
+#define ADC_FLAG_STIC                    ADC_STAT_STIC                               /*!< start flag of inserted channel group */
+#define ADC_FLAG_STRC                    ADC_STAT_STRC                               /*!< start flag of regular channel group */
+
+/* adc_ctl0 register value */
+#define CTL0_DISNUM(regval)              (BITS(13,15) & ((uint32_t)(regval) << 13))  /*!< number of conversions in discontinuous mode */
+
+/* ADC special function */
+#define ADC_SCAN_MODE                    ADC_CTL0_SM                                 /*!< scan mode */
+#define ADC_INSERTED_CHANNEL_AUTO        ADC_CTL0_ICA                                /*!< inserted channel group convert automatically */
+#define ADC_CONTINUOUS_MODE              ADC_CTL1_CTN                                /*!< continuous mode */
+
+/* ADC data alignment */
+#define ADC_DATAALIGN_RIGHT              ((uint32_t)0x00000000U)                     /*!< right alignment */
+#define ADC_DATAALIGN_LEFT               ADC_CTL1_DAL                                /*!< left alignment */
+
+/* external trigger select for regular  channel */
+#define CTL1_ETSRC(regval)               (BITS(17,19) & ((uint32_t)(regval) << 17))  
+#define ADC_EXTTRIG_REGULAR_T0_CH0       CTL1_ETSRC(0)                               /*!< TIMER0 CH0 event select */
+#define ADC_EXTTRIG_REGULAR_T0_CH1       CTL1_ETSRC(1)                               /*!< TIMER0 CH1 event select */
+#define ADC_EXTTRIG_REGULAR_T0_CH2       CTL1_ETSRC(2)                               /*!< TIMER0 CH2 event select */
+#define ADC_EXTTRIG_REGULAR_T2_TRGO      CTL1_ETSRC(4)                               /*!< TIMER2 TRGO event select */
+#define ADC_EXTTRIG_REGULAR_T14_CH0      CTL1_ETSRC(5)                               /*!< TIMER14 CH0 event select */
+#define ADC_EXTTRIG_REGULAR_EXTI_11      CTL1_ETSRC(6)                               /*!< external interrupt line 11 */
+#define ADC_EXTTRIG_REGULAR_NONE         CTL1_ETSRC(7)                               /*!< software trigger */
+
+/* external trigger select for inserted channel */
+#define CTL1_ETSIC(regval)               (BITS(12,14) & ((uint32_t)(regval) << 12))  
+#define ADC_EXTTRIG_INSERTED_T0_TRGO     CTL1_ETSIC(0)                               /*!< TIMER0 TRGO event select */
+#define ADC_EXTTRIG_INSERTED_T0_CH3      CTL1_ETSIC(1)                               /*!< TIMER0 CH3 event select */
+#define ADC_EXTTRIG_INSERTED_T2_CH3      CTL1_ETSIC(4)                               /*!< TIMER2 CH3 event select */
+#define ADC_EXTTRIG_INSERTED_T14_TRGO    CTL1_ETSIC(5)                               /*!< TIMER14 TRGO event select */
+#define ADC_EXTTRIG_INSERTED_EXTI_15     CTL1_ETSIC(6)                               /*!< external interrupt line 15 */
+#define ADC_EXTTRIG_INSERTED_NONE        CTL1_ETSIC(7)                               /*!< software trigger */
+
+/* adc_samptx register value */
+#define SAMPTX_SPT(regval)               (BITS(0,2) & ((uint32_t)(regval) << 0))     
+#define ADC_SAMPLETIME_1POINT5           SAMPTX_SPT(0)                               /*!< 1.5 sampling cycles */
+#define ADC_SAMPLETIME_7POINT5           SAMPTX_SPT(1)                               /*!< 7.5 sampling cycles */
+#define ADC_SAMPLETIME_13POINT5          SAMPTX_SPT(2)                               /*!< 13.5 sampling cycles */
+#define ADC_SAMPLETIME_28POINT5          SAMPTX_SPT(3)                               /*!< 28.5 sampling cycles */
+#define ADC_SAMPLETIME_41POINT5          SAMPTX_SPT(4)                               /*!< 41.5 sampling cycles */
+#define ADC_SAMPLETIME_55POINT5          SAMPTX_SPT(5)                               /*!< 55.5 sampling cycles */
+#define ADC_SAMPLETIME_71POINT5          SAMPTX_SPT(6)                               /*!< 71.5 sampling cycles */
+#define ADC_SAMPLETIME_239POINT5         SAMPTX_SPT(7)                               /*!< 239.5 sampling cycles */
+
+/* ADC data offset for inserted channel x*/
+#define IOFFX_IOFF(regval)               (BITS(0,11) & ((uint32_t)(regval) << 0))    
+
+/* ADC analog watchdog high threshold  */
+#define WDHT_WDHT(regval)                (BITS(0,11) & ((uint32_t)(regval) << 0))    
+
+/* ADC analog watchdog low  threshold */
+#define WDLT_WDLT(regval)                (BITS(0,11) & ((uint32_t)(regval) << 0))    
+
+/* ADC regular channel group length */
+#define RSQ0_RL(regval)                  (BITS(20,23) & ((uint32_t)(regval) << 20))  
+
+/* ADC inserted channel group length */
+#define ISQ_IL(regval)                   (BITS(20,21) & ((uint32_t)(regval) << 20))  
+
+/* ADC resolution definitions */
+#define CTL0_DRES(regval)                (BITS(24,25) & ((regval) << 24))            /*!< ADC resolution */
+#define ADC_RESOLUTION_12B               CTL0_DRES(0)                                /*!< 12-bit ADC resolution */
+#define ADC_RESOLUTION_10B               CTL0_DRES(1)                                /*!< 10-bit ADC resolution */
+#define ADC_RESOLUTION_8B                CTL0_DRES(2)                                /*!< 8-bit ADC resolution */
+#define ADC_RESOLUTION_6B                CTL0_DRES(3)                                /*!< 6-bit ADC resolution */
+
+/* ADC oversampling shift */
+#define OVSAMPCTL_OVSS(regval)           (BITS(5,8) & ((uint32_t)(regval) << 5))     
+#define ADC_OVERSAMPLING_SHIFT_NONE      OVSAMPCTL_OVSS(0)                           /*!< no oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_1B        OVSAMPCTL_OVSS(1)                           /*!< 1-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_2B        OVSAMPCTL_OVSS(2)                           /*!< 2-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_3B        OVSAMPCTL_OVSS(3)                           /*!< 3-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_4B        OVSAMPCTL_OVSS(4)                           /*!< 4-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_5B        OVSAMPCTL_OVSS(5)                           /*!< 5-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_6B        OVSAMPCTL_OVSS(6)                           /*!< 6-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_7B        OVSAMPCTL_OVSS(7)                           /*!< 7-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_8B        OVSAMPCTL_OVSS(8)                           /*!< 8-bit oversampling shift */
+
+/* ADC oversampling ratio */
+#define OVSAMPCTL_OVSR(regval)           (BITS(2,4) & ((uint32_t)(regval) << 2))     
+#define ADC_OVERSAMPLING_RATIO_MUL2      OVSAMPCTL_OVSR(0)                           /*!< oversampling ratio multiple 2 */
+#define ADC_OVERSAMPLING_RATIO_MUL4      OVSAMPCTL_OVSR(1)                           /*!< oversampling ratio multiple 4 */
+#define ADC_OVERSAMPLING_RATIO_MUL8      OVSAMPCTL_OVSR(2)                           /*!< oversampling ratio multiple 8 */
+#define ADC_OVERSAMPLING_RATIO_MUL16     OVSAMPCTL_OVSR(3)                           /*!< oversampling ratio multiple 16 */
+#define ADC_OVERSAMPLING_RATIO_MUL32     OVSAMPCTL_OVSR(4)                           /*!< oversampling ratio multiple 32 */
+#define ADC_OVERSAMPLING_RATIO_MUL64     OVSAMPCTL_OVSR(5)                           /*!< oversampling ratio multiple 64 */
+#define ADC_OVERSAMPLING_RATIO_MUL128    OVSAMPCTL_OVSR(6)                           /*!< oversampling ratio multiple 128 */
+#define ADC_OVERSAMPLING_RATIO_MUL256    OVSAMPCTL_OVSR(7)                           /*!< oversampling ratio multiple 256 */
+
+/* ADC triggered oversampling */
+#define ADC_OVERSAMPLING_ALL_CONVERT     0U                                          /*!< all oversampled conversions for a channel are done consecutively after a trigger */
+#define ADC_OVERSAMPLING_ONE_CONVERT     1U                                          /*!< each oversampled conversion for a channel needs a trigger */
+
+/* ADC channel group definitions */
+#define ADC_REGULAR_CHANNEL              ((uint8_t)0x01U)                            /*!< ADC regular channel group */
+#define ADC_INSERTED_CHANNEL             ((uint8_t)0x02U)                            /*!< ADC inserted channel group */
+#define ADC_REGULAR_INSERTED_CHANNEL     ((uint8_t)0x03U)                            /*!< both regular and inserted channel group */
+#define ADC_CHANNEL_DISCON_DISABLE       ((uint8_t)0x04U)                            /*!< disable discontinuous mode of regular & inserted channel */
+
+/* ADC inserted channel definitions */
+#define ADC_INSERTED_CHANNEL_0           ((uint8_t)0x00U)                            /*!< ADC inserted channel 0 */
+#define ADC_INSERTED_CHANNEL_1           ((uint8_t)0x01U)                            /*!< ADC inserted channel 1 */
+#define ADC_INSERTED_CHANNEL_2           ((uint8_t)0x02U)                            /*!< ADC inserted channel 2 */
+#define ADC_INSERTED_CHANNEL_3           ((uint8_t)0x03U)                            /*!< ADC inserted channel 3 */
+
+/* ADC channel definitions */
+#define ADC_CHANNEL_0                    ((uint8_t)0x00U)                            /*!< ADC channel 0 */
+#define ADC_CHANNEL_1                    ((uint8_t)0x01U)                            /*!< ADC channel 1 */
+#define ADC_CHANNEL_2                    ((uint8_t)0x02U)                            /*!< ADC channel 2 */
+#define ADC_CHANNEL_3                    ((uint8_t)0x03U)                            /*!< ADC channel 3 */
+#define ADC_CHANNEL_4                    ((uint8_t)0x04U)                            /*!< ADC channel 4 */
+#define ADC_CHANNEL_5                    ((uint8_t)0x05U)                            /*!< ADC channel 5 */
+#define ADC_CHANNEL_6                    ((uint8_t)0x06U)                            /*!< ADC channel 6 */
+#define ADC_CHANNEL_7                    ((uint8_t)0x07U)                            /*!< ADC channel 7 */
+#define ADC_CHANNEL_8                    ((uint8_t)0x08U)                            /*!< ADC channel 8 */
+#define ADC_CHANNEL_9                    ((uint8_t)0x09U)                            /*!< ADC channel 9 */
+#define ADC_CHANNEL_16                   ((uint8_t)0x10U)                            /*!< ADC channel 16 */
+#define ADC_CHANNEL_17                   ((uint8_t)0x11U)                            /*!< ADC channel 17 */
+
+/* ADC interrupt definitions */
+#define ADC_INT_WDE                      ADC_STAT_WDE                                /*!< analog watchdog event interrupt */
+#define ADC_INT_EOC                      ADC_STAT_EOC                                /*!< end of group conversion interrupt */
+#define ADC_INT_EOIC                     ADC_STAT_EOIC                               /*!< end of inserted group conversion interrupt */
+
+/* ADC interrupt flag */
+#define ADC_INT_FLAG_WDE                 ADC_STAT_WDE                                /*!< analog watchdog event interrupt flag */
+#define ADC_INT_FLAG_EOC                 ADC_STAT_EOC                                /*!< end of group conversion interrupt flag */
+#define ADC_INT_FLAG_EOIC                ADC_STAT_EOIC                               /*!< end of inserted group conversion interrupt flag */
+
+/* function declarations */
+/* reset ADC */
+void adc_deinit(void);
+/* enable ADC interface */
+void adc_enable(void);
+/* disable ADC interface */
+void adc_disable(void);
+
+/* ADC calibration and reset calibration */
+void adc_calibration_enable(void);
+/* enable DMA request */
+void adc_dma_mode_enable(void);
+/* disable DMA request */
+void adc_dma_mode_disable(void);
+
+/* enable the temperature sensor and Vrefint channel */
+void adc_tempsensor_vrefint_enable(void);
+/* disable the temperature sensor and Vrefint channel */
+void adc_tempsensor_vrefint_disable(void);
+
+/* configure ADC discontinuous mode */
+void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length);
+/* configure ADC special function */
+void adc_special_function_config(uint32_t function, ControlStatus newvalue);
+
+/* configure ADC data alignment */
+void adc_data_alignment_config(uint32_t data_alignment);
+/* configure the length of regular channel group or inserted channel group */
+void adc_channel_length_config(uint8_t channel_group, uint32_t length);
+/* configure ADC regular channel */
+void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time);
+/* configure ADC inserted channel */
+void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time);
+/* configure ADC inserted channel offset */
+void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset);
+/* enable ADC external trigger */
+void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue);
+/* configure ADC external trigger source */
+void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source);
+/* enable ADC software trigger */
+void adc_software_trigger_enable(uint8_t channel_group);
+
+/* read ADC regular group data register */
+uint16_t adc_regular_data_read(void);
+/* read ADC inserted group data register */
+uint16_t adc_inserted_data_read(uint8_t inserted_channel);
+
+/* get the ADC flag bits */
+FlagStatus adc_flag_get(uint32_t flag);
+/* clear the ADC flag bits */
+void adc_flag_clear(uint32_t flag);
+/* get the ADC interrupt bits */
+FlagStatus adc_interrupt_flag_get(uint32_t flag);
+/* clear the ADC flag */
+void adc_interrupt_flag_clear(uint32_t flag);
+/* enable ADC interrupt */
+void adc_interrupt_enable(uint32_t interrupt);
+/* disable ADC interrupt */
+void adc_interrupt_disable(uint32_t interrupt);
+
+/* configure ADC analog watchdog single channel */
+void adc_watchdog_single_channel_enable(uint8_t channel);
+/* configure ADC analog watchdog group channel */
+void adc_watchdog_group_channel_enable(uint8_t channel_group);
+/* disable ADC analog watchdog */
+void adc_watchdog_disable(void);
+/* configure ADC analog watchdog threshold */
+void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold);
+
+/* configure ADC resolution */
+void adc_resolution_config(uint32_t resolution);
+/* configure ADC oversample mode */
+void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio);
+/* enable ADC oversample mode */
+void adc_oversample_mode_enable(void);
+/* disable ADC oversample mode */
+void adc_oversample_mode_disable(void);
+
+#endif /* GD32E230_ADC_H */

+ 162 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h

@@ -0,0 +1,162 @@
+/*!
+    \file  gd32e230_cmp.h
+    \brief definitions for the CMP
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_CMP_H
+#define GD32E230_CMP_H
+
+#include "gd32e230.h"
+
+/* CMP definitions */
+#define CMP                                      CMP_BASE                       /*!< CMP base address */  
+
+/* registers definitions */
+#define CMP_CS                                   REG32((CMP) + 0x00U)           /*!< CMP control and status register */
+
+/* CMP_CS bits definitions */
+#define CMP_CS_CMPEN                             BIT(0)                         /*!< CMP enable  */
+#define CMP_CS_CMPSW                             BIT(1)                         /*!< CMP switch */
+#define CMP_CS_CMPM                              BITS(2,3)                      /*!< CMP mode */
+#define CMP_CS_CMPMSEL                           BITS(4,6)                      /*!< COMP_M input selection */
+#define CMP_CS_CMPOSEL                           BITS(8,10)                     /*!< CMP output selection */
+#define CMP_CS_CMPPL                             BIT(11)                        /*!< polarity of CMP output */
+#define CMP_CS_CMPHST                            BITS(12,13)                    /*!< CMP hysteresis */
+#define CMP_CS_CMPO                              BIT(14)                        /*!< CMP output */
+#define CMP_CS_CMPLK                             BIT(15)                        /*!< CMP lock */
+
+/* consts definitions */
+/* operating mode */
+typedef enum{
+    CMP_HIGHSPEED = 0,                                                          /*!< high speed mode */
+    CMP_MIDDLESPEED,                                                            /*!< medium speed mode */
+    CMP_LOWSPEED,                                                               /*!< low speed mode */
+    CMP_VERYLOWSPEED                                                            /*!< very-low speed mode */
+}operating_mode_enum;
+
+/* inverting input */
+typedef enum{
+    CMP_1_4VREFINT = 0,                                                         /*!< VREFINT /4 input */
+    CMP_1_2VREFINT,                                                             /*!< VREFINT /2 input */
+    CMP_3_4VREFINT,                                                             /*!< VREFINT *3/4 input */
+    CMP_VREFINT,                                                                /*!< VREFINT input */
+    CMP_PA4,                                                                    /*!< PA4 input */
+    CMP_PA5,                                                                    /*!< PA5 input */
+    CMP_PA0,                                                                    /*!< PA0 input */
+    CMP_PA2                                                                     /*!< PA2 input */
+}inverting_input_enum;
+
+/* hysteresis */
+typedef enum{
+    CMP_HYSTERESIS_NO = 0,                                                      /*!< output no hysteresis */
+    CMP_HYSTERESIS_LOW,                                                         /*!< output low hysteresis */
+    CMP_HYSTERESIS_MIDDLE,                                                      /*!< output middle hysteresis */
+    CMP_HYSTERESIS_HIGH                                                         /*!< output high hysteresis */
+}cmp_hysteresis_enum;
+
+/* output */  
+typedef enum{
+    CMP_OUTPUT_NONE = 0x0U,                                                     /*!< output no selection */
+    CMP_OUTPUT_TIMER0BKIN = 0x1U,                                               /*!< TIMER 0 break input */
+    CMP_OUTPUT_TIMER0IC0 = 0x2U,                                                /*!< TIMER 0 channel0 input capture */
+    CMP_OUTPUT_TIMER0OCPRECLR = 0x3U,                                           /*!< TIMER 0 OCPRE_CLR input */
+    CMP_OUTPUT_TIMER2IC0 = 0x06U,                                               /*!< TIMER 2 channel0 input capture */
+    CMP_OUTPUT_TIMER2OCPRECLR = 0x7U                                            /*!< TIMER 2 OCPRE_CLR input */
+}cmp_output_enum;
+
+/* CMP mode */
+#define CS_CMPM(regval)                         (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define CS_CMPM_HIGHSPEED                       CS_CMPM(0)                      /*!< CMP mode high speed */
+#define CS_CMPM_MIDDLESPEED                     CS_CMPM(1)                      /*!< CMP mode middle speed */
+#define CS_CMPM_LOWSPEED                        CS_CMPM(2)                      /*!< CMP mode low speed */
+#define CS_CMPM_VERYLOWSPEED                    CS_CMPM(3)                      /*!< CMP mode very low speed */
+
+/* comparator inverting input */
+#define CS_CMPMSEL(regval)                      (BITS(4,6) & ((uint32_t)(regval) << 4))
+#define CS_CMPMSEL_1_4VREFINT                   CS_CMPMSEL(0)                   /*!< CMP inverting input 1/4 Vrefint */
+#define CS_CMPMSEL_1_2VREFINT                   CS_CMPMSEL(1)                   /*!< CMP inverting input 1/2 Vrefint */
+#define CS_CMPMSEL_3_4VREFINT                   CS_CMPMSEL(2)                   /*!< CMP inverting input 3/4 Vrefint */
+#define CS_CMPMSEL_VREFINT                      CS_CMPMSEL(3)                   /*!< CMP inverting input Vrefint */
+#define CS_CMPMSEL_PA4                          CS_CMPMSEL(4)                   /*!< CMP inverting input PA4*/
+#define CS_CMPMSEL_PA5                          CS_CMPMSEL(5)                   /*!< CMP inverting input PA5*/
+#define CS_CMPMSEL_PA0                          CS_CMPMSEL(6)                   /*!< CMP inverting input PA0*/
+#define CS_CMPMSEL_PA2                          CS_CMPMSEL(7)                   /*!< CMP inverting input PA2*/
+
+/* CMP output */
+#define CS_CMPOSEL(regval)                      (BITS(8,10) & ((uint32_t)(regval) << 8))
+#define CS_CMPOSEL_OUTPUT_NONE                  CS_CMPOSEL(0)                   /*!< CMP output none  */
+#define CS_CMPOSEL_OUTPUT_TIMER0BKIN            CS_CMPOSEL(1)                   /*!< CMP output TIMER 0 break input */
+#define CS_CMPOSEL_OUTPUT_TIMER0IC0             CS_CMPOSEL(2)                   /*!< CMP output TIMER 0 channel 0 input capture */
+#define CS_CMPOSEL_OUTPUT_TIMER0OCPRECLR        CS_CMPOSEL(3)                   /*!< CMP output TIMER 0 ocpreclear input */ 
+#define CS_CMPOSEL_OUTPUT_TIMER2IC0             CS_CMPOSEL(6)                   /*!< CMP output TIMER 2 channle 0 input capture */
+#define CS_CMPOSEL_OUTPUT_TIMER2OCPRECLR        CS_CMPOSEL(7)                   /*!< CMP output TIMER 2 ocpreclear input */
+
+/* CMP hysteresis */
+#define CS_CMPHST(regval)                       (BITS(12,13) & ((uint32_t)(regval) << 12))
+#define CS_CMPHST_HYSTERESIS_NO                 CS_CMPHST(0)                    /*!< CMP output no hysteresis */
+#define CS_CMPHST_HYSTERESIS_LOW                CS_CMPHST(1)                    /*!< CMP output low hysteresis */
+#define CS_CMPHST_HYSTERESIS_MIDDLE             CS_CMPHST(2)                    /*!< CMP output middle hysteresis */
+#define CS_CMPHST_HYSTERESIS_HIGH               CS_CMPHST(3)                    /*!< CMP output high hysteresis */
+
+/* CMP output level */
+#define CMP_OUTPUTLEVEL_HIGH                     ((uint32_t)0x00000001)         /*!< comparator output high */
+#define CMP_OUTPUTLEVEL_LOW                      ((uint32_t)0x00000000)         /*!< comparator output low */
+
+/* output polarity of comparator */
+#define CMP_OUTPUT_POLARITY_INVERTED             ((uint32_t)0x00000001)         /*!< output is inverted */
+#define CMP_OUTPUT_POLARITY_NOINVERTED           ((uint32_t)0x00000000)         /*!< output is not inverted */
+
+/* function declarations */
+
+/* initialization functions */
+/* CMP deinit */
+void cmp_deinit(void);
+/* CMP mode init */
+void cmp_mode_init(operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis);
+/* CMP output init */
+void cmp_output_init(cmp_output_enum output_slection, uint32_t output_polarity);
+/* enable CMP */
+void cmp_enable(void);
+/* disable CMP */
+void cmp_disable(void);
+/* enable CMP switch */
+void cmp_switch_enable(void);
+/* disable CMP switch */
+void cmp_switch_disable(void);
+/* get output level */
+uint32_t cmp_output_level_get(void);
+/* lock the CMP */
+void cmp_lock_enable(void);
+
+#endif /* GD32E230_CMP_H */

+ 120 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h

@@ -0,0 +1,120 @@
+/*!
+    \file    gd32e230_crc.h
+    \brief   definitions for the CRC
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_CRC_H
+#define GD32E230_CRC_H
+
+#include "gd32e230.h"
+
+/* CRC definitions */
+#define CRC                            CRC_BASE
+
+/* registers definitions */
+#define CRC_DATA                       REG32((CRC) + 0x00U)            /*!< CRC data register */
+#define CRC_FDATA                      REG32((CRC) + 0x04U)            /*!< CRC free data register */
+#define CRC_CTL                        REG32((CRC) + 0x08U)            /*!< CRC control register */
+#define CRC_IDATA                      REG32((CRC) + 0x10U)            /*!< CRC initialization data register */
+#define CRC_POLY                       REG32((CRC) + 0x14U)            /*!< CRC polynomial register */
+
+/* bits definitions */
+/* CRC_DATA */
+#define CRC_DATA_DATA                  BITS(0,31)                      /*!< CRC data bits */
+
+/* CRC_FDATA */
+#define CRC_FDATA_FDATA                BITS(0,7)                       /*!< CRC free data bits */
+
+/* CRC_CTL */
+#define CRC_CTL_RST                    BIT(0)                          /*!< CRC reset bit */
+#define CRC_CTL_PS                     BITS(3,4)                       /*!< size of polynomial function bits */
+#define CRC_CTL_REV_I                  BITS(5,6)                       /*!< input data reverse function bits */
+#define CRC_CTL_REV_O                  BIT(7)                          /*!< output data reverse function bit */
+
+/* CRC_INIT */
+#define CRC_IDATA_IDATA                BITS(0,31)                      /*!< CRC initialization data bits */
+
+/* CRC_POLY */
+#define CRC_POLY_POLY                  BITS(0,31)                      /*!< CRC polynomial value bits */
+
+/* constants definitions */
+/* size of polynomial function */
+#define CTL_PS(regval)                 (BITS(3, 4) & ((regval) << 3))
+#define CRC_CTL_PS_32                  CTL_PS(0)                       /*!< 32-bit polynomial for CRC calculation */
+#define CRC_CTL_PS_16                  CTL_PS(1)                       /*!< 16-bit polynomial for CRC calculation */
+#define CRC_CTL_PS_8                   CTL_PS(2)                       /*!< 8-bit polynomial for CRC calculation */
+#define CRC_CTL_PS_7                   CTL_PS(3)                       /*!< 7-bit polynomial for CRC calculation */
+
+/* input data reverse function */
+#define CTL_REV_I(regval)              (BITS(5, 6) & ((regval) << 5))
+#define CRC_INPUT_DATA_NOT             CTL_REV_I(0)                    /*!< input data not reverse */
+#define CRC_INPUT_DATA_BYTE            CTL_REV_I(1)                    /*!< input data reversed by byte type */
+#define CRC_INPUT_DATA_HALFWORD        CTL_REV_I(2)                    /*!< input data reversed by half-word type */
+#define CRC_INPUT_DATA_WORD            CTL_REV_I(3)                    /*!< input data reversed by word type */
+
+/* function declarations */
+/* deinit CRC calculation unit */
+void crc_deinit(void);
+
+/* enable the reverse operation of output data */
+void crc_reverse_output_data_enable(void);
+/* disable the reverse operation of output data */
+void crc_reverse_output_data_disable(void);
+
+/* reset data register to the value of initializaiton data register */
+void crc_data_register_reset(void);
+/* read the data register  */
+uint32_t crc_data_register_read(void);
+
+/* read the free data register */
+uint8_t crc_free_data_register_read(void);
+/* write the free data register */
+void crc_free_data_register_write(uint8_t free_data);
+
+/* write the initial value register */
+void crc_init_data_register_write(uint32_t init_data);
+/* configure the CRC input data function */
+void crc_input_data_reverse_config(uint32_t data_reverse);
+
+/* configure the CRC size of polynomial function */
+void crc_polynomial_size_set(uint32_t poly_size);
+/* configure the CRC polynomial value function */
+void crc_polynomial_set(uint32_t poly);
+
+/* CRC calculate a 32-bit data */
+uint32_t crc_single_data_calculate(uint32_t sdata);
+/* CRC calculate a 32-bit data array */
+uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size);
+
+#endif /* GD32E230_CRC_H */

+ 123 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h

@@ -0,0 +1,123 @@
+/*!
+    \file    gd32e230_dbg.h
+    \brief   definitions for the DBG
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_DBG_H
+#define GD32E230_DBG_H
+
+#include "gd32e230.h"
+
+/* DBG definitions */
+#define DBG                      DBG_BASE
+
+/* registers definitions */
+#define DBG_ID                   REG32(DBG + 0x00U)      /*!< DBG_ID code register */
+#define DBG_CTL0                 REG32(DBG + 0x04U)      /*!< DBG control register 0 */
+#define DBG_CTL1                 REG32(DBG + 0x08U)      /*!< DBG control register 1 */
+
+/* bits definitions */
+/* DBG_ID */
+#define DBG_ID_ID_CODE           BITS(0,31)             /*!< DBG ID code values */
+
+/* DBG_CTL0 */
+#define DBG_CTL0_SLP_HOLD        BIT(0)                 /*!< keep debugger connection during sleep mode */
+#define DBG_CTL0_DSLP_HOLD       BIT(1)                 /*!< keep debugger connection during deepsleep mode */
+#define DBG_CTL0_STB_HOLD        BIT(2)                 /*!< keep debugger connection during standby mode */
+#define DBG_CTL0_FWDGT_HOLD      BIT(8)                 /*!< debug FWDGT kept when core is halted */
+#define DBG_CTL0_WWDGT_HOLD      BIT(9)                 /*!< debug WWDGT kept when core is halted */
+#define DBG_CTL0_TIMER0_HOLD     BIT(10)                /*!< TIMER0 counter kept when core is halted */
+#define DBG_CTL0_TIMER2_HOLD     BIT(12)                /*!< TIMER2 counter kept when core is halted */
+#define DBG_CTL0_I2C0_HOLD       BIT(15)                /*!< hold I2C0 smbus when core is halted */
+#define DBG_CTL0_I2C1_HOLD       BIT(16)                /*!< hold I2C1 smbus when core is halted */
+#define DBG_CTL0_TIMER5_HOLD     BIT(19)                /*!< hold TIMER5 counter when core is halted */
+#define DBG_CTL0_TIMER13_HOLD    BIT(27)                /*!< hold TIMER13 counter when core is halted */
+
+/* DBG_CTL1 */
+#define DBG_CTL1_RTC_HOLD        BIT(10)                /*!< hold RTC calendar and wakeup counter when core is halted */
+#define DBG_CTL1_TIMER14_HOLD    BIT(16)                /*!< hold TIMER14 counter when core is halted */
+#define DBG_CTL1_TIMER15_HOLD    BIT(17)                /*!< hold TIMER15 counter when core is halted */
+#define DBG_CTL1_TIMER16_HOLD    BIT(18)                /*!< hold TIMER16 counter when core is halted */
+
+/* constants definitions */
+#define DBG_LOW_POWER_SLEEP      DBG_CTL0_SLP_HOLD      /*!< keep debugger connection during sleep mode */
+#define DBG_LOW_POWER_DEEPSLEEP  DBG_CTL0_DSLP_HOLD     /*!< keep debugger connection during deepsleep mode */
+#define DBG_LOW_POWER_STANDBY    DBG_CTL0_STB_HOLD      /*!< keep debugger connection during standby mode */
+
+/* define the peripheral debug hold bit position and its register index offset */
+#define DBG_REGIDX_BIT(regidx, bitpos)      (((regidx) << 6) | (bitpos))
+#define DBG_REG_VAL(periph)                 (REG32(DBG + ((uint32_t)(periph) >> 6)))
+#define DBG_BIT_POS(val)                    ((uint32_t)(val) & 0x1FU)
+
+/* register index */
+enum dbg_reg_idx
+{
+    DBG_IDX_CTL0  = 0x04U, 
+    DBG_IDX_CTL1  = 0x08U, 
+};
+
+/* peripherals hold bit */
+typedef enum
+{
+    DBG_FWDGT_HOLD          = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U),              /*!< FWDGT hold bit */
+    DBG_WWDGT_HOLD          = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U),              /*!< WWDGT hold bit */
+    DBG_TIMER0_HOLD         = DBG_REGIDX_BIT(DBG_IDX_CTL0, 10U),             /*!< TIMER0 hold bit */
+    DBG_TIMER2_HOLD         = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U),             /*!< TIMER2 hold bit */
+    DBG_TIMER5_HOLD         = DBG_REGIDX_BIT(DBG_IDX_CTL0, 19U),             /*!< TIMER5 hold bit */
+    DBG_TIMER13_HOLD        = DBG_REGIDX_BIT(DBG_IDX_CTL0, 27U),             /*!< TIMER13 hold bit */
+    DBG_TIMER14_HOLD        = DBG_REGIDX_BIT(DBG_IDX_CTL1, 16U),             /*!< TIMER14 hold bit */
+    DBG_TIMER15_HOLD        = DBG_REGIDX_BIT(DBG_IDX_CTL1, 17U),             /*!< TIMER15 hold bit */
+    DBG_TIMER16_HOLD        = DBG_REGIDX_BIT(DBG_IDX_CTL1, 18U),             /*!< TIMER16 hold bit */
+    DBG_I2C0_HOLD           = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U),             /*!< I2C0 hold bit */
+    DBG_I2C1_HOLD           = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U),             /*!< I2C1 hold bit */
+    DBG_RTC_HOLD            = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U),             /*!< RTC hold bit */
+}dbg_periph_enum;
+
+/* function declarations */
+/* deinitialize the DBG */
+void dbg_deinit(void);
+/* read DBG_ID code register */
+uint32_t dbg_id_get(void);
+
+/* enable low power behavior when the MCU is in debug mode */
+void dbg_low_power_enable(uint32_t dbg_low_power);
+/* disable low power behavior when the MCU is in debug mode */
+void dbg_low_power_disable(uint32_t dbg_low_power);
+
+/* enable peripheral behavior when the MCU is in debug mode */
+void dbg_periph_enable(dbg_periph_enum dbg_periph);
+/* disable peripheral behavior when the MCU is in debug mode */
+void dbg_periph_disable(dbg_periph_enum dbg_periph);
+
+#endif /* GD32E230_DBG_H */

+ 264 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h

@@ -0,0 +1,264 @@
+/*!
+    \file  gd32e230_dma.h
+    \brief definitions for the DMA
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_DMA_H
+#define GD32E230_DMA_H
+
+#include "gd32e230.h"
+
+/* DMA definitions */
+#define DMA                               DMA_BASE              /*!< DMA base address */
+
+/* registers definitions */
+#define DMA_INTF                          REG32(DMA + 0x00U)    /*!< DMA interrupt flag register */
+#define DMA_INTC                          REG32(DMA + 0x04U)    /*!< DMA interrupt flag clear register */
+#define DMA_CH0CTL                        REG32(DMA + 0x08U)    /*!< DMA channel 0 control register */
+#define DMA_CH0CNT                        REG32(DMA + 0x0CU)    /*!< DMA channel 0 counter register */
+#define DMA_CH0PADDR                      REG32(DMA + 0x10U)    /*!< DMA channel 0 peripheral base address register */
+#define DMA_CH0MADDR                      REG32(DMA + 0x14U)    /*!< DMA channel 0 memory base address register */
+#define DMA_CH1CTL                        REG32(DMA + 0x1CU)    /*!< DMA channel 1 control register */
+#define DMA_CH1CNT                        REG32(DMA + 0x20U)    /*!< DMA channel 1 counter register */
+#define DMA_CH1PADDR                      REG32(DMA + 0x24U)    /*!< DMA channel 1 peripheral base address register */
+#define DMA_CH1MADDR                      REG32(DMA + 0x28U)    /*!< DMA channel 1 memory base address register */
+#define DMA_CH2CTL                        REG32(DMA + 0x30U)    /*!< DMA channel 2 control register */
+#define DMA_CH2CNT                        REG32(DMA + 0x34U)    /*!< DMA channel 2 counter register */
+#define DMA_CH2PADDR                      REG32(DMA + 0x38U)    /*!< DMA channel 2 peripheral base address register */
+#define DMA_CH2MADDR                      REG32(DMA + 0x3CU)    /*!< DMA channel 2 memory base address register */
+#define DMA_CH3CTL                        REG32(DMA + 0x44U)    /*!< DMA channel 3 control register */
+#define DMA_CH3CNT                        REG32(DMA + 0x48U)    /*!< DMA channel 3 counter register */
+#define DMA_CH3PADDR                      REG32(DMA + 0x4CU)    /*!< DMA channel 3 peripheral base address register */
+#define DMA_CH3MADDR                      REG32(DMA + 0x50U)    /*!< DMA channel 3 memory base address register */
+#define DMA_CH4CTL                        REG32(DMA + 0x58U)    /*!< DMA channel 4 control register */
+#define DMA_CH4CNT                        REG32(DMA + 0x5CU)    /*!< DMA channel 4 counter register */
+#define DMA_CH4PADDR                      REG32(DMA + 0x60U)    /*!< DMA channel 4 peripheral base address register */
+#define DMA_CH4MADDR                      REG32(DMA + 0x64U)    /*!< DMA channel 4 memory base address register */
+
+/* bits definitions */
+/* DMA_INTF */
+#define DMA_INTF_GIF                      BIT(0)                /*!< global interrupt flag of channel */
+#define DMA_INTF_FTFIF                    BIT(1)                /*!< full transfer finish flag of channel */
+#define DMA_INTF_HTFIF                    BIT(2)                /*!< half transfer finish flag of channel */
+#define DMA_INTF_ERRIF                    BIT(3)                /*!< error flag of channel */
+
+/* DMA_INTC */
+#define DMA_INTC_GIFC                     BIT(0)                /*!< clear global interrupt flag of channel */
+#define DMA_INTC_FTFIFC                   BIT(1)                /*!< clear transfer finish flag of channel */
+#define DMA_INTC_HTFIFC                   BIT(2)                /*!< clear half transfer finish flag of channel */
+#define DMA_INTC_ERRIFC                   BIT(3)                /*!< clear error flag of channel */
+
+/* DMA_CHxCTL,x=0..4 */
+#define DMA_CHXCTL_CHEN                   BIT(0)                /*!< channel x enable */
+#define DMA_CHXCTL_FTFIE                  BIT(1)                /*!< enable bit for channel x transfer complete interrupt */
+#define DMA_CHXCTL_HTFIE                  BIT(2)                /*!< enable bit for channel x transfer half complete interrupt */
+#define DMA_CHXCTL_ERRIE                  BIT(3)                /*!< enable bit for channel x error interrupt */
+#define DMA_CHXCTL_DIR                    BIT(4)                /*!< direction of the data transfer on the channel */
+#define DMA_CHXCTL_CMEN                   BIT(5)                /*!< circulation mode */
+#define DMA_CHXCTL_PNAGA                  BIT(6)                /*!< next address generation algorithm of peripheral */
+#define DMA_CHXCTL_MNAGA                  BIT(7)                /*!< next address generation algorithm of memory */
+#define DMA_CHXCTL_PWIDTH                 BITS(8,9)             /*!< transfer data size of peripheral */
+#define DMA_CHXCTL_MWIDTH                 BITS(10,11)           /*!< transfer data size of memory */
+#define DMA_CHXCTL_PRIO                   BITS(12,13)           /*!< priority level of channelx */
+#define DMA_CHXCTL_M2M                    BIT(14)               /*!< memory to memory mode */
+
+/* DMA_CHxCNT,x=0..4 */
+#define DMA_CHXCNT_CNT                    BITS(0,15)            /*!< transfer counter */
+
+/* DMA_CHxPADDR,x=0..4 */
+#define DMA_CHXPADDR_PADDR                BITS(0,31)            /*!< peripheral base address */
+
+/* DMA_CHxMADDR,x=0..4 */
+#define DMA_CHXMADDR_MADDR                BITS(0,31)            /*!< memory base address */
+
+/* constants definitions */
+/* DMA channel select */
+typedef enum 
+{
+    DMA_CH0 = 0,                          /*!< DMA Channel0 */
+    DMA_CH1,                              /*!< DMA Channel1 */ 
+    DMA_CH2,                              /*!< DMA Channel2 */ 
+    DMA_CH3,                              /*!< DMA Channel3 */ 
+    DMA_CH4,                              /*!< DMA Channel4 */ 
+} dma_channel_enum;
+
+/* DMA initialize struct */
+typedef struct
+{
+    uint32_t periph_addr;                 /*!< peripheral base address */
+    uint32_t periph_width;                /*!< transfer data size of peripheral */
+    uint32_t memory_addr;                 /*!< memory base address */
+    uint32_t memory_width;                /*!< transfer data size of memory */
+    uint32_t number;                      /*!< channel transfer number */
+    uint32_t priority;                    /*!< channel priority level */
+    uint8_t periph_inc;                   /*!< peripheral increasing mode */
+    uint8_t memory_inc;                   /*!< memory increasing mode */
+    uint8_t direction;                    /*!< channel data transfer direction */
+} dma_parameter_struct;
+
+/* DMA reset value */
+#define DMA_CHCTL_RESET_VALUE             ((uint32_t)0x00000000U)                         /*!< the reset value of DMA channel CHXCTL register */
+#define DMA_CHCNT_RESET_VALUE             ((uint32_t)0x00000000U)                         /*!< the reset value of DMA channel CHXCNT register */
+#define DMA_CHPADDR_RESET_VALUE           ((uint32_t)0x00000000U)                         /*!< the reset value of DMA channel CHXPADDR register */
+#define DMA_CHMADDR_RESET_VALUE           ((uint32_t)0x00000000U)                         /*!< the reset value of DMA channel CHXMADDR register */
+#define DMA_CHINTF_RESET_VALUE            (DMA_INTF_GIF | DMA_INTF_FTFIF | \
+                                           DMA_INTF_HTFIF | DMA_INTF_ERRIF)
+
+#define DMA_FLAG_ADD(flag,shift)          ((flag) << ((uint32_t)(shift) * 4U))            /*!< DMA channel flag shift */
+
+/* DMA_CHCTL base address */
+#define DMA_CHXCTL_BASE                   (DMA + 0x08U)                                   /*!< the base address of DMA channel CHXCTL register */
+#define DMA_CHXCNT_BASE                   (DMA + 0x0CU)                                   /*!< the base address of DMA channel CHXCNT register */
+#define DMA_CHXPADDR_BASE                 (DMA + 0x10U)                                   /*!< the base address of DMA channel CHXPADDR register */
+#define DMA_CHXMADDR_BASE                 (DMA + 0x14U)                                   /*!< the base address of DMA channel CHXMADDR register */
+
+/* DMA channel shift bit */
+#define DMA_CHCTL(channel)                REG32(DMA_CHXCTL_BASE + 0x14U * (uint32_t)(channel))         /*!< the address of DMA channel CHXCTL register */
+#define DMA_CHCNT(channel)                REG32(DMA_CHXCNT_BASE + 0x14U * (uint32_t)(channel))         /*!< the address of DMA channel CHXCNT register */
+#define DMA_CHPADDR(channel)              REG32(DMA_CHXPADDR_BASE + 0x14U * (uint32_t)(channel))       /*!< the address of DMA channel CHXPADDR register */
+#define DMA_CHMADDR(channel)              REG32(DMA_CHXMADDR_BASE + 0x14U * (uint32_t)(channel))       /*!< the address of DMA channel CHXMADDR register */
+
+/* DMA_INTF register */
+/* interrupt flag bits */
+#define DMA_INT_FLAG_G                    DMA_INTF_GIF                                    /*!< global interrupt flag of channel */
+#define DMA_INT_FLAG_FTF                  DMA_INTF_FTFIF                                  /*!< full transfer finish interrupt flag of channel */
+#define DMA_INT_FLAG_HTF                  DMA_INTF_HTFIF                                  /*!< half transfer finish interrupt flag of channel */
+#define DMA_INT_FLAG_ERR                  DMA_INTF_ERRIF                                  /*!< error interrupt flag of channel */
+
+/* flag bits */
+#define DMA_FLAG_G                        DMA_INTF_GIF                                    /*!< global interrupt flag of channel */
+#define DMA_FLAG_FTF                      DMA_INTF_FTFIF                                  /*!< full transfer finish flag of channel */
+#define DMA_FLAG_HTF                      DMA_INTF_HTFIF                                  /*!< half transfer finish flag of channel */
+#define DMA_FLAG_ERR                      DMA_INTF_ERRIF                                  /*!< error flag of channel */
+
+/* DMA_CHxCTL register */
+/* interrupt enable bits */
+#define DMA_INT_FTF                       DMA_CHXCTL_FTFIE                                /*!< enable bit for channel full transfer finish interrupt */
+#define DMA_INT_HTF                       DMA_CHXCTL_HTFIE                                /*!< enable bit for channel half transfer finish interrupt */
+#define DMA_INT_ERR                       DMA_CHXCTL_ERRIE                                /*!< enable bit for channel error interrupt */
+
+/* transfer direction */
+#define DMA_PERIPHERAL_TO_MEMORY          ((uint32_t)0x00000000U)                         /*!< read from peripheral and write to memory */
+#define DMA_MEMORY_TO_PERIPHERAL          ((uint32_t)0x00000001U)                         /*!< read from memory and write to peripheral */
+
+/* peripheral increasing mode */
+#define DMA_PERIPH_INCREASE_DISABLE       ((uint32_t)0x00000000U)                         /*!< next address of peripheral is fixed address mode */
+#define DMA_PERIPH_INCREASE_ENABLE        ((uint32_t)0x00000001U)                         /*!< next address of peripheral is increasing address mode */
+
+/* memory increasing mode */
+#define DMA_MEMORY_INCREASE_DISABLE       ((uint32_t)0x00000000U)                         /*!< next address of memory is fixed address mode */
+#define DMA_MEMORY_INCREASE_ENABLE        ((uint32_t)0x00000001U)                         /*!< next address of memory is increasing address mode */
+
+/* transfer data size of peripheral */
+#define CHCTL_PWIDTH(regval)              (BITS(8,9) & ((regval) << 8))                   /*!< transfer data size of peripheral */
+#define DMA_PERIPHERAL_WIDTH_8BIT         CHCTL_PWIDTH(0U)                                 /*!< transfer data size of peripheral is 8-bit */
+#define DMA_PERIPHERAL_WIDTH_16BIT        CHCTL_PWIDTH(1U)                                 /*!< transfer data size of peripheral is 16-bit */
+#define DMA_PERIPHERAL_WIDTH_32BIT        CHCTL_PWIDTH(2U)                                 /*!< transfer data size of peripheral is 32-bit */
+
+/* transfer data size of memory */
+#define CHCTL_MWIDTH(regval)              (BITS(10,11) & ((regval) << 10))                /*!< transfer data size of memory */
+#define DMA_MEMORY_WIDTH_8BIT             CHCTL_MWIDTH(0U)                                 /*!< transfer data size of memory is 8-bit */
+#define DMA_MEMORY_WIDTH_16BIT            CHCTL_MWIDTH(1U)                                 /*!< transfer data size of memory is 16-bit */
+#define DMA_MEMORY_WIDTH_32BIT            CHCTL_MWIDTH(2U)                                 /*!< transfer data size of memory is 32-bit */
+
+/* channel priority level */
+#define CHCTL_PRIO(regval)                (BITS(12,13) & ((regval) << 12))                /*!< DMA channel priority level */
+#define DMA_PRIORITY_LOW                  CHCTL_PRIO(0U)                                   /*!< low priority */
+#define DMA_PRIORITY_MEDIUM               CHCTL_PRIO(1U)                                   /*!< medium priority */
+#define DMA_PRIORITY_HIGH                 CHCTL_PRIO(2U)                                   /*!< high priority */
+#define DMA_PRIORITY_ULTRA_HIGH           CHCTL_PRIO(3U)                                   /*!< ultra high priority */
+
+/* DMA_CHxCNT register */
+/* transfer counter */
+#define DMA_CHANNEL_CNT_MASK              DMA_CHXCNT_CNT                    
+
+/* function declarations */
+/* deinitialize DMA a channel registers */
+void dma_deinit(dma_channel_enum channelx);
+/* initialize the parameters of DMA struct with the default values */
+void dma_struct_para_init(dma_parameter_struct* init_struct);
+/* initialize DMA channel */
+void dma_init(dma_channel_enum channelx, dma_parameter_struct* init_struct);
+/* enable DMA circulation mode */
+void dma_circulation_enable(dma_channel_enum channelx);
+/* disable DMA circulation mode */
+void dma_circulation_disable(dma_channel_enum channelx);
+/* enable memory to memory mode */
+void dma_memory_to_memory_enable(dma_channel_enum channelx);
+/* disable memory to memory mode */
+void dma_memory_to_memory_disable(dma_channel_enum channelx);
+/* enable DMA channel */
+void dma_channel_enable(dma_channel_enum channelx);
+/* disable DMA channel */
+void dma_channel_disable(dma_channel_enum channelx);
+
+/* set DMA peripheral base address */
+void dma_periph_address_config(dma_channel_enum channelx, uint32_t address);
+/* set DMA memory base address */
+void dma_memory_address_config(dma_channel_enum channelx, uint32_t address);
+/* set the number of remaining data to be transferred by the DMA */
+void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number);
+/* get the number of remaining data to be transferred by the DMA */
+uint32_t dma_transfer_number_get(dma_channel_enum channelx);
+/* configure priority level of DMA channel */
+void dma_priority_config(dma_channel_enum channelx, uint32_t priority);
+/* configure transfer data size of memory */
+void dma_memory_width_config (dma_channel_enum channelx, uint32_t mwidth);
+/* configure transfer data size of peripheral */
+void dma_periph_width_config (dma_channel_enum channelx, uint32_t pwidth);
+/* enable next address increasement algorithm of memory */
+void dma_memory_increase_enable(dma_channel_enum channelx);
+/* disable next address increasement algorithm of memory */
+void dma_memory_increase_disable(dma_channel_enum channelx);
+/* enable next address increasement algorithm of peripheral */
+void dma_periph_increase_enable(dma_channel_enum channelx);
+/* disable next address increasement algorithm of peripheral */
+void dma_periph_increase_disable(dma_channel_enum channelx);
+/* configure the direction of data transfer on the channel */
+void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction);
+
+/* check DMA flag is set or not */
+FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag);
+/* clear DMA a channel flag */
+void dma_flag_clear(dma_channel_enum channelx, uint32_t flag);
+/* check DMA flag and interrupt enable bit is set or not */
+FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag);
+/* clear DMA a channel flag */
+void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag);
+/* enable DMA interrupt */
+void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source);
+/* disable DMA interrupt */
+void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source);
+
+#endif /* GD32E230_DMA_H */

+ 278 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h

@@ -0,0 +1,278 @@
+/*!
+    \file  gd32e230_exti.h
+    \brief definitions for the EXTI
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_EXTI_H
+#define GD32E230_EXTI_H
+
+#include "gd32e230.h"
+
+/* EXTI definitions */
+#define EXTI                         EXTI_BASE
+
+/* registers definitions */
+#define EXTI_INTEN                   REG32(EXTI + 0x00U)      /*!< interrupt enable register */
+#define EXTI_EVEN                    REG32(EXTI + 0x04U)      /*!< event enable register */
+#define EXTI_RTEN                    REG32(EXTI + 0x08U)      /*!< rising edge trigger enable register */
+#define EXTI_FTEN                    REG32(EXTI + 0x0CU)      /*!< falling trigger enable register */
+#define EXTI_SWIEV                   REG32(EXTI + 0x10U)      /*!< software interrupt event register */
+#define EXTI_PD                      REG32(EXTI + 0x14U)      /*!< pending register */
+
+/* bits definitions */
+/* EXTI_INTEN */
+#define EXTI_INTEN_INTEN0            BIT(0)                   /*!< interrupt from line 0 */
+#define EXTI_INTEN_INTEN1            BIT(1)                   /*!< interrupt from line 1 */
+#define EXTI_INTEN_INTEN2            BIT(2)                   /*!< interrupt from line 2 */
+#define EXTI_INTEN_INTEN3            BIT(3)                   /*!< interrupt from line 3 */
+#define EXTI_INTEN_INTEN4            BIT(4)                   /*!< interrupt from line 4 */
+#define EXTI_INTEN_INTEN5            BIT(5)                   /*!< interrupt from line 5 */
+#define EXTI_INTEN_INTEN6            BIT(6)                   /*!< interrupt from line 6 */
+#define EXTI_INTEN_INTEN7            BIT(7)                   /*!< interrupt from line 7 */
+#define EXTI_INTEN_INTEN8            BIT(8)                   /*!< interrupt from line 8 */
+#define EXTI_INTEN_INTEN9            BIT(9)                   /*!< interrupt from line 9 */
+#define EXTI_INTEN_INTEN10           BIT(10)                  /*!< interrupt from line 10 */
+#define EXTI_INTEN_INTEN11           BIT(11)                  /*!< interrupt from line 11 */
+#define EXTI_INTEN_INTEN12           BIT(12)                  /*!< interrupt from line 12 */
+#define EXTI_INTEN_INTEN13           BIT(13)                  /*!< interrupt from line 13 */
+#define EXTI_INTEN_INTEN14           BIT(14)                  /*!< interrupt from line 14 */
+#define EXTI_INTEN_INTEN15           BIT(15)                  /*!< interrupt from line 15 */
+#define EXTI_INTEN_INTEN16           BIT(16)                  /*!< interrupt from line 16 */
+#define EXTI_INTEN_INTEN17           BIT(17)                  /*!< interrupt from line 17 */
+#define EXTI_INTEN_INTEN18           BIT(18)                  /*!< interrupt from line 18 */
+#define EXTI_INTEN_INTEN19           BIT(19)                  /*!< interrupt from line 19 */
+#define EXTI_INTEN_INTEN20           BIT(20)                  /*!< interrupt from line 20 */
+#define EXTI_INTEN_INTEN21           BIT(21)                  /*!< interrupt from line 21 */
+#define EXTI_INTEN_INTEN22           BIT(22)                  /*!< interrupt from line 22 */
+#define EXTI_INTEN_INTEN23           BIT(23)                  /*!< interrupt from line 23 */
+#define EXTI_INTEN_INTEN24           BIT(24)                  /*!< interrupt from line 24 */
+#define EXTI_INTEN_INTEN25           BIT(25)                  /*!< interrupt from line 25 */
+#define EXTI_INTEN_INTEN26           BIT(26)                  /*!< interrupt from line 26 */
+#define EXTI_INTEN_INTEN27           BIT(27)                  /*!< interrupt from line 27 */
+
+/* EXTI_EVEN */
+#define EXTI_EVEN_EVEN0              BIT(0)                   /*!< event from line 0 */
+#define EXTI_EVEN_EVEN1              BIT(1)                   /*!< event from line 1 */
+#define EXTI_EVEN_EVEN2              BIT(2)                   /*!< event from line 2 */
+#define EXTI_EVEN_EVEN3              BIT(3)                   /*!< event from line 3 */
+#define EXTI_EVEN_EVEN4              BIT(4)                   /*!< event from line 4 */
+#define EXTI_EVEN_EVEN5              BIT(5)                   /*!< event from line 5 */
+#define EXTI_EVEN_EVEN6              BIT(6)                   /*!< event from line 6 */
+#define EXTI_EVEN_EVEN7              BIT(7)                   /*!< event from line 7 */
+#define EXTI_EVEN_EVEN8              BIT(8)                   /*!< event from line 8 */
+#define EXTI_EVEN_EVEN9              BIT(9)                   /*!< event from line 9 */
+#define EXTI_EVEN_EVEN10             BIT(10)                  /*!< event from line 10 */
+#define EXTI_EVEN_EVEN11             BIT(11)                  /*!< event from line 11 */
+#define EXTI_EVEN_EVEN12             BIT(12)                  /*!< event from line 12 */
+#define EXTI_EVEN_EVEN13             BIT(13)                  /*!< event from line 13 */
+#define EXTI_EVEN_EVEN14             BIT(14)                  /*!< event from line 14 */
+#define EXTI_EVEN_EVEN15             BIT(15)                  /*!< event from line 15 */
+#define EXTI_EVEN_EVEN16             BIT(16)                  /*!< event from line 16 */
+#define EXTI_EVEN_EVEN17             BIT(17)                  /*!< event from line 17 */
+#define EXTI_EVEN_EVEN18             BIT(18)                  /*!< event from line 18 */
+#define EXTI_EVEN_EVEN19             BIT(19)                  /*!< event from line 19 */
+#define EXTI_EVEN_EVEN20             BIT(20)                  /*!< event from line 20 */
+#define EXTI_EVEN_EVEN21             BIT(21)                  /*!< event from line 21 */
+#define EXTI_EVEN_EVEN22             BIT(22)                  /*!< event from line 22 */
+#define EXTI_EVEN_EVEN23             BIT(23)                  /*!< event from line 23 */
+#define EXTI_EVEN_EVEN24             BIT(24)                  /*!< event from line 24 */
+#define EXTI_EVEN_EVEN25             BIT(25)                  /*!< event from line 25 */
+#define EXTI_EVEN_EVEN26             BIT(26)                  /*!< event from line 26 */
+#define EXTI_EVEN_EVEN27             BIT(27)                  /*!< event from line 27 */
+
+/* EXTI_RTEN */
+#define EXTI_RTEN_RTEN0              BIT(0)                   /*!< rising edge from line 0 */
+#define EXTI_RTEN_RTEN1              BIT(1)                   /*!< rising edge from line 1 */
+#define EXTI_RTEN_RTEN2              BIT(2)                   /*!< rising edge from line 2 */
+#define EXTI_RTEN_RTEN3              BIT(3)                   /*!< rising edge from line 3 */
+#define EXTI_RTEN_RTEN4              BIT(4)                   /*!< rising edge from line 4 */
+#define EXTI_RTEN_RTEN5              BIT(5)                   /*!< rising edge from line 5 */
+#define EXTI_RTEN_RTEN6              BIT(6)                   /*!< rising edge from line 6 */
+#define EXTI_RTEN_RTEN7              BIT(7)                   /*!< rising edge from line 7 */
+#define EXTI_RTEN_RTEN8              BIT(8)                   /*!< rising edge from line 8 */
+#define EXTI_RTEN_RTEN9              BIT(9)                   /*!< rising edge from line 9 */
+#define EXTI_RTEN_RTEN10             BIT(10)                  /*!< rising edge from line 10 */
+#define EXTI_RTEN_RTEN11             BIT(11)                  /*!< rising edge from line 11 */
+#define EXTI_RTEN_RTEN12             BIT(12)                  /*!< rising edge from line 12 */
+#define EXTI_RTEN_RTEN13             BIT(13)                  /*!< rising edge from line 13 */
+#define EXTI_RTEN_RTEN14             BIT(14)                  /*!< rising edge from line 14 */
+#define EXTI_RTEN_RTEN15             BIT(15)                  /*!< rising edge from line 15 */
+#define EXTI_RTEN_RTEN16             BIT(16)                  /*!< rising edge from line 16 */
+#define EXTI_RTEN_RTEN17             BIT(17)                  /*!< rising edge from line 17 */
+#define EXTI_RTEN_RTEN19             BIT(19)                  /*!< rising edge from line 19 */
+#define EXTI_RTEN_RTEN21             BIT(21)                  /*!< rising edge from line 21 */
+
+/* EXTI_FTEN */
+#define EXTI_FTEN_FTEN0              BIT(0)                   /*!< falling edge from line 0 */
+#define EXTI_FTEN_FTEN1              BIT(1)                   /*!< falling edge from line 1 */
+#define EXTI_FTEN_FTEN2              BIT(2)                   /*!< falling edge from line 2 */
+#define EXTI_FTEN_FTEN3              BIT(3)                   /*!< falling edge from line 3 */
+#define EXTI_FTEN_FTEN4              BIT(4)                   /*!< falling edge from line 4 */
+#define EXTI_FTEN_FTEN5              BIT(5)                   /*!< falling edge from line 5 */
+#define EXTI_FTEN_FTEN6              BIT(6)                   /*!< falling edge from line 6 */
+#define EXTI_FTEN_FTEN7              BIT(7)                   /*!< falling edge from line 7 */
+#define EXTI_FTEN_FTEN8              BIT(8)                   /*!< falling edge from line 8 */
+#define EXTI_FTEN_FTEN9              BIT(9)                   /*!< falling edge from line 9 */
+#define EXTI_FTEN_FTEN10             BIT(10)                  /*!< falling edge from line 10 */
+#define EXTI_FTEN_FTEN11             BIT(11)                  /*!< falling edge from line 11 */
+#define EXTI_FTEN_FTEN12             BIT(12)                  /*!< falling edge from line 12 */
+#define EXTI_FTEN_FTEN13             BIT(13)                  /*!< falling edge from line 13 */
+#define EXTI_FTEN_FTEN14             BIT(14)                  /*!< falling edge from line 14 */
+#define EXTI_FTEN_FTEN15             BIT(15)                  /*!< falling edge from line 15 */
+#define EXTI_FTEN_FTEN16             BIT(16)                  /*!< falling edge from line 16 */
+#define EXTI_FTEN_FTEN17             BIT(17)                  /*!< falling edge from line 17 */
+#define EXTI_FTEN_FTEN19             BIT(19)                  /*!< falling edge from line 19 */
+#define EXTI_FTEN_FTEN21             BIT(21)                  /*!< falling edge from line 21 */
+
+/* EXTI_SWIEV */
+#define EXTI_SWIEV_SWIEV0            BIT(0)                   /*!< software interrupt/event request from line 0 */
+#define EXTI_SWIEV_SWIEV1            BIT(1)                   /*!< software interrupt/event request from line 1 */
+#define EXTI_SWIEV_SWIEV2            BIT(2)                   /*!< software interrupt/event request from line 2 */
+#define EXTI_SWIEV_SWIEV3            BIT(3)                   /*!< software interrupt/event request from line 3 */
+#define EXTI_SWIEV_SWIEV4            BIT(4)                   /*!< software interrupt/event request from line 4 */
+#define EXTI_SWIEV_SWIEV5            BIT(5)                   /*!< software interrupt/event request from line 5 */
+#define EXTI_SWIEV_SWIEV6            BIT(6)                   /*!< software interrupt/event request from line 6 */
+#define EXTI_SWIEV_SWIEV7            BIT(7)                   /*!< software interrupt/event request from line 7 */
+#define EXTI_SWIEV_SWIEV8            BIT(8)                   /*!< software interrupt/event request from line 8 */
+#define EXTI_SWIEV_SWIEV9            BIT(9)                   /*!< software interrupt/event request from line 9 */
+#define EXTI_SWIEV_SWIEV10           BIT(10)                  /*!< software interrupt/event request from line 10 */
+#define EXTI_SWIEV_SWIEV11           BIT(11)                  /*!< software interrupt/event request from line 11 */
+#define EXTI_SWIEV_SWIEV12           BIT(12)                  /*!< software interrupt/event request from line 12 */
+#define EXTI_SWIEV_SWIEV13           BIT(13)                  /*!< software interrupt/event request from line 13 */
+#define EXTI_SWIEV_SWIEV14           BIT(14)                  /*!< software interrupt/event request from line 14 */
+#define EXTI_SWIEV_SWIEV15           BIT(15)                  /*!< software interrupt/event request from line 15 */
+#define EXTI_SWIEV_SWIEV16           BIT(16)                  /*!< software interrupt/event request from line 16 */
+#define EXTI_SWIEV_SWIEV17           BIT(17)                  /*!< software interrupt/event request from line 17 */
+#define EXTI_SWIEV_SWIEV19           BIT(19)                  /*!< software interrupt/event request from line 19 */
+#define EXTI_SWIEV_SWIEV21           BIT(21)                  /*!< software interrupt/event request from line 21 */
+
+/* EXTI_PD */
+#define EXTI_PD_PD0                  BIT(0)                   /*!< interrupt/event pending status from line 0 */
+#define EXTI_PD_PD1                  BIT(1)                   /*!< interrupt/event pending status from line 1 */
+#define EXTI_PD_PD2                  BIT(2)                   /*!< interrupt/event pending status from line 2 */
+#define EXTI_PD_PD3                  BIT(3)                   /*!< interrupt/event pending status from line 3 */
+#define EXTI_PD_PD4                  BIT(4)                   /*!< interrupt/event pending status from line 4 */
+#define EXTI_PD_PD5                  BIT(5)                   /*!< interrupt/event pending status from line 5 */
+#define EXTI_PD_PD6                  BIT(6)                   /*!< interrupt/event pending status from line 6 */
+#define EXTI_PD_PD7                  BIT(7)                   /*!< interrupt/event pending status from line 7 */
+#define EXTI_PD_PD8                  BIT(8)                   /*!< interrupt/event pending status from line 8 */
+#define EXTI_PD_PD9                  BIT(9)                   /*!< interrupt/event pending status from line 9 */
+#define EXTI_PD_PD10                 BIT(10)                  /*!< interrupt/event pending status from line 10 */
+#define EXTI_PD_PD11                 BIT(11)                  /*!< interrupt/event pending status from line 11 */
+#define EXTI_PD_PD12                 BIT(12)                  /*!< interrupt/event pending status from line 12 */
+#define EXTI_PD_PD13                 BIT(13)                  /*!< interrupt/event pending status from line 13 */
+#define EXTI_PD_PD14                 BIT(14)                  /*!< interrupt/event pending status from line 14 */
+#define EXTI_PD_PD15                 BIT(15)                  /*!< interrupt/event pending status from line 15 */
+#define EXTI_PD_PD16                 BIT(16)                  /*!< interrupt/event pending status from line 16 */
+#define EXTI_PD_PD17                 BIT(17)                  /*!< interrupt/event pending status from line 17 */
+#define EXTI_PD_PD19                 BIT(19)                  /*!< interrupt/event pending status from line 19 */
+#define EXTI_PD_PD21                 BIT(21)                  /*!< interrupt/event pending status from line 21 */
+
+/* constants definitions */
+/* EXTI line number */
+typedef enum
+{ 
+    EXTI_0      = BIT(0),                                     /*!< EXTI line 0 */
+    EXTI_1      = BIT(1),                                     /*!< EXTI line 1 */
+    EXTI_2      = BIT(2),                                     /*!< EXTI line 2 */
+    EXTI_3      = BIT(3),                                     /*!< EXTI line 3 */
+    EXTI_4      = BIT(4),                                     /*!< EXTI line 4 */
+    EXTI_5      = BIT(5),                                     /*!< EXTI line 5 */
+    EXTI_6      = BIT(6),                                     /*!< EXTI line 6 */
+    EXTI_7      = BIT(7),                                     /*!< EXTI line 7 */
+    EXTI_8      = BIT(8),                                     /*!< EXTI line 8 */
+    EXTI_9      = BIT(9),                                     /*!< EXTI line 9 */
+    EXTI_10     = BIT(10),                                    /*!< EXTI line 10 */
+    EXTI_11     = BIT(11),                                    /*!< EXTI line 11 */
+    EXTI_12     = BIT(12),                                    /*!< EXTI line 12 */
+    EXTI_13     = BIT(13),                                    /*!< EXTI line 13 */
+    EXTI_14     = BIT(14),                                    /*!< EXTI line 14 */
+    EXTI_15     = BIT(15),                                    /*!< EXTI line 15 */
+    EXTI_16     = BIT(16),                                    /*!< EXTI line 16 */
+    EXTI_17     = BIT(17),                                    /*!< EXTI line 17 */
+    EXTI_18     = BIT(18),                                    /*!< EXTI line 18 */
+    EXTI_19     = BIT(19),                                    /*!< EXTI line 19 */
+    EXTI_20     = BIT(20),                                    /*!< EXTI line 20 */    
+    EXTI_21     = BIT(21),                                    /*!< EXTI line 21 */
+    EXTI_22     = BIT(22),                                    /*!< EXTI line 22 */
+    EXTI_23     = BIT(23),                                    /*!< EXTI line 23 */
+    EXTI_24     = BIT(24),                                    /*!< EXTI line 24 */
+    EXTI_25     = BIT(25),                                    /*!< EXTI line 25 */
+    EXTI_26     = BIT(26),                                    /*!< EXTI line 26 */
+    EXTI_27     = BIT(27),                                    /*!< EXTI line 27 */
+}exti_line_enum;
+
+/* external interrupt and event */
+typedef enum
+{
+    EXTI_INTERRUPT   = 0,                                     /*!< EXTI interrupt mode */
+    EXTI_EVENT                                                /*!< EXTI event mode */
+}exti_mode_enum;
+
+/* interrupt trigger mode */
+typedef enum
+{ 
+    EXTI_TRIG_RISING = 0,                                     /*!< EXTI rising edge trigger */
+    EXTI_TRIG_FALLING,                                        /*!< EXTI falling edge trigger */
+    EXTI_TRIG_BOTH                                            /*!< EXTI rising and falling edge trigger */
+}exti_trig_type_enum;
+
+/* function declarations */
+/* deinitialize the EXTI */
+void exti_deinit(void);
+/* enable the configuration of EXTI initialize */
+void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type);
+/* enable the interrupts from EXTI line x */
+void exti_interrupt_enable(exti_line_enum linex);
+/* enable the events from EXTI line x */
+void exti_event_enable(exti_line_enum linex);
+/* disable the interrupts from EXTI line x */
+void exti_interrupt_disable(exti_line_enum linex);
+/* disable the events from EXTI line x */
+void exti_event_disable(exti_line_enum linex);
+
+/* get EXTI lines pending flag */
+FlagStatus exti_flag_get(exti_line_enum linex);
+/* clear EXTI lines pending flag */
+void exti_flag_clear(exti_line_enum linex);
+/* get EXTI lines flag when the interrupt flag is set */
+FlagStatus exti_interrupt_flag_get(exti_line_enum linex);
+/* clear EXTI lines pending flag */
+void exti_interrupt_flag_clear(exti_line_enum linex);
+/* EXTI software interrupt event enable */
+void exti_software_interrupt_enable(exti_line_enum linex);
+/* EXTI software interrupt event disable */
+void exti_software_interrupt_disable(exti_line_enum linex);
+
+#endif /* GD32E230_EXTI_H */

+ 272 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h

@@ -0,0 +1,272 @@
+/*!
+    \file  gd32e230_fmc.h
+    \brief definitions for the FMC
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_FMC_H
+#define GD32E230_FMC_H
+
+#include "gd32e230.h"
+
+/* FMC and option byte definition */
+#define FMC                     FMC_BASE                    /*!< FMC register base address */
+#define OB                      OB_BASE                     /*!< option byte base address */
+
+/* registers definitions */
+#define FMC_WS                  REG32((FMC) + 0x00U)        /*!< FMC wait state register */
+#define FMC_KEY                 REG32((FMC) + 0x04U)        /*!< FMC unlock key register */
+#define FMC_OBKEY               REG32((FMC) + 0x08U)        /*!< FMC option bytes unlock key register */
+#define FMC_STAT                REG32((FMC) + 0x0CU)        /*!< FMC status register */
+#define FMC_CTL                 REG32((FMC) + 0x10U)        /*!< FMC control register */
+#define FMC_ADDR                REG32((FMC) + 0x14U)        /*!< FMC address register */
+#define FMC_OBSTAT              REG32((FMC) + 0x1CU)        /*!< FMC option bytes status register */
+#define FMC_WP                  REG32((FMC) + 0x20U)        /*!< FMC write protection register */
+#define FMC_PID                 REG32((FMC) + 0x100U)       /*!< FMC product ID register */
+
+#define OB_SPC_USER             REG32((OB) + 0x00U)         /*!< option byte security protection value and user value */
+#define OB_DATA                 REG32((OB) + 0x04U)         /*!< option byte data value*/
+#define OB_WP                   REG32((OB) + 0x08U)         /*!< option byte write protection */
+
+/* bits definitions */
+/* FMC_WS */
+#define FMC_WS_WSCNT            BITS(0,2)                   /*!< wait state counter */
+#define FMC_WS_PFEN             BIT(4)                      /*!< pre-fetch enable */
+#define FMC_WS_PGW              BIT(15)                     /*!< program width to flash memory */
+
+/* FMC_KEY */
+#define FMC_KEY_KEY             BITS(0,31)                  /*!< FMC main flash unlock key bits */
+
+/* FMC_OBKEY */
+#define FMC_OBKEY_OBKEY         BITS(0,31)                  /*!< option bytes unlock key bits */
+
+/* FMC_STAT */
+#define FMC_STAT_BUSY           BIT(0)                      /*!< flash busy flag bit */
+#define FMC_STAT_PGERR          BIT(2)                      /*!< flash program error flag bit */
+#define FMC_STAT_PGAERR         BIT(3)                      /*!< program alignment error flag bit */
+#define FMC_STAT_WPERR          BIT(4)                      /*!< flash write protection error flag bit */
+#define FMC_STAT_ENDF           BIT(5)                      /*!< end of operation flag bit */
+
+/* FMC_CTL */
+#define FMC_CTL_PG              BIT(0)                      /*!< main flash program command bit */
+#define FMC_CTL_PER             BIT(1)                      /*!< main flash page erase bit */
+#define FMC_CTL_MER             BIT(2)                      /*!< main flash mass erase bit */
+#define FMC_CTL_OBPG            BIT(4)                      /*!< option bytes program command bit */
+#define FMC_CTL_OBER            BIT(5)                      /*!< option bytes erase command bit */
+#define FMC_CTL_START           BIT(6)                      /*!< send erase command to FMC bit */
+#define FMC_CTL_LK              BIT(7)                      /*!< flash lock bit */
+#define FMC_CTL_OBWEN           BIT(9)                      /*!< option bytes erase/program enable bit */
+#define FMC_CTL_ERRIE           BIT(10)                     /*!< error interrupt enable bit */
+#define FMC_CTL_ENDIE           BIT(12)                     /*!< end of operation interrupt enable bit */
+#define FMC_CTL_OBRLD           BIT(13)                     /*!< option bytes reload bit */
+
+/* FMC_ADDR */
+#define FMC_ADDR_ADDR           BITS(0,31)                  /*!< flash command address bits */
+
+/* FMC_OBSTAT */
+#define FMC_OBSTAT_OBERR        BIT(0)                      /*!< option bytes read error bit */
+#define FMC_OBSTAT_PLEVEL_BIT0  BIT(1)                      /*!< protection level bit 0 */
+#define FMC_OBSTAT_PLEVEL_BIT1  BIT(2)                      /*!< protection level bit 1 */
+#define FMC_OBSTAT_USER         BITS(8,15)                  /*!< option bytes user bits */
+#define FMC_OBSTAT_DATA         BITS(16,31)                 /*!< option byte data bits */
+
+/* FMC_WP */
+#define FMC_WP_WP               BITS(0,15)                  /*!< store WP[15:0] of option byte block after system reset */
+
+/* FMC_PID */
+#define FMC_PID_PID             BITS(0,31)                  /*!< product ID bits */
+
+/* constants definitions */
+/* fmc state */
+typedef enum
+{
+    FMC_READY,                                              /*!< the operation has been completed */
+    FMC_BUSY,                                               /*!< the operation is in progress */
+    FMC_PGERR,                                              /*!< program error */
+    FMC_PGAERR,                                             /*!< program alignment error */
+    FMC_WPERR,                                              /*!< erase/program protection error */
+    FMC_TOERR,                                              /*!< timeout error */
+    FMC_OB_HSPC                                             /*!< option byte security protection code high */
+}fmc_state_enum;
+
+/* unlock key */
+#define UNLOCK_KEY0                ((uint32_t)0x45670123U)  /*!< unlock key 0 */
+#define UNLOCK_KEY1                ((uint32_t)0xCDEF89ABU)  /*!< unlock key 1 */
+
+/* wait state counter value */
+#define WS_WSCNT_0                 ((uint8_t)0x00U)         /*!< 0 wait state added */
+#define WS_WSCNT_1                 ((uint8_t)0x01U)         /*!< 1 wait state added */
+#define WS_WSCNT_2                 ((uint8_t)0x02U)         /*!< 2 wait state added */
+
+/* read protect configure */
+#define FMC_NSPC                   ((uint16_t)0x5AA5U)      /*!< no security protection */
+#define FMC_LSPC                   ((uint16_t)0x44BBU)      /*!< low security protection, any value except 0xA5 or 0xCC */
+#define FMC_HSPC                   ((uint16_t)0x33CCU)      /*!< high security protection */
+
+#define LOW_16BITS_MASK            ((uint32_t)0x0000FFFFU)  /*!< low 16 bits mask  */
+#define HIGH_16BITS_MASK           ((uint32_t)0xFFFF0000U)  /*!< high 16 bits mask  */
+
+/* option byte address */
+#define OB_SPC_USER_ADDRESS        ((uint32_t)0x1FFFF800U)  /*!< address of option byte security protection and user */
+#define OB_DATA_ADDRESS            ((uint32_t)0x1FFFF804U)  /*!< address of option byte data */
+#define OB_WP_ADDRESS              ((uint32_t)0x1FFFF808U)  /*!< address of option byte write protection */
+
+/* option byte write protection */
+#define OB_LWP                     ((uint32_t)0x000000FFU)  /*!< write protection low bits */
+#define OB_HWP                     ((uint32_t)0x0000FF00U)  /*!< write protection high bits */
+
+/* option byte software/hardware free watchdog timer */  
+#define OB_FWDGT_HW                ((uint8_t)(~BIT(0)))     /*!< hardware free watchdog timer */
+#define OB_FWDGT_SW                ((uint8_t)BIT(0))        /*!< software free watchdog timer */
+
+/* option byte reset or not entering deep sleep mode */
+#define OB_DEEPSLEEP_RST           ((uint8_t)(~BIT(1)))     /*!< generate a reset instead of entering deepsleep mode */
+#define OB_DEEPSLEEP_NRST          ((uint8_t)BIT(1))        /*!< no reset when entering deepsleep mode */
+
+/* option byte reset or not entering standby mode */
+#define OB_STDBY_RST               ((uint8_t)(~BIT(2)))     /*!< generate a reset instead of entering standby mode */
+#define OB_STDBY_NRST              ((uint8_t)BIT(2))        /*!< no reset when entering deepsleep mode */
+
+/* option byte OB_BOOT1_n set */
+#define OB_BOOT1_SET_1             ((uint8_t)(~BIT(4)))     /*!< BOOT1 bit is 1 */
+#define OB_BOOT1_SET_0             ((uint8_t)BIT(4))        /*!< BOOT1 bit is 0 */
+
+/* option byte VDDA monitor enable/disable */
+#define OB_VDDA_DISABLE            ((uint8_t)(~BIT(5)))     /*!< disable VDDA monitor */
+#define OB_VDDA_ENABLE             ((uint8_t)BIT(5))        /*!< enable VDDA monitor */
+
+/* option byte SRAM parity enable/disable */
+#define OB_SRAM_PARITY_ENABLE      ((uint8_t)(~BIT(6)))     /*!< enable SRAM parity check */
+#define OB_SRAM_PARITY_DISABLE     ((uint8_t)BIT(6))        /*!< disable SRAM parity check */
+
+/* option byte security protection level in FMC_OBSTAT register */
+#define OB_OBSTAT_PLEVEL_NO        ((uint8_t)0x00U)         /*!< no security protection */
+#define OB_OBSTAT_PLEVEL_LOW       ((uint8_t)0x01U)         /*!< low security protection */
+#define OB_OBSTAT_PLEVEL_HIGH      ((uint8_t)0x03U)         /*!< high security protection */
+
+/* option byte user mask */
+#define OB_USER_MASK               ((uint8_t)0x88U)         /*!< OB_USER reserved bit mask */
+
+/* option byte data address */
+#define OB_DATA_ADDR0              ((uint32_t)0x1FFFF804U)  /*!< option byte data address 0 */
+#define OB_DATA_ADDR1              ((uint32_t)0x1FFFF806U)  /*!< option byte data address 1 */
+
+/* FMC flags */
+#define FMC_FLAG_BUSY              FMC_STAT_BUSY            /*!< FMC busy flag */
+#define FMC_FLAG_PGERR             FMC_STAT_PGERR           /*!< FMC programming error flag */
+#define FMC_FLAG_PGAERR            FMC_STAT_PGAERR          /*!< FMC program alignment error flag */
+#define FMC_FLAG_WPERR             FMC_STAT_WPERR           /*!< FMC write protection error flag */
+#define FMC_FLAG_END               FMC_STAT_ENDF            /*!< FMC end of programming flag */
+
+/* FMC interrupt flags */
+#define FMC_INT_FLAG_PGERR         FMC_STAT_PGERR           /*!< FMC programming error flag */
+#define FMC_INT_FLAG_PGAERR        FMC_STAT_PGAERR          /*!< FMC program alignment error flag */
+#define FMC_INT_FLAG_WPERR         FMC_STAT_WPERR           /*!< FMC write protection error flag */
+#define FMC_INT_FLAG_END           FMC_STAT_ENDF            /*!< FMC end of programming flag */
+
+/* FMC interrupt enable */
+#define FMC_INTEN_END              FMC_CTL_ENDIE            /*!< enable FMC end of operation interrupt */
+#define FMC_INTEN_ERR              FMC_CTL_ERRIE            /*!< enable FMC error interrupt */
+
+/* FMC time out */
+#define FMC_TIMEOUT_COUNT          ((uint32_t)0x000F0000U)  /*!< count to judge of FMC timeout */
+
+/* function declarations */
+/* FMC main memory programming functions */
+/* unlock the main FMC operation */
+void fmc_unlock(void);
+/* lock the main FMC operation */
+void fmc_lock(void);
+/* set the wait state counter value */
+void fmc_wscnt_set(uint8_t wscnt);
+
+/* pre-fetch enable */
+void fmc_prefetch_enable(void);
+/* pre-fetch disable */
+void fmc_prefetch_disable(void);
+/* FMC erase page */
+fmc_state_enum fmc_page_erase(uint32_t page_address);
+/* FMC erase whole chip */
+fmc_state_enum fmc_mass_erase(void);
+/* FMC program a double word at the corresponding address */
+fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data);
+/* FMC program a word at the corresponding address */
+fmc_state_enum fmc_word_program(uint32_t address, uint32_t data);
+
+/* FMC option bytes programming functions */
+/* unlock the option byte operation */
+void ob_unlock(void);
+/* lock the option byte operation */
+void ob_lock(void);
+/* reload the option byte and generate a system reset */
+void ob_reset(void);
+/* get option byte value */
+uint32_t option_byte_value_get(uint32_t addr);
+/* erase option byte */
+fmc_state_enum ob_erase(void);
+/* enable option byte write protection (OB_WP) */
+fmc_state_enum ob_write_protection_enable(uint16_t ob_wp);
+/* configure read out protect */
+fmc_state_enum ob_security_protection_config(uint16_t ob_spc);
+/* write the FMC option byte user */
+fmc_state_enum ob_user_write(uint8_t ob_user);
+/* write the FMC option byte data */
+fmc_state_enum ob_data_program(uint16_t data);
+/* get the FMC option byte OB_USER */
+uint8_t ob_user_get(void);
+/* get the FMC option byte OB_DATA */
+uint16_t ob_data_get(void);
+/* get the FMC option byte write protection */
+uint16_t ob_write_protection_get(void);
+/* get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register */
+uint32_t ob_obstat_plevel_get(void);
+
+/* FMC interrupts and flags management functions */
+/* enable FMC interrupt */
+void fmc_interrupt_enable(uint32_t interrupt);
+/* disable FMC interrupt */
+void fmc_interrupt_disable(uint32_t interrupt);
+/* get flag set or reset */
+FlagStatus fmc_flag_get(uint32_t flag);
+/* clear the FMC pending flag */
+void fmc_flag_clear(uint32_t flag);
+/* get intrrupt flag set or reset */
+FlagStatus fmc_interrupt_flag_get(uint32_t int_flag);
+/* clear the FMC interrupt pending flag by writing 1 */
+void fmc_interrupt_flag_clear(uint32_t int_flag);
+/* return the FMC state */
+fmc_state_enum fmc_state_get(void);
+/* check FMC ready or not */
+fmc_state_enum fmc_ready_wait(uint32_t timeout);
+
+#endif /* GD32E230_FMC_H */

+ 119 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h

@@ -0,0 +1,119 @@
+/*!
+    \file  gd32e230_fwdgt.h
+    \brief definitions for the FWDGT 
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_FWDGT_H
+#define GD32E230_FWDGT_H
+
+#include "gd32e230.h"
+
+/* FWDGT definitions */
+#define FWDGT                       FWDGT_BASE
+
+/* registers definitions */
+#define FWDGT_CTL                   REG32((FWDGT) + 0x00000000U)                     /*!< FWDGT control register */
+#define FWDGT_PSC                   REG32((FWDGT) + 0x00000004U)                     /*!< FWDGT prescaler register */
+#define FWDGT_RLD                   REG32((FWDGT) + 0x00000008U)                     /*!< FWDGT reload register */
+#define FWDGT_STAT                  REG32((FWDGT) + 0x0000000CU)                     /*!< FWDGT status register */
+#define FWDGT_WND                   REG32((FWDGT) + 0x00000010U)                     /*!< FWDGT window register */
+
+/* bits definitions */
+/* FWDGT_CTL */
+#define FWDGT_CTL_CMD               BITS(0,15)                                 /*!< FWDGT command value */
+
+/* FWDGT_PSC */
+#define FWDGT_PSC_PSC               BITS(0,2)                                  /*!< FWDGT prescaler divider value */
+
+/* FWDGT_RLD */
+#define FWDGT_RLD_RLD               BITS(0,11)                                 /*!< FWDGT counter reload value */
+
+/* FWDGT_STAT */
+#define FWDGT_STAT_PUD              BIT(0)                                     /*!< FWDGT prescaler divider value update */
+#define FWDGT_STAT_RUD              BIT(1)                                     /*!< FWDGT counter reload value update */
+#define FWDGT_STAT_WUD              BIT(2)                                     /*!< FWDGT counter window value update */
+
+/* FWDGT_WND */
+#define FWDGT_WND_WND               BITS(0,11)                                 /*!< FWDGT counter window value */
+
+/* constants definitions */
+/* FWDGT_PSC register value */
+#define PSC_PSC(regval)             (BITS(0,2) & ((uint32_t)(regval) << 0U))
+#define FWDGT_PSC_DIV4              ((uint8_t)PSC_PSC(0))                      /*!< FWDGT prescaler set to 4 */
+#define FWDGT_PSC_DIV8              ((uint8_t)PSC_PSC(1))                      /*!< FWDGT prescaler set to 8 */
+#define FWDGT_PSC_DIV16             ((uint8_t)PSC_PSC(2))                      /*!< FWDGT prescaler set to 16 */
+#define FWDGT_PSC_DIV32             ((uint8_t)PSC_PSC(3))                      /*!< FWDGT prescaler set to 32 */
+#define FWDGT_PSC_DIV64             ((uint8_t)PSC_PSC(4))                      /*!< FWDGT prescaler set to 64 */
+#define FWDGT_PSC_DIV128            ((uint8_t)PSC_PSC(5))                      /*!< FWDGT prescaler set to 128 */
+#define FWDGT_PSC_DIV256            ((uint8_t)PSC_PSC(6))                      /*!< FWDGT prescaler set to 256 */
+
+/* control value */
+#define FWDGT_WRITEACCESS_ENABLE    ((uint16_t)0x00005555U)                    /*!< FWDGT_CTL bits write access enable value */
+#define FWDGT_WRITEACCESS_DISABLE   ((uint16_t)0x00000000U)                    /*!< FWDGT_CTL bits write access disable value */
+#define FWDGT_KEY_RELOAD            ((uint16_t)0x0000AAAAU)                    /*!< FWDGT_CTL bits fwdgt counter reload value */
+#define FWDGT_KEY_ENABLE            ((uint16_t)0x0000CCCCU)                    /*!< FWDGT_CTL bits fwdgt counter enable value */
+
+/* FWDGT timeout value */
+#define FWDGT_WND_TIMEOUT           ((uint32_t)0x000FFFFFU)                    /*!< FWDGT_WND register write operation state flag timeout */
+#define FWDGT_PSC_TIMEOUT           ((uint32_t)0x000FFFFFU)                    /*!< FWDGT_PSC register write operation state flag timeout */
+#define FWDGT_RLD_TIMEOUT           ((uint32_t)0x000FFFFFU)                    /*!< FWDGT_RLD register write operation state flag timeout */
+
+/* FWDGT flag definitions */
+#define FWDGT_FLAG_PUD              FWDGT_STAT_PUD                             /*!< a write operation to FWDGT_PSC register is on going */
+#define FWDGT_FLAG_RUD              FWDGT_STAT_RUD                             /*!< a write operation to FWDGT_RLD register is on going */
+#define FWDGT_FLAG_WUD              FWDGT_STAT_WUD                             /*!< a write operation to FWDGT_WND register is on going */
+
+/* function declarations */
+/* enable write access to FWDGT_PSC and FWDGT_RLD */
+void fwdgt_write_enable(void);
+/* disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND */
+void fwdgt_write_disable(void);
+/* start the free watchdog timer counter */
+void fwdgt_enable(void);
+
+/* configure the free watchdog timer counter prescaler value */
+ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value);
+/* configure the free watchdog timer counter reload value */
+ErrStatus fwdgt_reload_value_config(uint16_t reload_value);
+/* configure the free watchdog timer counter window value */
+ErrStatus fwdgt_window_value_config(uint16_t window_value);
+/* reload the counter of FWDGT */
+void fwdgt_counter_reload(void);
+/* configure counter reload value, and prescaler divider value */
+ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div);
+
+/* get flag state of FWDGT */
+FlagStatus fwdgt_flag_get(uint16_t flag);
+
+#endif /* GD32E230_FWDGT_H */

+ 388 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h

@@ -0,0 +1,388 @@
+/*!
+    \file    gd32e230_gpio.h
+    \brief   definitions for the GPIO
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_GPIO_H
+#define GD32E230_GPIO_H
+
+#include "gd32e230.h"
+
+/* GPIOx(x=A,B,C,F) definitions */
+#define GPIOA                      (GPIO_BASE + 0x00000000U)
+#define GPIOB                      (GPIO_BASE + 0x00000400U)
+#define GPIOC                      (GPIO_BASE + 0x00000800U)
+#define GPIOF                      (GPIO_BASE + 0x00001400U)
+
+/* registers definitions */
+#define GPIO_CTL(gpiox)            REG32((gpiox) + 0x00U)    /*!< GPIO port control register */
+#define GPIO_OMODE(gpiox)          REG32((gpiox) + 0x04U)    /*!< GPIO port output mode register */
+#define GPIO_OSPD(gpiox)           REG32((gpiox) + 0x08U)    /*!< GPIO port output speed register */
+#define GPIO_PUD(gpiox)            REG32((gpiox) + 0x0CU)    /*!< GPIO port pull-up/pull-down register */
+#define GPIO_ISTAT(gpiox)          REG32((gpiox) + 0x10U)    /*!< GPIO port input status register */
+#define GPIO_OCTL(gpiox)           REG32((gpiox) + 0x14U)    /*!< GPIO port output control register */
+#define GPIO_BOP(gpiox)            REG32((gpiox) + 0x18U)    /*!< GPIO port bit operation register */
+#define GPIO_LOCK(gpiox)           REG32((gpiox) + 0x1CU)    /*!< GPIO port configuration lock register */
+#define GPIO_AFSEL0(gpiox)         REG32((gpiox) + 0x20U)    /*!< GPIO alternate function selected register 0 */
+#define GPIO_AFSEL1(gpiox)         REG32((gpiox) + 0x24U)    /*!< GPIO alternate function selected register 1 */
+#define GPIO_BC(gpiox)             REG32((gpiox) + 0x28U)    /*!< GPIO bit clear register */
+#define GPIO_TG(gpiox)             REG32((gpiox) + 0x2CU)    /*!< GPIO port bit toggle register */
+
+/* bits definitions */
+/* GPIO_CTL */
+#define GPIO_CTL_CTL0              BITS(0,1)             /*!< pin 0 configuration bits */ 
+#define GPIO_CTL_CTL1              BITS(2,3)             /*!< pin 1 configuration bits */
+#define GPIO_CTL_CTL2              BITS(4,5)             /*!< pin 2 configuration bits */
+#define GPIO_CTL_CTL3              BITS(6,7)             /*!< pin 3 configuration bits */
+#define GPIO_CTL_CTL4              BITS(8,9)             /*!< pin 4 configuration bits */
+#define GPIO_CTL_CTL5              BITS(10,11)           /*!< pin 5 configuration bits */
+#define GPIO_CTL_CTL6              BITS(12,13)           /*!< pin 6 configuration bits */
+#define GPIO_CTL_CTL7              BITS(14,15)           /*!< pin 7 configuration bits */
+#define GPIO_CTL_CTL8              BITS(16,17)           /*!< pin 8 configuration bits */
+#define GPIO_CTL_CTL9              BITS(18,19)           /*!< pin 9 configuration bits */
+#define GPIO_CTL_CTL10             BITS(20,21)           /*!< pin 10 configuration bits */
+#define GPIO_CTL_CTL11             BITS(22,23)           /*!< pin 11 configuration bits */
+#define GPIO_CTL_CTL12             BITS(24,25)           /*!< pin 12 configuration bits */
+#define GPIO_CTL_CTL13             BITS(26,27)           /*!< pin 13 configuration bits */
+#define GPIO_CTL_CTL14             BITS(28,29)           /*!< pin 14 configuration bits */
+#define GPIO_CTL_CTL15             BITS(30,31)           /*!< pin 15 configuration bits */
+
+/* GPIO_OMODE */
+#define GPIO_OMODE_OM0             BIT(0)                /*!< pin 0 output mode bit */
+#define GPIO_OMODE_OM1             BIT(1)                /*!< pin 1 output mode bit */
+#define GPIO_OMODE_OM2             BIT(2)                /*!< pin 2 output mode bit */
+#define GPIO_OMODE_OM3             BIT(3)                /*!< pin 3 output mode bit */
+#define GPIO_OMODE_OM4             BIT(4)                /*!< pin 4 output mode bit */
+#define GPIO_OMODE_OM5             BIT(5)                /*!< pin 5 output mode bit */
+#define GPIO_OMODE_OM6             BIT(6)                /*!< pin 6 output mode bit */
+#define GPIO_OMODE_OM7             BIT(7)                /*!< pin 7 output mode bit */
+#define GPIO_OMODE_OM8             BIT(8)                /*!< pin 8 output mode bit */
+#define GPIO_OMODE_OM9             BIT(9)                /*!< pin 9 output mode bit */
+#define GPIO_OMODE_OM10            BIT(10)               /*!< pin 10 output mode bit */
+#define GPIO_OMODE_OM11            BIT(11)               /*!< pin 11 output mode bit */
+#define GPIO_OMODE_OM12            BIT(12)               /*!< pin 12 output mode bit */
+#define GPIO_OMODE_OM13            BIT(13)               /*!< pin 13 output mode bit */
+#define GPIO_OMODE_OM14            BIT(14)               /*!< pin 14 output mode bit */
+#define GPIO_OMODE_OM15            BIT(15)               /*!< pin 15 output mode bit */
+
+/* GPIO_OSPD */
+#define GPIO_OSPD_OSPD0           BITS(0,1)              /*!< pin 0 output max speed bits */
+#define GPIO_OSPD_OSPD1           BITS(2,3)              /*!< pin 1 output max speed bits */
+#define GPIO_OSPD_OSPD2           BITS(4,5)              /*!< pin 2 output max speed bits */
+#define GPIO_OSPD_OSPD3           BITS(6,7)              /*!< pin 3 output max speed bits */
+#define GPIO_OSPD_OSPD4           BITS(8,9)              /*!< pin 4 output max speed bits */
+#define GPIO_OSPD_OSPD5           BITS(10,11)            /*!< pin 5 output max speed bits */
+#define GPIO_OSPD_OSPD6           BITS(12,13)            /*!< pin 6 output max speed bits */
+#define GPIO_OSPD_OSPD7           BITS(14,15)            /*!< pin 7 output max speed bits */
+#define GPIO_OSPD_OSPD8           BITS(16,17)            /*!< pin 8 output max speed bits */
+#define GPIO_OSPD_OSPD9           BITS(18,19)            /*!< pin 9 output max speed bits */
+#define GPIO_OSPD_OSPD10          BITS(20,21)            /*!< pin 10 output max speed bits */
+#define GPIO_OSPD_OSPD11          BITS(22,23)            /*!< pin 11 output max speed bits */
+#define GPIO_OSPD_OSPD12          BITS(24,25)            /*!< pin 12 output max speed bits */
+#define GPIO_OSPD_OSPD13          BITS(26,27)            /*!< pin 13 output max speed bits */
+#define GPIO_OSPD_OSPD14          BITS(28,29)            /*!< pin 14 output max speed bits */
+#define GPIO_OSPD_OSPD15          BITS(30,31)            /*!< pin 15 output max speed bits */
+
+/* GPIO_PUD */
+#define GPIO_PUD_PUD0              BITS(0,1)             /*!< pin 0 pull-up or pull-down bits */
+#define GPIO_PUD_PUD1              BITS(2,3)             /*!< pin 1 pull-up or pull-down bits */
+#define GPIO_PUD_PUD2              BITS(4,5)             /*!< pin 2 pull-up or pull-down bits */
+#define GPIO_PUD_PUD3              BITS(6,7)             /*!< pin 3 pull-up or pull-down bits */
+#define GPIO_PUD_PUD4              BITS(8,9)             /*!< pin 4 pull-up or pull-down bits */
+#define GPIO_PUD_PUD5              BITS(10,11)           /*!< pin 5 pull-up or pull-down bits */
+#define GPIO_PUD_PUD6              BITS(12,13)           /*!< pin 6 pull-up or pull-down bits */
+#define GPIO_PUD_PUD7              BITS(14,15)           /*!< pin 7 pull-up or pull-down bits */
+#define GPIO_PUD_PUD8              BITS(16,17)           /*!< pin 8 pull-up or pull-down bits */
+#define GPIO_PUD_PUD9              BITS(18,19)           /*!< pin 9 pull-up or pull-down bits */
+#define GPIO_PUD_PUD10             BITS(20,21)           /*!< pin 10 pull-up or pull-down bits */
+#define GPIO_PUD_PUD11             BITS(22,23)           /*!< pin 11 pull-up or pull-down bits */
+#define GPIO_PUD_PUD12             BITS(24,25)           /*!< pin 12 pull-up or pull-down bits */
+#define GPIO_PUD_PUD13             BITS(26,27)           /*!< pin 13 pull-up or pull-down bits */
+#define GPIO_PUD_PUD14             BITS(28,29)           /*!< pin 14 pull-up or pull-down bits */
+#define GPIO_PUD_PUD15             BITS(30,31)           /*!< pin 15 pull-up or pull-down bits */
+
+/* GPIO_ISTAT */
+#define GPIO_ISTAT_ISTAT0          BIT(0)                /*!< pin 0 input status */
+#define GPIO_ISTAT_ISTAT1          BIT(1)                /*!< pin 1 input status */
+#define GPIO_ISTAT_ISTAT2          BIT(2)                /*!< pin 2 input status */
+#define GPIO_ISTAT_ISTAT3          BIT(3)                /*!< pin 3 input status */
+#define GPIO_ISTAT_ISTAT4          BIT(4)                /*!< pin 4 input status */
+#define GPIO_ISTAT_ISTAT5          BIT(5)                /*!< pin 5 input status */
+#define GPIO_ISTAT_ISTAT6          BIT(6)                /*!< pin 6 input status */
+#define GPIO_ISTAT_ISTAT7          BIT(7)                /*!< pin 7 input status */
+#define GPIO_ISTAT_ISTAT8          BIT(8)                /*!< pin 8 input status */
+#define GPIO_ISTAT_ISTAT9          BIT(9)                /*!< pin 9 input status */
+#define GPIO_ISTAT_ISTAT10         BIT(10)               /*!< pin 10 input status */
+#define GPIO_ISTAT_ISTAT11         BIT(11)               /*!< pin 11 input status */
+#define GPIO_ISTAT_ISTAT12         BIT(12)               /*!< pin 12 input status */
+#define GPIO_ISTAT_ISTAT13         BIT(13)               /*!< pin 13 input status */
+#define GPIO_ISTAT_ISTAT14         BIT(14)               /*!< pin 14 input status */
+#define GPIO_ISTAT_ISTAT15         BIT(15)               /*!< pin 15 input status */
+
+/* GPIO_OCTL */
+#define GPIO_OCTL_OCTL0            BIT(0)                /*!< pin 0 output bit */
+#define GPIO_OCTL_OCTL1            BIT(1)                /*!< pin 1 output bit */
+#define GPIO_OCTL_OCTL2            BIT(2)                /*!< pin 2 output bit */
+#define GPIO_OCTL_OCTL3            BIT(3)                /*!< pin 3 output bit */
+#define GPIO_OCTL_OCTL4            BIT(4)                /*!< pin 4 output bit */
+#define GPIO_OCTL_OCTL5            BIT(5)                /*!< pin 5 output bit */
+#define GPIO_OCTL_OCTL6            BIT(6)                /*!< pin 6 output bit */
+#define GPIO_OCTL_OCTL7            BIT(7)                /*!< pin 7 output bit */
+#define GPIO_OCTL_OCTL8            BIT(8)                /*!< pin 8 output bit */
+#define GPIO_OCTL_OCTL9            BIT(9)                /*!< pin 9 output bit */
+#define GPIO_OCTL_OCTL10           BIT(10)               /*!< pin 10 output bit */
+#define GPIO_OCTL_OCTL11           BIT(11)               /*!< pin 11 output bit */
+#define GPIO_OCTL_OCTL12           BIT(12)               /*!< pin 12 output bit */
+#define GPIO_OCTL_OCTL13           BIT(13)               /*!< pin 13 output bit */
+#define GPIO_OCTL_OCTL14           BIT(14)               /*!< pin 14 output bit */
+#define GPIO_OCTL_OCTL15           BIT(15)               /*!< pin 15 output bit */
+
+/* GPIO_BOP */
+#define GPIO_BOP_BOP0              BIT(0)                /*!< pin 0 set bit */
+#define GPIO_BOP_BOP1              BIT(1)                /*!< pin 1 set bit */
+#define GPIO_BOP_BOP2              BIT(2)                /*!< pin 2 set bit */
+#define GPIO_BOP_BOP3              BIT(3)                /*!< pin 3 set bit */
+#define GPIO_BOP_BOP4              BIT(4)                /*!< pin 4 set bit */
+#define GPIO_BOP_BOP5              BIT(5)                /*!< pin 5 set bit */
+#define GPIO_BOP_BOP6              BIT(6)                /*!< pin 6 set bit */
+#define GPIO_BOP_BOP7              BIT(7)                /*!< pin 7 set bit */
+#define GPIO_BOP_BOP8              BIT(8)                /*!< pin 8 set bit */
+#define GPIO_BOP_BOP9              BIT(9)                /*!< pin 9 set bit */
+#define GPIO_BOP_BOP10             BIT(10)               /*!< pin 10 set bit */
+#define GPIO_BOP_BOP11             BIT(11)               /*!< pin 11 set bit */
+#define GPIO_BOP_BOP12             BIT(12)               /*!< pin 12 set bit */
+#define GPIO_BOP_BOP13             BIT(13)               /*!< pin 13 set bit */
+#define GPIO_BOP_BOP14             BIT(14)               /*!< pin 14 set bit */
+#define GPIO_BOP_BOP15             BIT(15)               /*!< pin 15 set bit */
+#define GPIO_BOP_CR0               BIT(16)               /*!< pin 0 clear bit */
+#define GPIO_BOP_CR1               BIT(17)               /*!< pin 1 clear bit */
+#define GPIO_BOP_CR2               BIT(18)               /*!< pin 2 clear bit */
+#define GPIO_BOP_CR3               BIT(19)               /*!< pin 3 clear bit */
+#define GPIO_BOP_CR4               BIT(20)               /*!< pin 4 clear bit */
+#define GPIO_BOP_CR5               BIT(21)               /*!< pin 5 clear bit */
+#define GPIO_BOP_CR6               BIT(22)               /*!< pin 6 clear bit */
+#define GPIO_BOP_CR7               BIT(23)               /*!< pin 7 clear bit */
+#define GPIO_BOP_CR8               BIT(24)               /*!< pin 8 clear bit */
+#define GPIO_BOP_CR9               BIT(25)               /*!< pin 9 clear bit */
+#define GPIO_BOP_CR10              BIT(26)               /*!< pin 10 clear bit */
+#define GPIO_BOP_CR11              BIT(27)               /*!< pin 11 clear bit */
+#define GPIO_BOP_CR12              BIT(28)               /*!< pin 12 clear bit */
+#define GPIO_BOP_CR13              BIT(29)               /*!< pin 13 clear bit */
+#define GPIO_BOP_CR14              BIT(30)               /*!< pin 14 clear bit */
+#define GPIO_BOP_CR15              BIT(31)               /*!< pin 15 clear bit */
+
+/* GPIO_LOCK */
+#define GPIO_LOCK_LK0              BIT(0)                /*!< pin 0 lock bit */
+#define GPIO_LOCK_LK1              BIT(1)                /*!< pin 1 lock bit */
+#define GPIO_LOCK_LK2              BIT(2)                /*!< pin 2 lock bit */
+#define GPIO_LOCK_LK3              BIT(3)                /*!< pin 3 lock bit */
+#define GPIO_LOCK_LK4              BIT(4)                /*!< pin 4 lock bit */
+#define GPIO_LOCK_LK5              BIT(5)                /*!< pin 5 lock bit */
+#define GPIO_LOCK_LK6              BIT(6)                /*!< pin 6 lock bit */
+#define GPIO_LOCK_LK7              BIT(7)                /*!< pin 7 lock bit */
+#define GPIO_LOCK_LK8              BIT(8)                /*!< pin 8 lock bit */
+#define GPIO_LOCK_LK9              BIT(9)                /*!< pin 9 lock bit */
+#define GPIO_LOCK_LK10             BIT(10)               /*!< pin 10 lock bit */
+#define GPIO_LOCK_LK11             BIT(11)               /*!< pin 11 lock bit */
+#define GPIO_LOCK_LK12             BIT(12)               /*!< pin 12 lock bit */
+#define GPIO_LOCK_LK13             BIT(13)               /*!< pin 13 lock bit */
+#define GPIO_LOCK_LK14             BIT(14)               /*!< pin 14 lock bit */
+#define GPIO_LOCK_LK15             BIT(15)               /*!< pin 15 lock bit */
+#define GPIO_LOCK_LKK              BIT(16)               /*!< pin sequence lock key */
+
+/* GPIO_AFSEL0 */
+#define GPIO_AFSEL0_SEL0           BITS(0,3)             /*!< pin 0 alternate function selected */
+#define GPIO_AFSEL0_SEL1           BITS(4,7)             /*!< pin 1 alternate function selected */
+#define GPIO_AFSEL0_SEL2           BITS(8,11)            /*!< pin 2 alternate function selected */
+#define GPIO_AFSEL0_SEL3           BITS(12,15)           /*!< pin 3 alternate function selected */
+#define GPIO_AFSEL0_SEL4           BITS(16,19)           /*!< pin 4 alternate function selected */
+#define GPIO_AFSEL0_SEL5           BITS(20,23)           /*!< pin 5 alternate function selected */
+#define GPIO_AFSEL0_SEL6           BITS(24,27)           /*!< pin 6 alternate function selected */
+#define GPIO_AFSEL0_SEL7           BITS(28,31)           /*!< pin 7 alternate function selected */
+
+/* GPIO_AFSEL1 */
+#define GPIO_AFSEL1_SEL8           BITS(0,3)             /*!< pin 8 alternate function selected */
+#define GPIO_AFSEL1_SEL9           BITS(4,7)             /*!< pin 9 alternate function selected */
+#define GPIO_AFSEL1_SEL10          BITS(8,11)            /*!< pin 10 alternate function selected */
+#define GPIO_AFSEL1_SEL11          BITS(12,15)           /*!< pin 11 alternate function selected */
+#define GPIO_AFSEL1_SEL12          BITS(16,19)           /*!< pin 12 alternate function selected */
+#define GPIO_AFSEL1_SEL13          BITS(20,23)           /*!< pin 13 alternate function selected */
+#define GPIO_AFSEL1_SEL14          BITS(24,27)           /*!< pin 14 alternate function selected */
+#define GPIO_AFSEL1_SEL15          BITS(28,31)           /*!< pin 15 alternate function selected */
+
+/* GPIO_BC */
+#define GPIO_BC_CR0                BIT(0)                /*!< pin 0 clear bit */
+#define GPIO_BC_CR1                BIT(1)                /*!< pin 1 clear bit */
+#define GPIO_BC_CR2                BIT(2)                /*!< pin 2 clear bit */
+#define GPIO_BC_CR3                BIT(3)                /*!< pin 3 clear bit */
+#define GPIO_BC_CR4                BIT(4)                /*!< pin 4 clear bit */
+#define GPIO_BC_CR5                BIT(5)                /*!< pin 5 clear bit */
+#define GPIO_BC_CR6                BIT(6)                /*!< pin 6 clear bit */
+#define GPIO_BC_CR7                BIT(7)                /*!< pin 7 clear bit */
+#define GPIO_BC_CR8                BIT(8)                /*!< pin 8 clear bit */
+#define GPIO_BC_CR9                BIT(9)                /*!< pin 9 clear bit */
+#define GPIO_BC_CR10               BIT(10)               /*!< pin 10 clear bit */
+#define GPIO_BC_CR11               BIT(11)               /*!< pin 11 clear bit */
+#define GPIO_BC_CR12               BIT(12)               /*!< pin 12 clear bit */
+#define GPIO_BC_CR13               BIT(13)               /*!< pin 13 clear bit */
+#define GPIO_BC_CR14               BIT(14)               /*!< pin 14 clear bit */
+#define GPIO_BC_CR15               BIT(15)               /*!< pin 15 clear bit */
+
+/* GPIO_TG */
+#define GPIO_TG_TG0                BIT(0)                /*!< pin 0 toggle bit */
+#define GPIO_TG_TG1                BIT(1)                /*!< pin 1 toggle bit */
+#define GPIO_TG_TG2                BIT(2)                /*!< pin 2 toggle bit */
+#define GPIO_TG_TG3                BIT(3)                /*!< pin 3 toggle bit */
+#define GPIO_TG_TG4                BIT(4)                /*!< pin 4 toggle bit */
+#define GPIO_TG_TG5                BIT(5)                /*!< pin 5 toggle bit */
+#define GPIO_TG_TG6                BIT(6)                /*!< pin 6 toggle bit */
+#define GPIO_TG_TG7                BIT(7)                /*!< pin 7 toggle bit */
+#define GPIO_TG_TG8                BIT(8)                /*!< pin 8 toggle bit */
+#define GPIO_TG_TG9                BIT(9)                /*!< pin 9 toggle bit */
+#define GPIO_TG_TG10               BIT(10)               /*!< pin 10 toggle bit */
+#define GPIO_TG_TG11               BIT(11)               /*!< pin 11 toggle bit */
+#define GPIO_TG_TG12               BIT(12)               /*!< pin 12 toggle bit */
+#define GPIO_TG_TG13               BIT(13)               /*!< pin 13 toggle bit */
+#define GPIO_TG_TG14               BIT(14)               /*!< pin 14 toggle bit */
+#define GPIO_TG_TG15               BIT(15)               /*!< pin 15 toggle bit */
+
+/* constants definitions */
+typedef FlagStatus bit_status;
+
+/* output mode definitions */
+#define CTL_CLTR(regval)           (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define GPIO_MODE_INPUT            CTL_CLTR(0)           /*!< input mode */
+#define GPIO_MODE_OUTPUT           CTL_CLTR(1)           /*!< output mode */
+#define GPIO_MODE_AF               CTL_CLTR(2)           /*!< alternate function mode */
+#define GPIO_MODE_ANALOG           CTL_CLTR(3)           /*!< analog mode */
+
+/* pull-up/pull-down definitions */
+#define PUD_PUPD(regval)           (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define GPIO_PUPD_NONE             PUD_PUPD(0)           /*!< floating mode, no pull-up and pull-down resistors */
+#define GPIO_PUPD_PULLUP           PUD_PUPD(1)           /*!< with pull-up resistor */
+#define GPIO_PUPD_PULLDOWN         PUD_PUPD(2)           /*!< with pull-down resistor */
+
+/* GPIO pin definitions */
+#define GPIO_PIN_0                 BIT(0)                /*!< GPIO pin 0 */
+#define GPIO_PIN_1                 BIT(1)                /*!< GPIO pin 1 */
+#define GPIO_PIN_2                 BIT(2)                /*!< GPIO pin 2 */
+#define GPIO_PIN_3                 BIT(3)                /*!< GPIO pin 3 */
+#define GPIO_PIN_4                 BIT(4)                /*!< GPIO pin 4 */
+#define GPIO_PIN_5                 BIT(5)                /*!< GPIO pin 5 */
+#define GPIO_PIN_6                 BIT(6)                /*!< GPIO pin 6 */
+#define GPIO_PIN_7                 BIT(7)                /*!< GPIO pin 7 */
+#define GPIO_PIN_8                 BIT(8)                /*!< GPIO pin 8 */
+#define GPIO_PIN_9                 BIT(9)                /*!< GPIO pin 9 */
+#define GPIO_PIN_10                BIT(10)               /*!< GPIO pin 10 */
+#define GPIO_PIN_11                BIT(11)               /*!< GPIO pin 11 */
+#define GPIO_PIN_12                BIT(12)               /*!< GPIO pin 12 */
+#define GPIO_PIN_13                BIT(13)               /*!< GPIO pin 13 */
+#define GPIO_PIN_14                BIT(14)               /*!< GPIO pin 14 */
+#define GPIO_PIN_15                BIT(15)               /*!< GPIO pin 15 */
+#define GPIO_PIN_ALL               BITS(0,15)            /*!< GPIO pin all */
+
+/* GPIO mode configuration values */
+#define GPIO_MODE_SET(n, mode)     ((uint32_t)((uint32_t)(mode) << (2U * (n))))
+#define GPIO_MODE_MASK(n)          (0x3U << (2U * (n)))
+
+/* GPIO pull-up/pull-down values */
+#define GPIO_PUPD_SET(n, pupd)     ((uint32_t)((uint32_t)(pupd) << (2U * (n))))
+#define GPIO_PUPD_MASK(n)          (0x3U << (2U * (n)))
+
+/* GPIO output speed values */
+#define GPIO_OSPEED_SET(n, speed)  ((uint32_t)((uint32_t)(speed) << (2U * (n))))
+#define GPIO_OSPEED_MASK(n)        (0x3U << (2U * (n)))
+
+/* GPIO output type */
+#define GPIO_OTYPE_PP              ((uint8_t)(0x00U))    /*!< push pull mode */
+#define GPIO_OTYPE_OD              ((uint8_t)(0x01U))    /*!< open drain mode */
+
+/* GPIO output max speed value */
+#define OSPD_OSPD0(regval)         (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define GPIO_OSPEED_2MHZ           OSPD_OSPD0(0)         /*!< output max speed 2MHz */
+#define GPIO_OSPEED_10MHZ          OSPD_OSPD0(1)         /*!< output max speed 10MHz */
+#define GPIO_OSPEED_50MHZ          OSPD_OSPD0(3)         /*!< output max speed 50MHz */
+
+/* GPIO alternate function values */
+#define GPIO_AFR_SET(n, af)        ((uint32_t)((uint32_t)(af) << (4U * (n))))
+#define GPIO_AFR_MASK(n)           (0xFU << (4U * (n)))
+ 
+/* GPIO alternate function */
+#define AF(regval)                 (BITS(0,3) & ((uint32_t)(regval) << 0)) 
+#define GPIO_AF_0                   AF(0)                /*!< alternate function 0 selected */
+#define GPIO_AF_1                   AF(1)                /*!< alternate function 1 selected */
+#define GPIO_AF_2                   AF(2)                /*!< alternate function 2 selected */
+#define GPIO_AF_3                   AF(3)                /*!< alternate function 3 selected */
+#define GPIO_AF_4                   AF(4)                /*!< alternate function 4 selected (port A,B only) */
+#define GPIO_AF_5                   AF(5)                /*!< alternate function 5 selected (port A,B only) */
+#define GPIO_AF_6                   AF(6)                /*!< alternate function 6 selected (port A,B only) */
+#define GPIO_AF_7                   AF(7)                /*!< alternate function 7 selected (port A,B only) */
+
+/* function declarations */
+/* reset GPIO port */
+void gpio_deinit(uint32_t gpio_periph);
+/* set GPIO mode */
+void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin);
+/* set GPIO output type and speed */
+void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin);
+
+/* set GPIO pin bit */
+void gpio_bit_set(uint32_t gpio_periph, uint32_t pin);
+/* reset GPIO pin bit */
+void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin);
+/* write data to the specified GPIO pin */
+void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value);
+/* write data to the specified GPIO port */
+void gpio_port_write(uint32_t gpio_periph, uint16_t data);
+
+/* get GPIO pin input status */
+FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin);
+/* get GPIO port input status */
+uint16_t gpio_input_port_get(uint32_t gpio_periph);
+/* get GPIO pin output status */
+FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin);
+/* get GPIO port output status */
+uint16_t gpio_output_port_get(uint32_t gpio_periph);
+
+/* set GPIO alternate function */
+void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num, uint32_t pin);
+/* lock GPIO pin bit */
+void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin);
+
+/* toggle GPIO pin status */
+void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin);
+/* toggle GPIO port status */
+void gpio_port_toggle(uint32_t gpio_periph);
+
+#endif /* GD32E230_GPIO_H */

+ 389 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h

@@ -0,0 +1,389 @@
+/*!
+    \file  gd32e230_i2c.h
+    \brief definitions for the I2C
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_I2C_H
+#define GD32E230_I2C_H
+
+#include "gd32e230.h"
+
+/* I2Cx(x=0,1) definitions */
+#define I2C0                          I2C_BASE                   /*!< I2C0 base address */
+#define I2C1                          (I2C_BASE+0x400U)          /*!< I2C1 base address */
+
+/* registers definitions */
+#define I2C_CTL0(i2cx)                REG32((i2cx) + 0x00U)      /*!< I2C control register 0 */
+#define I2C_CTL1(i2cx)                REG32((i2cx) + 0x04U)      /*!< I2C control register 1 */
+#define I2C_SADDR0(i2cx)              REG32((i2cx) + 0x08U)      /*!< I2C slave address register 0*/
+#define I2C_SADDR1(i2cx)              REG32((i2cx) + 0x0CU)      /*!< I2C slave address register */
+#define I2C_DATA(i2cx)                REG32((i2cx) + 0x10U)      /*!< I2C transfer buffer register */
+#define I2C_STAT0(i2cx)               REG32((i2cx) + 0x14U)      /*!< I2C transfer status register 0 */
+#define I2C_STAT1(i2cx)               REG32((i2cx) + 0x18U)      /*!< I2C transfer status register */
+#define I2C_CKCFG(i2cx)               REG32((i2cx) + 0x1CU)      /*!< I2C clock configure register */
+#define I2C_RT(i2cx)                  REG32((i2cx) + 0x20U)      /*!< I2C rise time register */
+#define I2C_SAMCS(i2cx)               REG32((i2cx) + 0x80U)      /*!< I2C SAM control and status register */
+#define I2C_FMPCFG(i2cx)              REG32((i2cx) + 0x90U)      /*!< I2C fast-mode-plus configure register */
+
+/* bits definitions */
+/* I2Cx_CTL0 */
+#define I2C_CTL0_I2CEN                BIT(0)        /*!< peripheral enable */
+#define I2C_CTL0_SMBEN                BIT(1)        /*!< SMBus mode */
+#define I2C_CTL0_SMBSEL               BIT(3)        /*!< SMBus type */
+#define I2C_CTL0_ARPEN                BIT(4)        /*!< ARP enable */
+#define I2C_CTL0_PECEN                BIT(5)        /*!< PEC enable */
+#define I2C_CTL0_GCEN                 BIT(6)        /*!< general call enable */
+#define I2C_CTL0_SS                   BIT(7)        /*!< clock stretching disable (slave mode) */
+#define I2C_CTL0_START                BIT(8)        /*!< start generation */
+#define I2C_CTL0_STOP                 BIT(9)        /*!< stop generation */
+#define I2C_CTL0_ACKEN                BIT(10)       /*!< acknowledge enable */
+#define I2C_CTL0_POAP                 BIT(11)       /*!< acknowledge/PEC position (for data reception) */
+#define I2C_CTL0_PECTRANS             BIT(12)       /*!< packet error checking */
+#define I2C_CTL0_SALT                 BIT(13)       /*!< SMBus alert */
+#define I2C_CTL0_SRESET               BIT(15)       /*!< software reset */
+
+/* I2Cx_CTL1 */
+#define I2C_CTL1_I2CCLK               BITS(0,6)     /*!< I2CCLK[6:0] bits (peripheral clock frequency) */
+#define I2C_CTL1_ERRIE                BIT(8)        /*!< error interrupt inable */
+#define I2C_CTL1_EVIE                 BIT(9)        /*!< event interrupt enable */
+#define I2C_CTL1_BUFIE                BIT(10)       /*!< buffer interrupt enable */
+#define I2C_CTL1_DMAON                BIT(11)       /*!< DMA requests enable */
+#define I2C_CTL1_DMALST               BIT(12)       /*!< DMA last transfer */
+
+/* I2Cx_SADDR0 */
+#define I2C_SADDR0_ADDRESS0           BIT(0)        /*!< bit 0 of a 10-bit address */
+#define I2C_SADDR0_ADDRESS            BITS(1,7)     /*!< 7-bit address or bits 7:1 of a 10-bit address */
+#define I2C_SADDR0_ADDRESS_H          BITS(8,9)     /*!< highest two bits of a 10-bit address */
+#define I2C_SADDR0_ADDFORMAT          BIT(15)       /*!< address mode for the I2C slave */
+
+/* I2Cx_SADDR1 */
+#define I2C_SADDR1_DUADEN             BIT(0)        /*!< aual-address mode switch */
+#define I2C_SADDR1_ADDRESS2           BITS(1,7)     /*!< second I2C address for the slave in dual-address mode */
+
+/* I2Cx_DATA */
+#define I2C_DATA_TRB                  BITS(0,7)     /*!< 8-bit data register */
+
+/* I2Cx_STAT0 */
+#define I2C_STAT0_SBSEND              BIT(0)        /*!< start bit (master mode) */
+#define I2C_STAT0_ADDSEND             BIT(1)        /*!< address sent (master mode)/matched (slave mode) */
+#define I2C_STAT0_BTC                 BIT(2)        /*!< byte transfer finished */
+#define I2C_STAT0_ADD10SEND           BIT(3)        /*!< 10-bit header sent (master mode) */
+#define I2C_STAT0_STPDET              BIT(4)        /*!< stop detection (slave mode) */
+#define I2C_STAT0_RBNE                BIT(6)        /*!< data register not empty (receivers) */
+#define I2C_STAT0_TBE                 BIT(7)        /*!< data register empty (transmitters) */
+#define I2C_STAT0_BERR                BIT(8)        /*!< bus error */
+#define I2C_STAT0_LOSTARB             BIT(9)        /*!< arbitration lost (master mode) */
+#define I2C_STAT0_AERR                BIT(10)       /*!< acknowledge failure */
+#define I2C_STAT0_OUERR               BIT(11)       /*!< overrun/underrun */
+#define I2C_STAT0_PECERR              BIT(12)       /*!< PEC error in reception */
+#define I2C_STAT0_SMBTO               BIT(14)       /*!< timeout signal in SMBus mode */
+#define I2C_STAT0_SMBALT              BIT(15)       /*!< SMBus alert status */
+
+/* I2Cx_STAT1 */
+#define I2C_STAT1_MASTER              BIT(0)        /*!< master/slave */
+#define I2C_STAT1_I2CBSY              BIT(1)        /*!< bus busy */
+#define I2C_STAT1_TR                  BIT(2)        /*!< transmitter/receiver */
+#define I2C_STAT1_RXGC                BIT(4)        /*!< general call address (slave mode) */
+#define I2C_STAT1_DEFSMB              BIT(5)        /*!< SMBus device default address (slave mode) */
+#define I2C_STAT1_HSTSMB              BIT(6)        /*!< SMBus host header (slave mode) */
+#define I2C_STAT1_DUMODF              BIT(7)        /*!< dual flag (slave mode) */
+#define I2C_STAT1_PECV                BITS(8,15)    /*!< packet error checking value */
+
+/* I2Cx_CKCFG */
+#define I2C_CKCFG_CLKC                BITS(0,11)    /*!< clock control register in fast/standard mode or fast mode plus(master mode) */
+#define I2C_CKCFG_DTCY                BIT(14)       /*!< duty cycle of fast mode or fast mode plus */
+#define I2C_CKCFG_FAST                BIT(15)       /*!< I2C speed selection in master mode */
+
+/* I2Cx_RT */
+#define I2C_RT_RISETIME               BITS(0,6)     /*!< maximum rise time in fast/standard mode or fast mode plus(master mode) */
+
+/* I2Cx_SAMCS */
+#define I2C_SAMCS_SAMEN               BIT(0)        /*!< SAM_V interface enable */
+#define I2C_SAMCS_STOEN               BIT(1)        /*!< SAM_V interface timeout detect enable */
+#define I2C_SAMCS_TFFIE               BIT(4)        /*!< txframe fall interrupt enable */
+#define I2C_SAMCS_TFRIE               BIT(5)        /*!< txframe rise interrupt enable */
+#define I2C_SAMCS_RFFIE               BIT(6)        /*!< rxframe fall interrupt enable */
+#define I2C_SAMCS_RFRIE               BIT(7)        /*!< rxframe rise interrupt enable */
+#define I2C_SAMCS_TXF                 BIT(8)        /*!< level of txframe signal */
+#define I2C_SAMCS_RXF                 BIT(9)        /*!< level of rxframe signal */
+#define I2C_SAMCS_TFF                 BIT(12)       /*!< txframe fall flag */
+#define I2C_SAMCS_TFR                 BIT(13)       /*!< txframe rise flag */
+#define I2C_SAMCS_RFF                 BIT(14)       /*!< rxframe fall flag */
+#define I2C_SAMCS_RFR                 BIT(15)       /*!< rxframe rise flag */
+
+/* I2Cx_FMPCFG */
+#define I2C_FMPCFG_FMPEN              BIT(0)        /*!< fast mode plus enable bit */
+
+/* constants definitions */
+/* define the I2C bit position and its register index offset */
+#define I2C_REGIDX_BIT(regidx, bitpos)  (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define I2C_REG_VAL(i2cx, offset)       (REG32((i2cx) + (((uint32_t)(offset) & 0xFFFFU) >> 6)))
+#define I2C_BIT_POS(val)                ((uint32_t)(val) & 0x1FU)
+#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2)   (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\
+                                                              | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)))
+#define I2C_REG_VAL2(i2cx, offset)      (REG32((i2cx) + ((uint32_t)(offset) >> 22)))
+#define I2C_BIT_POS2(val)               (((uint32_t)(val) & 0x1F0000U) >> 16)
+
+/* register offset */
+#define I2C_CTL1_REG_OFFSET           0x04U         /*!< CTL1 register offset */
+#define I2C_STAT0_REG_OFFSET          0x14U         /*!< STAT0 register offset */
+#define I2C_STAT1_REG_OFFSET          0x18U         /*!< STAT1 register offset */
+#define I2C_SAMCS_REG_OFFSET          0x80U         /*!< SAMCS register offset */
+
+/* I2C flags */
+typedef enum
+{
+    /* flags in STAT0 register */
+    I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U),                /*!< start condition sent out in master mode */
+    I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U),               /*!< address is sent in master mode or received and matches in slave mode */
+    I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U),                   /*!< byte transmission finishes */
+    I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U),             /*!< header of 10-bit address is sent in master mode */
+    I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U),                /*!< stop condition detected in slave mode */
+    I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U),                  /*!< I2C_DATA is not Empty during receiving */
+    I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U),                   /*!< I2C_DATA is empty during transmitting */
+    I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U),                  /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */
+    I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U),               /*!< arbitration lost in master mode */
+    I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U),                 /*!< acknowledge error */
+    I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U),                /*!< over-run or under-run situation occurs in slave mode */
+    I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U),               /*!< PEC error when receiving data */
+    I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U),                /*!< timeout signal in SMBus mode */
+    I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U),               /*!< SMBus alert status */
+    /* flags in STAT1 register */
+    I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U),                /*!< a flag indicating whether I2C block is in master or slave mode */
+    I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U),                /*!< busy flag */
+    I2C_FLAG_TR = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U),                    /*!< whether the I2C is a transmitter or a receiver */
+    I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U),                  /*!< general call address (00h) received */
+    I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U),                /*!< default address of SMBus device */
+    I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U),                /*!< SMBus host header detected in slave mode */
+    I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U),                 /*!< dual flag in slave mode indicating which address is matched in dual-address mode */
+    /* flags in SAMCS register */
+    I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U),                  /*!< txframe fall flag */
+    I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U),                  /*!< txframe rise flag */
+    I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U),                  /*!< rxframe fall flag */
+    I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U)                   /*!< rxframe rise flag */
+}i2c_flag_enum;
+
+/* I2C interrupt flags */
+typedef enum
+{
+    /* interrupt flags in CTL1 register */
+    I2C_INT_FLAG_SBSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 0U),        /*!< start condition sent out in master mode interrupt flag */
+    I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 1U),       /*!< address is sent in master mode or received and matches in slave mode interrupt flag */
+    I2C_INT_FLAG_BTC =  I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U),          /*!< byte transmission finishes */
+    I2C_INT_FLAG_ADD10SEND =  I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 3U),    /*!< header of 10-bit address is sent in master mode interrupt flag */
+    I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 4U),        /*!< stop condition detected in slave mode interrupt flag */
+    I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 6U),          /*!< I2C_DATA is not Empty during receiving interrupt flag */
+    I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U),           /*!< I2C_DATA is empty during transmitting interrupt flag */    
+    I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 8U),          /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */
+    I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 9U),       /*!< arbitration lost in master mode interrupt flag */
+    I2C_INT_FLAG_AERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 10U),         /*!< acknowledge error interrupt flag */
+    I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 11U),        /*!< over-run or under-run situation occurs in slave mode interrupt flag */
+    I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 12U),       /*!< PEC error when receiving data interrupt flag */
+    I2C_INT_FLAG_SMBTO = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 14U),        /*!< timeout signal in SMBus mode interrupt flag */
+    I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U),       /*!< SMBus Alert status interrupt flag */
+    /* interrupt flags in SAMCS register */
+    I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U),         /*!< txframe fall interrupt flag */ 
+    I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U),         /*!< txframe rise interrupt  flag */
+    I2C_INT_FLAG_RFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 6U, I2C_SAMCS_REG_OFFSET, 14U),         /*!< rxframe fall interrupt flag */
+    I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U)          /*!< rxframe rise interrupt flag */
+}i2c_interrupt_flag_enum;
+
+/* I2C interrupt enable or disable */
+typedef enum
+{
+    /* interrupt in CTL1 register */
+    I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U),                     /*!< error interrupt enable */
+    I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U),                      /*!< event interrupt enable */
+    I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U),                    /*!< buffer interrupt enable */
+    /* interrupt in SAMCS register */
+    I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U),                    /*!< txframe fall interrupt enable  */
+    I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U),                    /*!< txframe rise interrupt  enable */
+    I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U),                    /*!< rxframe fall interrupt enable */
+    I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U)                     /*!< rxframe rise interrupt enable */
+}i2c_interrupt_enum;
+
+/* SMBus/I2C mode switch and SMBus type selection */
+#define I2C_I2CMODE_ENABLE            ((uint32_t)0x00000000U)                  /*!< I2C mode */
+#define I2C_SMBUSMODE_ENABLE          I2C_CTL0_SMBEN                           /*!< SMBus mode */
+
+/* SMBus/I2C mode switch and SMBus type selection */
+#define I2C_SMBUS_DEVICE              ((uint32_t)0x00000000U)                  /*!< SMBus mode device type */
+#define I2C_SMBUS_HOST                I2C_CTL0_SMBSEL                          /*!< SMBus mode host type */
+
+/* I2C transfer direction */
+#define I2C_RECEIVER                  ((uint32_t)0x00000001U)                  /*!< receiver */
+#define I2C_TRANSMITTER               ((uint32_t)0xFFFFFFFEU)                  /*!< transmitter */
+
+/* whether or not to send an ACK */
+#define I2C_ACK_DISABLE               ((uint32_t)0x00000000U)                  /*!< ACK will be not sent */
+#define I2C_ACK_ENABLE                ((uint32_t)0x00000001U)                  /*!< ACK will be sent */
+
+/* I2C POAP position*/
+#define I2C_ACKPOS_NEXT               ((uint32_t)0x00000000U)                  /*!< ACKEN bit decides whether or not to send ACK for the next byte */
+#define I2C_ACKPOS_CURRENT            ((uint32_t)0x00000001U)                  /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */
+
+/* whether or not to stretch SCL low */
+#define I2C_SCLSTRETCH_ENABLE         I2C_CTL0_SS                              /*!< SCL stretching is enabled */
+#define I2C_SCLSTRETCH_DISABLE        ((uint32_t)0x00000000U)                  /*!< SCL stretching is disabled */
+
+/* whether or not to response to a general call */
+#define I2C_GCEN_ENABLE               I2C_CTL0_GCEN                            /*!< slave will response to a general call */
+#define I2C_GCEN_DISABLE              ((uint32_t)0x00000000U)                  /*!< slave will not response to a general call */
+
+/* software reset I2C */
+#define I2C_SRESET_SET                I2C_CTL0_SRESET                          /*!< I2C is under reset */
+#define I2C_SRESET_RESET              ((uint32_t)0x00000000U)                  /*!< I2C is not under reset */
+
+/* I2C DMA mode configure */
+/* DMA mode switch */
+#define I2C_DMA_ON                    I2C_CTL1_DMAON                           /*!< DMA mode enabled */
+#define I2C_DMA_OFF                   ((uint32_t)0x00000000U)                  /*!< DMA mode disabled */
+
+/* flag indicating DMA last transfer */
+#define I2C_DMALST_ON                 I2C_CTL1_DMALST                          /*!< next DMA EOT is the last transfer */
+#define I2C_DMALST_OFF                ((uint32_t)0x00000000U)                  /*!< next DMA EOT is not the last transfer */
+
+/* I2C PEC configure */
+/* PEC enable */
+#define I2C_PEC_ENABLE                I2C_CTL0_PECEN                           /*!< PEC calculation on */
+#define I2C_PEC_DISABLE               ((uint32_t)0x00000000U)                  /*!< PEC calculation off */
+
+/* PEC transfer */
+#define I2C_PECTRANS_ENABLE           I2C_CTL0_PECTRANS                        /*!< transfer PEC */
+#define I2C_PECTRANS_DISABLE          ((uint32_t)0x00000000U)                  /*!< not transfer PEC value */
+
+/* I2C SMBus configure */
+/* issue or not alert through SMBA pin */
+#define I2C_SALTSEND_ENABLE           I2C_CTL0_SALT                            /*!< issue alert through SMBA pin */
+#define I2C_SALTSEND_DISABLE          ((uint32_t)0x00000000U)                  /*!< not issue alert through SMBA */
+
+/* ARP protocol in SMBus switch */
+#define I2C_ARP_ENABLE                I2C_CTL0_ARPEN                           /*!< ARP enable */
+#define I2C_ARP_DISABLE               ((uint32_t)0x00000000U)                  /*!< ARP disable */
+
+/* fast mode plus enable */
+#define I2C_FAST_MODE_PLUS_ENABLE     I2C_FMPCFG_FMPEN                         /*!< fast mode plus enable */
+#define I2C_FAST_MODE_PLUS_DISABLE    ((uint32_t)0x00000000U)                  /*!< fast mode plus disable */
+
+/* transmit I2C data */
+#define DATA_TRANS(regval)            (BITS(0,7) & ((uint32_t)(regval) << 0))
+
+/* receive I2C data */
+#define DATA_RECV(regval)             GET_BITS((uint32_t)(regval), 0, 7)
+
+/* I2C duty cycle in fast mode or fast mode plus */
+#define I2C_DTCY_2                    ((uint32_t)0x00000000U)                  /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 2 */
+#define I2C_DTCY_16_9                 I2C_CKCFG_DTCY                           /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 16/9 */
+
+/* address mode for the I2C slave */
+#define I2C_ADDFORMAT_7BITS           ((uint32_t)0x00000000U)                  /*!< address:7 bits */
+#define I2C_ADDFORMAT_10BITS          I2C_SADDR0_ADDFORMAT                     /*!< address:10 bits */
+
+/* function declarations */
+/* reset I2C */
+void i2c_deinit(uint32_t i2c_periph);
+/* configure I2C clock */
+void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc);
+/* configure I2C address */
+void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr);
+/* SMBus type selection */
+void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type);
+/* whether or not to send an ACK */
+void i2c_ack_config(uint32_t i2c_periph, uint32_t ack);
+/* configure I2C POAP position */
+void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos);
+/* master sends slave address */
+void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection);
+/* enable dual-address mode */
+void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr);
+/* disable dual-address mode */
+void i2c_dualaddr_disable(uint32_t i2c_periph);
+/* enable I2C */
+void i2c_enable(uint32_t i2c_periph);
+/* disable I2C */
+void i2c_disable(uint32_t i2c_periph);
+
+/* generate a START condition on I2C bus */
+void i2c_start_on_bus(uint32_t i2c_periph);
+/* generate a STOP condition on I2C bus */
+void i2c_stop_on_bus(uint32_t i2c_periph);
+/* I2C transmit data function */
+void i2c_data_transmit(uint32_t i2c_periph, uint8_t data);
+/* I2C receive data function */
+uint8_t i2c_data_receive(uint32_t i2c_periph);
+/* enable I2C DMA mode */
+void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate);
+/* configure whether next DMA EOT is DMA last transfer or not */
+void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast);
+/* whether to stretch SCL low when data is not ready in slave mode */
+void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara);
+/* whether or not to response to a general call */
+void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara);
+/* software reset I2C */
+void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset);
+
+/* I2C PEC calculation on or off */
+void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate);
+/* I2C whether to transfer PEC value */
+void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara);
+/* packet error checking value */
+uint8_t i2c_pec_value_get(uint32_t i2c_periph);
+/* I2C issue alert through SMBA pin */
+void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara);
+/* I2C ARP protocol in SMBus switch */
+void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate);
+
+/* enable SAM_V interface */
+void i2c_sam_enable(uint32_t i2c_periph);
+/* disable SAM_V interface */
+void i2c_sam_disable(uint32_t i2c_periph);
+/* enable SAM_V interface timeout detect */
+void i2c_sam_timeout_enable(uint32_t i2c_periph);
+/* disable SAM_V interface timeout detect */
+void i2c_sam_timeout_disable(uint32_t i2c_periph);
+
+/* check I2C flag is set or not */
+FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag);
+/* clear I2C flag */
+void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag);
+/* enable I2C interrupt */
+void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt);
+/* disable I2C interrupt */
+void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt);
+/* check I2C interrupt flag */
+FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag);
+/* clear I2C interrupt flag */
+void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag);
+
+#endif /* GD32E230_I2C_H */

+ 86 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h

@@ -0,0 +1,86 @@
+/*!
+    \file  gd32e230_misc.h
+    \brief definitions for the MISC
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_MISC_H
+#define GD32E230_MISC_H
+
+#include "gd32e230.h"
+
+/* constants definitions */
+/* set the RAM and FLASH base address */
+#define NVIC_VECTTAB_RAM            ((uint32_t)0x20000000)                      /*!< RAM base address */
+#define NVIC_VECTTAB_FLASH          ((uint32_t)0x08000000)                      /*!< Flash base address */
+
+/* set the NVIC vector table offset mask */
+#define NVIC_VECTTAB_OFFSET_MASK    ((uint32_t)0x1FFFFF80)                      /*!< NVIC vector table offset mask */
+
+/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */
+#define NVIC_AIRCR_VECTKEY_MASK     ((uint32_t)0x05FA0000)                      /*!< NVIC VECTKEY mask */
+
+/* choose the method to enter or exit the lowpower mode */
+#define SCB_SCR_SLEEPONEXIT         ((uint8_t)0x02)                             /*!< choose the the system whether enter low power mode by exiting from ISR */
+#define SCB_SCR_SLEEPDEEP           ((uint8_t)0x04)                             /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */
+#define SCB_SCR_SEVONPEND           ((uint8_t)0x10)                             /*!< choose the interrupt source that can wake up the lowpower mode */
+
+#define SCB_LPM_SLEEP_EXIT_ISR      SCB_SCR_SLEEPONEXIT                         /*!< low power mode by exiting from ISR */
+#define SCB_LPM_DEEPSLEEP           SCB_SCR_SLEEPDEEP                           /*!< DEEPSLEEP mode or SLEEP mode */
+#define SCB_LPM_WAKE_BY_ALL_INT     SCB_SCR_SEVONPEND                           /*!< wakeup by all interrupt */
+
+/* choose the systick clock source */
+#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU)                     /*!< systick clock source is from HCLK/8 */
+#define SYSTICK_CLKSOURCE_HCLK      ((uint32_t)0x00000004U)                     /*!< systick clock source is from HCLK */
+
+/* function declarations */
+
+/* enable NVIC request */
+void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority);
+/* disable NVIC request */
+void nvic_irq_disable(uint8_t nvic_irq);
+/* initiates a system reset request to reset the MCU */
+void nvic_system_reset(void);
+
+/* set the NVIC vector table base address */
+void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset);
+
+/* set the state of the low power mode */
+void system_lowpower_set(uint8_t lowpower_mode);
+/* reset the state of the low power mode */
+void system_lowpower_reset(uint8_t lowpower_mode);
+
+/* set the systick clock source */
+void systick_clksource_set(uint32_t systick_clksource);
+
+#endif /* GD32E230_MISC_H */

+ 146 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h

@@ -0,0 +1,146 @@
+/*!
+    \file  gd32e230_pmu.h
+    \brief definitions for the PMU
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_PMU_H
+#define GD32E230_PMU_H
+
+#include "gd32e230.h"
+
+/* PMU definitions */
+#define PMU                           PMU_BASE                 /*!< PMU base address */
+
+/* registers definitions */
+#define PMU_CTL                       REG32((PMU) + 0x00U)     /*!< PMU control register */
+#define PMU_CS                        REG32((PMU) + 0x04U)     /*!< PMU control and status register */
+
+/* bits definitions */
+/* PMU_CTL */
+#define PMU_CTL_LDOLP                 BIT(0)                   /*!< LDO low power mode */
+#define PMU_CTL_STBMOD                BIT(1)                   /*!< standby mode */
+#define PMU_CTL_WURST                 BIT(2)                   /*!< wakeup flag reset */
+#define PMU_CTL_STBRST                BIT(3)                   /*!< standby flag reset */
+#define PMU_CTL_LVDEN                 BIT(4)                   /*!< low voltage detector enable */
+#define PMU_CTL_LVDT                  BITS(5,7)                /*!< low voltage detector threshold */
+#define PMU_CTL_BKPWEN                BIT(8)                   /*!< backup domain write enable */
+#define PMU_CTL_LDOVS_0               BIT(14)                  /*!< LDO output voltage select */
+#define PMU_CTL_LDOVS_1               BIT(15)                  /*!< LDO output voltage select */
+#define PMU_CTL_LDOVS                 BITS(14,15)              /*!< LDO output voltage select */
+
+/* PMU_CS */
+#define PMU_CS_WUF                    BIT(0)                   /*!< wakeup flag */
+#define PMU_CS_STBF                   BIT(1)                   /*!< standby flag */
+#define PMU_CS_LVDF                   BIT(2)                   /*!< low voltage detector status flag */
+#define PMU_CS_WUPEN0                 BIT(8)                   /*!< wakeup pin enable */
+#define PMU_CS_WUPEN1                 BIT(9)                   /*!< wakeup pin enable */
+#define PMU_CS_WUPEN5                 BIT(13)                  /*!< wakeup pin enable */
+#define PMU_CS_WUPEN6                 BIT(14)                  /*!< wakeup pin enable */
+
+/* constants definitions */
+/* PMU low voltage detector threshold definitions */
+#define CTL_LVDT(regval)              (BITS(5,7)&((uint32_t)(regval)<<5))
+#define PMU_LVDT_0                    CTL_LVDT(0)              /*!< voltage threshold is 2.1V */
+#define PMU_LVDT_1                    CTL_LVDT(1)              /*!< voltage threshold is 2.3V */
+#define PMU_LVDT_2                    CTL_LVDT(2)              /*!< voltage threshold is 2.4V */
+#define PMU_LVDT_3                    CTL_LVDT(3)              /*!< voltage threshold is 2.6V */
+#define PMU_LVDT_4                    CTL_LVDT(4)              /*!< voltage threshold is 2.7V */
+#define PMU_LVDT_5                    CTL_LVDT(5)              /*!< voltage threshold is 2.9V */
+#define PMU_LVDT_6                    CTL_LVDT(6)              /*!< voltage threshold is 3.0V */
+#define PMU_LVDT_7                    CTL_LVDT(7)              /*!< voltage threshold is 3.1V */
+
+/* PMU LDO output voltage select definitions */
+#define CTL_LDOVS(regval)             (BITS(14,15)&((uint32_t)(regval)<<14))
+#define PMU_LDOVS_HIGH                CTL_LDOVS(1)             /*!< LDO output voltage high mode */
+#define PMU_LDOVS_LOW                 CTL_LDOVS(2)             /*!< LDO output voltage low mode */
+
+/* PMU ldo definitions */
+#define PMU_LDO_NORMAL                ((uint32_t)0x00000000U)  /*!< LDO operates normally when PMU enter deepsleep mode */
+#define PMU_LDO_LOWPOWER              PMU_CTL_LDOLP            /*!< LDO work at low power status when PMU enter deepsleep mode */
+
+/* PMU flag definitions */
+#define PMU_FLAG_WAKEUP               PMU_CS_WUF               /*!< wakeup flag status */
+#define PMU_FLAG_STANDBY              PMU_CS_STBF              /*!< standby flag status */
+#define PMU_FLAG_LVD                  PMU_CS_LVDF              /*!< LVD flag status */
+
+/* PMU WKUP pin definitions */
+#define PMU_WAKEUP_PIN0               PMU_CS_WUPEN0            /*!< WKUP Pin 0 (PA0) enable */
+#define PMU_WAKEUP_PIN1               PMU_CS_WUPEN1            /*!< WKUP Pin 1 (PC13) enable */
+#define PMU_WAKEUP_PIN5               PMU_CS_WUPEN5            /*!< WKUP Pin 5 (PB5) enable */
+#define PMU_WAKEUP_PIN6               PMU_CS_WUPEN6            /*!< WKUP Pin 6 (PB15) enable */
+
+/* PMU flag reset definitions */
+#define PMU_FLAG_RESET_WAKEUP         PMU_CTL_WURST            /*!< wakeup flag reset */
+#define PMU_FLAG_RESET_STANDBY        PMU_CTL_STBRST           /*!< standby flag reset */
+
+/* PMU command constants definitions */
+#define WFI_CMD                       ((uint8_t)0x00U)         /*!< use WFI command */
+#define WFE_CMD                       ((uint8_t)0x01U)         /*!< use WFE command */
+
+/* function declarations */
+/* reset PMU registers */
+void pmu_deinit(void);
+
+/* select low voltage detector threshold */
+void pmu_lvd_select(uint32_t lvdt_n);
+/* select LDO output voltage */
+void pmu_ldo_output_select(uint32_t ldo_output);
+/* disable PMU lvd */
+void pmu_lvd_disable(void);
+
+/* set PMU mode */
+/* PMU work in sleep mode */
+void pmu_to_sleepmode(uint8_t sleepmodecmd);
+/* PMU work in deepsleep mode */
+void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd);
+/* PMU work in standby mode */
+void pmu_to_standbymode(uint8_t standbymodecmd);
+/* enable PMU wakeup pin */
+void pmu_wakeup_pin_enable(uint32_t wakeup_pin);
+/* disable PMU wakeup pin */
+void pmu_wakeup_pin_disable(uint32_t wakeup_pin);
+
+/* backup related functions */
+/* enable backup domain write */
+void pmu_backup_write_enable(void);
+/* disable backup domain write */
+void pmu_backup_write_disable(void);
+
+/* flag functions */
+/* clear flag bit */
+void pmu_flag_clear(uint32_t flag_clear);
+/* get flag state */
+FlagStatus pmu_flag_get(uint32_t flag);
+
+#endif /* GD32E230_PMU_H */

+ 672 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h

@@ -0,0 +1,672 @@
+/*!
+    \file  gd32e230_rcu.h
+    \brief definitions for the RCU
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_RCU_H
+#define GD32E230_RCU_H
+
+#include "gd32e230.h"
+
+/* RCU definitions */
+#define RCU                         RCU_BASE
+
+/* registers definitions */
+#define RCU_CTL0                    REG32(RCU + 0x00U)        /*!< control register 0 */
+#define RCU_CFG0                    REG32(RCU + 0x04U)        /*!< configuration register 0 */
+#define RCU_INT                     REG32(RCU + 0x08U)        /*!< interrupt register */
+#define RCU_APB2RST                 REG32(RCU + 0x0CU)        /*!< APB2 reset register */
+#define RCU_APB1RST                 REG32(RCU + 0x10U)        /*!< APB1 reset register */
+#define RCU_AHBEN                   REG32(RCU + 0x14U)        /*!< AHB enable register */
+#define RCU_APB2EN                  REG32(RCU + 0x18U)        /*!< APB2 enable register */
+#define RCU_APB1EN                  REG32(RCU + 0x1CU)        /*!< APB1 enable register  */
+#define RCU_BDCTL                   REG32(RCU + 0x20U)        /*!< backup domain control register */
+#define RCU_RSTSCK                  REG32(RCU + 0x24U)        /*!< reset source /clock register */
+#define RCU_AHBRST                  REG32(RCU + 0x28U)        /*!< AHB reset register */
+#define RCU_CFG1                    REG32(RCU + 0x2CU)        /*!< configuration register 1 */
+#define RCU_CFG2                    REG32(RCU + 0x30U)        /*!< configuration register 2 */
+#define RCU_CTL1                    REG32(RCU + 0x34U)        /*!< control register 1 */
+#define RCU_VKEY                    REG32(RCU + 0x100U)       /*!< voltage key register */
+#define RCU_DSV                     REG32(RCU + 0x134U)       /*!< deep-sleep mode voltage register */
+
+/* bits definitions */
+/* RCU_CTL0 */
+#define RCU_CTL0_IRC8MEN            BIT(0)                    /*!< internal high speed oscillator enable */
+#define RCU_CTL0_IRC8MSTB           BIT(1)                    /*!< IRC8M high speed internal oscillator stabilization flag */
+#define RCU_CTL0_IRC8MADJ           BITS(3,7)                 /*!< high speed internal oscillator clock trim adjust value */
+#define RCU_CTL0_IRC8MCALIB         BITS(8,15)                /*!< high speed internal oscillator calibration value register */
+#define RCU_CTL0_HXTALEN            BIT(16)                   /*!< external high speed oscillator enable */
+#define RCU_CTL0_HXTALSTB           BIT(17)                   /*!< external crystal oscillator clock stabilization flag */
+#define RCU_CTL0_HXTALBPS           BIT(18)                   /*!< external crystal oscillator clock bypass mode enable */
+#define RCU_CTL0_CKMEN              BIT(19)                   /*!< HXTAL clock monitor enable */
+#define RCU_CTL0_PLLEN              BIT(24)                   /*!< PLL enable */
+#define RCU_CTL0_PLLSTB             BIT(25)                   /*!< PLL clock stabilization flag */
+
+/* RCU_CFG0 */
+#define RCU_CFG0_SCS                BITS(0,1)                 /*!< system clock switch */
+#define RCU_CFG0_SCSS               BITS(2,3)                 /*!< system clock switch status */
+#define RCU_CFG0_AHBPSC             BITS(4,7)                 /*!< AHB prescaler selection */
+#define RCU_CFG0_APB1PSC            BITS(8,10)                /*!< APB1 prescaler selection */
+#define RCU_CFG0_APB2PSC            BITS(11,13)               /*!< APB2 prescaler selection */
+#define RCU_CFG0_ADCPSC             BITS(14,15)               /*!< ADC clock prescaler selection */
+#define RCU_CFG0_PLLSEL             BIT(16)                   /*!< PLL clock source selection */
+#define RCU_CFG0_PLLPREDV           BIT(17)                   /*!< divider for PLL source clock selection */
+#define RCU_CFG0_PLLMF              (BIT(27) | BITS(18,21))   /*!< PLL multiply factor */
+#define RCU_CFG0_CKOUTSEL           BITS(24,26)               /*!< CK_OUT clock source selection */
+#define RCU_CFG0_PLLMF4             BIT(27)                   /*!< bit 4 of PLLMF */
+#define RCU_CFG0_CKOUTDIV           BITS(28,30)               /*!< CK_OUT divider which the CK_OUT frequency can be reduced */
+#define RCU_CFG0_PLLDV              BIT(31)                   /*!< CK_PLL divide by 1 or 2 */
+
+/* RCU_INT */
+#define RCU_INT_IRC40KSTBIF         BIT(0)                    /*!< IRC40K stabilization interrupt flag */
+#define RCU_INT_LXTALSTBIF          BIT(1)                    /*!< LXTAL stabilization interrupt flag */
+#define RCU_INT_IRC8MSTBIF          BIT(2)                    /*!< IRC8M stabilization interrupt flag */
+#define RCU_INT_HXTALSTBIF          BIT(3)                    /*!< HXTAL stabilization interrupt flag */
+#define RCU_INT_PLLSTBIF            BIT(4)                    /*!< PLL stabilization interrupt flag */
+#define RCU_INT_IRC28MSTBIF         BIT(5)                    /*!< IRC28M stabilization interrupt flag */
+#define RCU_INT_CKMIF               BIT(7)                    /*!< HXTAL clock stuck interrupt flag */
+#define RCU_INT_IRC40KSTBIE         BIT(8)                    /*!< IRC40K stabilization interrupt enable */
+#define RCU_INT_LXTALSTBIE          BIT(9)                    /*!< LXTAL stabilization interrupt enable */
+#define RCU_INT_IRC8MSTBIE          BIT(10)                   /*!< IRC8M stabilization interrupt enable */
+#define RCU_INT_HXTALSTBIE          BIT(11)                   /*!< HXTAL stabilization interrupt enable */
+#define RCU_INT_PLLSTBIE            BIT(12)                   /*!< PLL stabilization interrupt enable */
+#define RCU_INT_IRC28MSTBIE         BIT(13)                   /*!< IRC28M stabilization interrupt enable */
+#define RCU_INT_IRC40KSTBIC         BIT(16)                   /*!< IRC40K stabilization interrupt clear */
+#define RCU_INT_LXTALSTBIC          BIT(17)                   /*!< LXTAL stabilization interrupt clear */
+#define RCU_INT_IRC8MSTBIC          BIT(18)                   /*!< IRC8M stabilization interrupt clear */
+#define RCU_INT_HXTALSTBIC          BIT(19)                   /*!< HXTAL stabilization interrupt clear */
+#define RCU_INT_PLLSTBIC            BIT(20)                   /*!< PLL stabilization interrupt clear */
+#define RCU_INT_IRC28MSTBIC         BIT(21)                   /*!< IRC28M stabilization interrupt clear */
+#define RCU_INT_CKMIC               BIT(23)                   /*!< HXTAL clock stuck interrupt clear */
+
+/* RCU_APB2RST */
+#define RCU_APB2RST_CFGRST          BIT(0)                    /*!< system configuration reset */
+#define RCU_APB2RST_ADCRST          BIT(9)                    /*!< ADC reset */
+#define RCU_APB2RST_TIMER0RST       BIT(11)                   /*!< TIMER0 reset */
+#define RCU_APB2RST_SPI0RST         BIT(12)                   /*!< SPI0 reset */
+#define RCU_APB2RST_USART0RST       BIT(14)                   /*!< USART0 reset */
+#define RCU_APB2RST_TIMER14RST      BIT(16)                   /*!< TIMER14 reset */
+#define RCU_APB2RST_TIMER15RST      BIT(17)                   /*!< TIMER15 reset */
+#define RCU_APB2RST_TIMER16RST      BIT(18)                   /*!< TIMER16 reset */
+
+/* RCU_APB1RST */
+#define RCU_APB1RST_TIMER2RST       BIT(1)                    /*!< TIMER2 timer reset */
+#define RCU_APB1RST_TIMER5RST       BIT(4)                    /*!< TIMER5 timer reset */
+#define RCU_APB1RST_TIMER13RST      BIT(8)                    /*!< TIMER13 timer reset */
+#define RCU_APB1RST_WWDGTRST        BIT(11)                   /*!< window watchdog timer reset */
+#define RCU_APB1RST_SPI1RST         BIT(14)                   /*!< SPI1 reset */
+#define RCU_APB1RST_USART1RST       BIT(17)                   /*!< USART1 reset */
+#define RCU_APB1RST_I2C0RST         BIT(21)                   /*!< I2C0 reset */
+#define RCU_APB1RST_I2C1RST         BIT(22)                   /*!< I2C1 reset */
+#define RCU_APB1RST_PMURST          BIT(28)                   /*!< power control reset */
+
+/* RCU_AHBEN */
+#define RCU_AHBEN_DMAEN             BIT(0)                    /*!< DMA clock enable */
+#define RCU_AHBEN_SRAMSPEN          BIT(2)                    /*!< SRAM interface clock enable */
+#define RCU_AHBEN_FMCSPEN           BIT(4)                    /*!< FMC clock enable */
+#define RCU_AHBEN_CRCEN             BIT(6)                    /*!< CRC clock enable */
+#define RCU_AHBEN_PAEN              BIT(17)                   /*!< GPIO port A clock enable */
+#define RCU_AHBEN_PBEN              BIT(18)                   /*!< GPIO port B clock enable */
+#define RCU_AHBEN_PCEN              BIT(19)                   /*!< GPIO port C clock enable */
+#define RCU_AHBEN_PFEN              BIT(22)                   /*!< GPIO port F clock enable */
+
+/* RCU_APB2EN */
+#define RCU_APB2EN_CFGCMPEN         BIT(0)                    /*!< system configuration and comparator clock enable */
+#define RCU_APB2EN_ADCEN            BIT(9)                    /*!< ADC interface clock enable */
+#define RCU_APB2EN_TIMER0EN         BIT(11)                   /*!< TIMER0 timer clock enable */
+#define RCU_APB2EN_SPI0EN           BIT(12)                   /*!< SPI0 clock enable */
+#define RCU_APB2EN_USART0EN         BIT(14)                   /*!< USART0 clock enable */
+#define RCU_APB2EN_TIMER14EN        BIT(16)                   /*!< TIMER14 timer clock enable */
+#define RCU_APB2EN_TIMER15EN        BIT(17)                   /*!< TIMER15 timer clock enable */
+#define RCU_APB2EN_TIMER16EN        BIT(18)                   /*!< TIMER16 timer clock enable */
+#define RCU_APB2EN_DBGMCUEN         BIT(22)                   /*!< DBGMCU clock enable */
+
+/* RCU_APB1EN */
+#define RCU_APB1EN_TIMER2EN         BIT(1)                    /*!< TIMER2 timer clock enable */
+#define RCU_APB1EN_TIMER5EN         BIT(4)                    /*!< TIMER5 timer clock enable */
+#define RCU_APB1EN_TIMER13EN        BIT(8)                    /*!< TIMER13 timer clock enable */
+#define RCU_APB1EN_WWDGTEN          BIT(11)                   /*!< window watchdog timer clock enable */
+#define RCU_APB1EN_SPI1EN           BIT(14)                   /*!< SPI1 clock enable */
+#define RCU_APB1EN_USART1EN         BIT(17)                   /*!< USART1 clock enable */
+#define RCU_APB1EN_I2C0EN           BIT(21)                   /*!< I2C0 clock enable */
+#define RCU_APB1EN_I2C1EN           BIT(22)                   /*!< I2C1 clock enable */
+#define RCU_APB1EN_PMUEN            BIT(28)                   /*!< power interface clock enable */
+
+/* RCU_BDCTL */
+#define RCU_BDCTL_LXTALEN           BIT(0)                    /*!< LXTAL enable */
+#define RCU_BDCTL_LXTALSTB          BIT(1)                    /*!< external low-speed oscillator stabilization */
+#define RCU_BDCTL_LXTALBPS          BIT(2)                    /*!< LXTAL bypass mode enable */
+#define RCU_BDCTL_LXTALDRI          BITS(3,4)                 /*!< LXTAL drive capability */
+#define RCU_BDCTL_RTCSRC            BITS(8,9)                 /*!< RTC clock entry selection */
+#define RCU_BDCTL_RTCEN             BIT(15)                   /*!< RTC clock enable */
+#define RCU_BDCTL_BKPRST            BIT(16)                   /*!< backup domain reset */
+
+/* RCU_RSTSCK */
+#define RCU_RSTSCK_IRC40KEN         BIT(0)                    /*!< IRC40K enable */
+#define RCU_RSTSCK_IRC40KSTB        BIT(1)                    /*!< IRC40K stabilization */
+#define RCU_RSTSCK_V12RSTF          BIT(23)                   /*!< V12 domain power reset flag */
+#define RCU_RSTSCK_RSTFC            BIT(24)                   /*!< reset flag clear */
+#define RCU_RSTSCK_OBLRSTF          BIT(25)                   /*!< option byte loader reset flag */
+#define RCU_RSTSCK_EPRSTF           BIT(26)                   /*!< external pin reset flag */
+#define RCU_RSTSCK_PORRSTF          BIT(27)                   /*!< power reset flag */
+#define RCU_RSTSCK_SWRSTF           BIT(28)                   /*!< software reset flag */
+#define RCU_RSTSCK_FWDGTRSTF        BIT(29)                   /*!< free watchdog timer reset flag */
+#define RCU_RSTSCK_WWDGTRSTF        BIT(30)                   /*!< window watchdog timer reset flag */
+#define RCU_RSTSCK_LPRSTF           BIT(31)                   /*!< low-power reset flag */
+
+/* RCU_AHBRST */
+#define RCU_AHBRST_PARST            BIT(17)                   /*!< GPIO port A reset */
+#define RCU_AHBRST_PBRST            BIT(18)                   /*!< GPIO port B reset */
+#define RCU_AHBRST_PCRST            BIT(19)                   /*!< GPIO port C reset */
+#define RCU_AHBRST_PFRST            BIT(22)                   /*!< GPIO port F reset */
+
+/* RCU_CFG1 */
+#define RCU_CFG1_PREDV              BITS(0,3)                 /*!< CK_HXTAL divider previous PLL */
+
+/* RCU_CFG2 */
+#define RCU_CFG2_USART0SEL          BITS(0,1)                 /*!< CK_USART0 clock source selection */
+#define RCU_CFG2_ADCSEL             BIT(8)                    /*!< CK_ADC clock source selection */
+#define RCU_CFG2_IRC28MDIV          BIT(16)                   /*!< CK_IRC28M divider 2 or not */
+#define RCU_CFG2_ADCPSC2            BIT(31)                   /*!< bit 2 of ADCPSC */
+
+/* RCU_CTL1 */
+#define RCU_CTL1_IRC28MEN           BIT(0)                    /*!< IRC28M internal 28M RC oscillator enable */
+#define RCU_CTL1_IRC28MSTB          BIT(1)                    /*!< IRC28M internal 28M RC oscillator stabilization flag */
+#define RCU_CTL1_IRC28MADJ          BITS(3,7)                 /*!< internal 28M RC oscillator clock trim adjust value */
+#define RCU_CTL1_IRC28MCALIB        BITS(8,15)                /*!< internal 28M RC oscillator calibration value register */
+
+/* RCU_VKEY */
+#define RCU_VKEY_KEY                BITS(0,31)                /*!< key of RCU_DSV register */
+
+/* RCU_DSV */
+#define RCU_DSV_DSLPVS              BITS(0,1)                 /*!< deep-sleep mode voltage select */
+
+/* constants definitions */
+/* define the peripheral clock enable bit position and its register index offset */
+#define RCU_REGIDX_BIT(regidx, bitpos)      (((uint32_t)(regidx)<<6) | (uint32_t)(bitpos))
+#define RCU_REG_VAL(periph)                 (REG32(RCU + ((uint32_t)(periph)>>6)))
+#define RCU_BIT_POS(val)                    ((uint32_t)(val) & 0x1FU)
+/* define the voltage key unlock value */
+#define RCU_VKEY_UNLOCK                     ((uint32_t)0x1A2B3C4D)
+
+/* register index */
+typedef enum
+{
+    /* peripherals enable */
+    IDX_AHBEN      = 0x14U, 
+    IDX_APB2EN     = 0x18U, 
+    IDX_APB1EN     = 0x1CU, 
+    /* peripherals reset */
+    IDX_AHBRST     = 0x28U, 
+    IDX_APB2RST    = 0x0CU, 
+    IDX_APB1RST    = 0x10U, 
+    /* clock stabilization */
+    IDX_CTL0       = 0x00U,
+    IDX_BDCTL      = 0x20U,
+    IDX_CTL1       = 0x34U,
+    /* peripheral reset */
+    IDX_RSTSCK     = 0x24U,
+    /* clock stabilization and stuck interrupt */
+    IDX_INT        = 0x08U,
+    /* configuration register */
+    IDX_CFG0       = 0x04U,
+    IDX_CFG2       = 0x30U
+}reg_idx;
+
+/* peripheral clock enable */
+typedef enum
+{
+    /* AHB peripherals */
+    RCU_DMA     = RCU_REGIDX_BIT(IDX_AHBEN, 0U),                  /*!< DMA clock */
+    RCU_CRC     = RCU_REGIDX_BIT(IDX_AHBEN, 6U),                  /*!< CRC clock */
+    RCU_GPIOA   = RCU_REGIDX_BIT(IDX_AHBEN, 17U),                 /*!< GPIOA clock */
+    RCU_GPIOB   = RCU_REGIDX_BIT(IDX_AHBEN, 18U),                 /*!< GPIOB clock */
+    RCU_GPIOC   = RCU_REGIDX_BIT(IDX_AHBEN, 19U),                 /*!< GPIOC clock */
+    RCU_GPIOF   = RCU_REGIDX_BIT(IDX_AHBEN, 22U),                 /*!< GPIOF clock */
+    
+    /* APB2 peripherals */
+    RCU_CFGCMP  = RCU_REGIDX_BIT(IDX_APB2EN, 0U),                 /*!< CFGCMP clock */
+    RCU_ADC     = RCU_REGIDX_BIT(IDX_APB2EN, 9U),                 /*!< ADC clock */
+    RCU_TIMER0  = RCU_REGIDX_BIT(IDX_APB2EN, 11U),                /*!< TIMER0 clock */
+    RCU_SPI0    = RCU_REGIDX_BIT(IDX_APB2EN, 12U),                /*!< SPI0 clock */
+    RCU_USART0  = RCU_REGIDX_BIT(IDX_APB2EN, 14U),                /*!< USART0 clock */
+    RCU_TIMER14 = RCU_REGIDX_BIT(IDX_APB2EN, 16U),                /*!< TIMER14 clock */
+    RCU_TIMER15 = RCU_REGIDX_BIT(IDX_APB2EN, 17U),                /*!< TIMER15 clock */
+    RCU_TIMER16 = RCU_REGIDX_BIT(IDX_APB2EN, 18U),                /*!< TIMER16 clock */
+    RCU_DBGMCU  = RCU_REGIDX_BIT(IDX_APB2EN, 22U),                /*!< DBGMCU clock */
+    
+    /* APB1 peripherals */
+    RCU_TIMER2  = RCU_REGIDX_BIT(IDX_APB1EN, 1U),                 /*!< TIMER2 clock */
+    RCU_TIMER5  = RCU_REGIDX_BIT(IDX_APB1EN, 4U),                 /*!< TIMER5 clock */
+    RCU_TIMER13 = RCU_REGIDX_BIT(IDX_APB1EN, 8U),                 /*!< TIMER13 clock */
+    RCU_WWDGT   = RCU_REGIDX_BIT(IDX_APB1EN, 11U),                /*!< WWDGT clock */
+    RCU_SPI1    = RCU_REGIDX_BIT(IDX_APB1EN, 14U),                /*!< SPI1 clock */
+    RCU_USART1  = RCU_REGIDX_BIT(IDX_APB1EN, 17U),                /*!< USART1 clock */
+    RCU_I2C0    = RCU_REGIDX_BIT(IDX_APB1EN, 21U),                /*!< I2C0 clock */
+    RCU_I2C1    = RCU_REGIDX_BIT(IDX_APB1EN, 22U),                /*!< I2C1 clock */
+    RCU_PMU     = RCU_REGIDX_BIT(IDX_APB1EN, 28U),                /*!< PMU clock */
+    
+    /* Backup domain control(BDCTL) */
+    RCU_RTC     = RCU_REGIDX_BIT(IDX_BDCTL, 15U)                  /*!< RTC clock */
+}rcu_periph_enum;
+
+/* peripheral clock enable when sleep mode*/
+typedef enum
+{
+    /* AHB peripherals */
+    RCU_SRAM_SLP     = RCU_REGIDX_BIT(IDX_AHBEN, 2U),             /*!< SRAM clock */
+    RCU_FMC_SLP      = RCU_REGIDX_BIT(IDX_AHBEN, 4U),             /*!< FMC clock */
+}rcu_periph_sleep_enum;
+
+/* peripherals reset */
+typedef enum
+{
+    /* AHB peripherals reset */
+    RCU_GPIOARST   = RCU_REGIDX_BIT(IDX_AHBRST, 17U),             /*!< GPIOA reset */
+    RCU_GPIOBRST   = RCU_REGIDX_BIT(IDX_AHBRST, 18U),             /*!< GPIOB reset */
+    RCU_GPIOCRST   = RCU_REGIDX_BIT(IDX_AHBRST, 19U),             /*!< GPIOC reset */
+    RCU_GPIOFRST   = RCU_REGIDX_BIT(IDX_AHBRST, 22U),             /*!< GPIOF reset */
+    
+    /* APB2 peripherals reset */
+    RCU_CFGCMPRST  = RCU_REGIDX_BIT(IDX_APB2RST, 0U),             /*!< CFGCMP reset */
+    RCU_ADCRST     = RCU_REGIDX_BIT(IDX_APB2RST, 9U),             /*!< ADC reset */
+    RCU_TIMER0RST  = RCU_REGIDX_BIT(IDX_APB2RST, 11U),            /*!< TIMER0 reset */
+    RCU_SPI0RST    = RCU_REGIDX_BIT(IDX_APB2RST, 12U),            /*!< SPI0 reset */
+    RCU_USART0RST  = RCU_REGIDX_BIT(IDX_APB2RST, 14U),            /*!< USART0 reset */
+    RCU_TIMER14RST = RCU_REGIDX_BIT(IDX_APB2RST, 16U),            /*!< TIMER14 reset */
+    RCU_TIMER15RST = RCU_REGIDX_BIT(IDX_APB2RST, 17U),            /*!< TIMER15 reset */
+    RCU_TIMER16RST = RCU_REGIDX_BIT(IDX_APB2RST, 18U),            /*!< TIMER16 reset */
+    
+    /* APB1 peripherals reset */
+    RCU_TIMER2RST  = RCU_REGIDX_BIT(IDX_APB1RST, 1U),             /*!< TIMER2 reset */
+    RCU_TIMER5RST  = RCU_REGIDX_BIT(IDX_APB1RST, 4U),             /*!< TIMER5 reset */
+    RCU_TIMER13RST = RCU_REGIDX_BIT(IDX_APB1RST, 8U),             /*!< TIMER13 reset */
+    RCU_WWDGTRST   = RCU_REGIDX_BIT(IDX_APB1RST, 11U),            /*!< WWDGT reset */
+    RCU_SPI1RST    = RCU_REGIDX_BIT(IDX_APB1RST, 14U),            /*!< SPI1 reset */
+    RCU_USART1RST  = RCU_REGIDX_BIT(IDX_APB1RST, 17U),            /*!< USART1 reset */
+    RCU_I2C0RST    = RCU_REGIDX_BIT(IDX_APB1RST, 21U),            /*!< I2C0 reset */
+    RCU_I2C1RST    = RCU_REGIDX_BIT(IDX_APB1RST, 22U),            /*!< I2C1 reset */
+    RCU_PMURST     = RCU_REGIDX_BIT(IDX_APB1RST, 28U),            /*!< PMU reset */
+}rcu_periph_reset_enum;
+
+/* clock stabilization and peripheral reset flags */
+typedef enum
+{
+    RCU_FLAG_IRC40KSTB    = RCU_REGIDX_BIT(IDX_RSTSCK, 1U),       /*!< IRC40K stabilization flags */
+    RCU_FLAG_LXTALSTB     = RCU_REGIDX_BIT(IDX_BDCTL, 1U),        /*!< LXTAL stabilization flags */
+    RCU_FLAG_IRC8MSTB     = RCU_REGIDX_BIT(IDX_CTL0, 1U),         /*!< IRC8M stabilization flags */
+    RCU_FLAG_HXTALSTB     = RCU_REGIDX_BIT(IDX_CTL0, 17U),        /*!< HXTAL stabilization flags */
+    RCU_FLAG_PLLSTB       = RCU_REGIDX_BIT(IDX_CTL0, 25U),        /*!< PLL stabilization flags */
+    RCU_FLAG_IRC28MSTB    = RCU_REGIDX_BIT(IDX_CTL1, 1U),         /*!< IRC28M stabilization flags */
+
+    RCU_FLAG_V12RST       = RCU_REGIDX_BIT(IDX_RSTSCK, 23U),      /*!< V12 reset flags */
+    RCU_FLAG_OBLRST       = RCU_REGIDX_BIT(IDX_RSTSCK, 25U),      /*!< OBL reset flags */
+    RCU_FLAG_EPRST        = RCU_REGIDX_BIT(IDX_RSTSCK, 26U),      /*!< EPR reset flags */
+    RCU_FLAG_PORRST       = RCU_REGIDX_BIT(IDX_RSTSCK, 27U),      /*!< power reset flags */
+    RCU_FLAG_SWRST        = RCU_REGIDX_BIT(IDX_RSTSCK, 28U),      /*!< SW reset flags */
+    RCU_FLAG_FWDGTRST     = RCU_REGIDX_BIT(IDX_RSTSCK, 29U),      /*!< FWDGT reset flags */
+    RCU_FLAG_WWDGTRST     = RCU_REGIDX_BIT(IDX_RSTSCK, 30U),      /*!< WWDGT reset flags */
+    RCU_FLAG_LPRST        = RCU_REGIDX_BIT(IDX_RSTSCK, 31U)       /*!< LP reset flags */
+}rcu_flag_enum;
+
+/* clock stabilization and ckm interrupt flags */
+typedef enum
+{
+    RCU_INT_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_INT, 0U),         /*!< IRC40K stabilization interrupt flag */
+    RCU_INT_FLAG_LXTALSTB  = RCU_REGIDX_BIT(IDX_INT, 1U),         /*!< LXTAL stabilization interrupt flag */
+    RCU_INT_FLAG_IRC8MSTB  = RCU_REGIDX_BIT(IDX_INT, 2U),         /*!< IRC8M stabilization interrupt flag */
+    RCU_INT_FLAG_HXTALSTB  = RCU_REGIDX_BIT(IDX_INT, 3U),         /*!< HXTAL stabilization interrupt flag */
+    RCU_INT_FLAG_PLLSTB    = RCU_REGIDX_BIT(IDX_INT, 4U),         /*!< PLL stabilization interrupt flag */
+    RCU_INT_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_INT, 5U),         /*!< IRC28M stabilization interrupt flag */
+    RCU_INT_FLAG_CKM       = RCU_REGIDX_BIT(IDX_INT, 7U),         /*!< CKM interrupt flag */
+}rcu_int_flag_enum;
+
+/* clock stabilization and stuck interrupt flags clear */
+typedef enum
+{
+    RCU_INT_FLAG_IRC40KSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 16U),    /*!< IRC40K stabilization interrupt flags clear */
+    RCU_INT_FLAG_LXTALSTB_CLR  = RCU_REGIDX_BIT(IDX_INT, 17U),    /*!< LXTAL stabilization interrupt flags clear */
+    RCU_INT_FLAG_IRC8MSTB_CLR  = RCU_REGIDX_BIT(IDX_INT, 18U),    /*!< IRC8M stabilization interrupt flags clear */
+    RCU_INT_FLAG_HXTALSTB_CLR  = RCU_REGIDX_BIT(IDX_INT, 19U),    /*!< HXTAL stabilization interrupt flags clear */
+    RCU_INT_FLAG_PLLSTB_CLR    = RCU_REGIDX_BIT(IDX_INT, 20U),    /*!< PLL stabilization interrupt flags clear */
+    RCU_INT_FLAG_IRC28MSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 21U),    /*!< IRC28M stabilization interrupt flags clear */
+    RCU_INT_FLAG_CKM_CLR       = RCU_REGIDX_BIT(IDX_INT, 23U),    /*!< CKM interrupt flags clear */
+}rcu_int_flag_clear_enum;
+
+/* clock stabilization interrupt enable or disable */
+typedef enum
+{
+    RCU_INT_IRC40KSTB       = RCU_REGIDX_BIT(IDX_INT, 8U),        /*!< IRC40K stabilization interrupt */
+    RCU_INT_LXTALSTB        = RCU_REGIDX_BIT(IDX_INT, 9U),        /*!< LXTAL stabilization interrupt */
+    RCU_INT_IRC8MSTB        = RCU_REGIDX_BIT(IDX_INT, 10U),       /*!< IRC8M stabilization interrupt */
+    RCU_INT_HXTALSTB        = RCU_REGIDX_BIT(IDX_INT, 11U),       /*!< HXTAL stabilization interrupt */
+    RCU_INT_PLLSTB          = RCU_REGIDX_BIT(IDX_INT, 12U),       /*!< PLL stabilization interrupt */
+    RCU_INT_IRC28MSTB       = RCU_REGIDX_BIT(IDX_INT, 13U),       /*!< IRC28M stabilization interrupt */
+}rcu_int_enum;
+
+/* ADC clock source */
+typedef enum
+{
+    RCU_ADCCK_IRC28M_DIV2   = 0U,                                 /*!< ADC clock source select IRC28M/2 */
+    RCU_ADCCK_IRC28M,                                             /*!< ADC clock source select IRC28M */
+    RCU_ADCCK_APB2_DIV2,                                          /*!< ADC clock source select APB2/2 */
+    RCU_ADCCK_AHB_DIV3,                                           /*!< ADC clock source select AHB/3 */
+    RCU_ADCCK_APB2_DIV4,                                          /*!< ADC clock source select APB2/4 */
+    RCU_ADCCK_AHB_DIV5,                                           /*!< ADC clock source select AHB/5 */
+    RCU_ADCCK_APB2_DIV6,                                          /*!< ADC clock source select APB2/6 */
+    RCU_ADCCK_AHB_DIV7,                                           /*!< ADC clock source select AHB/7 */
+    RCU_ADCCK_APB2_DIV8,                                          /*!< ADC clock source select APB2/8 */
+    RCU_ADCCK_AHB_DIV9                                            /*!< ADC clock source select AHB/9 */
+}rcu_adc_clock_enum;
+
+/* oscillator types */
+typedef enum
+{
+    RCU_HXTAL   = RCU_REGIDX_BIT(IDX_CTL0, 16U),                  /*!< HXTAL */
+    RCU_LXTAL   = RCU_REGIDX_BIT(IDX_BDCTL, 0U),                  /*!< LXTAL */
+    RCU_IRC8M   = RCU_REGIDX_BIT(IDX_CTL0, 0U),                   /*!< IRC8M */
+    RCU_IRC28M  = RCU_REGIDX_BIT(IDX_CTL1, 0U),                   /*!< IRC28M */
+    RCU_IRC40K  = RCU_REGIDX_BIT(IDX_RSTSCK, 0U),                 /*!< IRC40K */
+    RCU_PLL_CK  = RCU_REGIDX_BIT(IDX_CTL0, 24U)                   /*!< PLL */
+}rcu_osci_type_enum;
+
+/* rcu clock frequency */
+typedef enum
+{
+    CK_SYS      = 0U,                                             /*!< system clock */
+    CK_AHB,                                                       /*!< AHB clock */
+    CK_APB1,                                                      /*!< APB1 clock */
+    CK_APB2,                                                      /*!< APB2 clock */
+    CK_ADC,                                                       /*!< ADC clock */
+    CK_USART                                                      /*!< USART clock */
+}rcu_clock_freq_enum;
+
+/* system clock source select */
+#define CFG0_SCS(regval)            (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define RCU_CKSYSSRC_IRC8M          CFG0_SCS(0)                   /*!< system clock source select IRC8M */
+#define RCU_CKSYSSRC_HXTAL          CFG0_SCS(1)                   /*!< system clock source select HXTAL */
+#define RCU_CKSYSSRC_PLL            CFG0_SCS(2)                   /*!< system clock source select PLL */
+
+/* system clock source select status */
+#define CFG0_SCSS(regval)           (BITS(2,3) & ((uint32_t)(regval) << 2))
+#define RCU_SCSS_IRC8M              CFG0_SCSS(0)                  /*!< system clock source select IRC8M */
+#define RCU_SCSS_HXTAL              CFG0_SCSS(1)                  /*!< system clock source select HXTAL */
+#define RCU_SCSS_PLL                CFG0_SCSS(2)                  /*!< system clock source select PLL */
+
+/* AHB prescaler selection */
+#define CFG0_AHBPSC(regval)         (BITS(4,7) & ((uint32_t)(regval) << 4))
+#define RCU_AHB_CKSYS_DIV1          CFG0_AHBPSC(0)                /*!< AHB prescaler select CK_SYS */
+#define RCU_AHB_CKSYS_DIV2          CFG0_AHBPSC(8)                /*!< AHB prescaler select CK_SYS/2 */
+#define RCU_AHB_CKSYS_DIV4          CFG0_AHBPSC(9)                /*!< AHB prescaler select CK_SYS/4 */
+#define RCU_AHB_CKSYS_DIV8          CFG0_AHBPSC(10)               /*!< AHB prescaler select CK_SYS/8 */
+#define RCU_AHB_CKSYS_DIV16         CFG0_AHBPSC(11)               /*!< AHB prescaler select CK_SYS/16 */
+#define RCU_AHB_CKSYS_DIV64         CFG0_AHBPSC(12)               /*!< AHB prescaler select CK_SYS/64 */
+#define RCU_AHB_CKSYS_DIV128        CFG0_AHBPSC(13)               /*!< AHB prescaler select CK_SYS/128 */
+#define RCU_AHB_CKSYS_DIV256        CFG0_AHBPSC(14)               /*!< AHB prescaler select CK_SYS/256 */
+#define RCU_AHB_CKSYS_DIV512        CFG0_AHBPSC(15)               /*!< AHB prescaler select CK_SYS/512 */
+
+/* APB1 prescaler selection */
+#define CFG0_APB1PSC(regval)        (BITS(8,10) & ((uint32_t)(regval) << 8))
+#define RCU_APB1_CKAHB_DIV1         CFG0_APB1PSC(0)               /*!< APB1 prescaler select CK_AHB */
+#define RCU_APB1_CKAHB_DIV2         CFG0_APB1PSC(4)               /*!< APB1 prescaler select CK_AHB/2 */
+#define RCU_APB1_CKAHB_DIV4         CFG0_APB1PSC(5)               /*!< APB1 prescaler select CK_AHB/4 */
+#define RCU_APB1_CKAHB_DIV8         CFG0_APB1PSC(6)               /*!< APB1 prescaler select CK_AHB/8 */
+#define RCU_APB1_CKAHB_DIV16        CFG0_APB1PSC(7)               /*!< APB1 prescaler select CK_AHB/16 */
+
+/* APB2 prescaler selection */
+#define CFG0_APB2PSC(regval)        (BITS(11,13) & ((uint32_t)(regval) << 11))
+#define RCU_APB2_CKAHB_DIV1         CFG0_APB2PSC(0)               /*!< APB2 prescaler select CK_AHB */
+#define RCU_APB2_CKAHB_DIV2         CFG0_APB2PSC(4)               /*!< APB2 prescaler select CK_AHB/2 */
+#define RCU_APB2_CKAHB_DIV4         CFG0_APB2PSC(5)               /*!< APB2 prescaler select CK_AHB/4 */
+#define RCU_APB2_CKAHB_DIV8         CFG0_APB2PSC(6)               /*!< APB2 prescaler select CK_AHB/8 */
+#define RCU_APB2_CKAHB_DIV16        CFG0_APB2PSC(7)               /*!< APB2 prescaler select CK_AHB/16 */
+
+/* ADC clock prescaler selection */
+#define CFG0_ADCPSC(regval)         (BITS(14,15) & ((uint32_t)(regval) << 14))
+#define RCU_ADC_CKAPB2_DIV2         CFG0_ADCPSC(0)                /*!< ADC clock prescaler select CK_APB2/2 */
+#define RCU_ADC_CKAPB2_DIV4         CFG0_ADCPSC(1)                /*!< ADC clock prescaler select CK_APB2/4 */
+#define RCU_ADC_CKAPB2_DIV6         CFG0_ADCPSC(2)                /*!< ADC clock prescaler select CK_APB2/6 */
+#define RCU_ADC_CKAPB2_DIV8         CFG0_ADCPSC(3)                /*!< ADC clock prescaler select CK_APB2/8 */
+
+/* PLL clock source selection */
+#define RCU_PLLSRC_IRC8M_DIV2       (uint32_t)0x00000000U         /*!< PLL clock source select IRC8M/2 */
+#define RCU_PLLSRC_HXTAL            RCU_CFG0_PLLSEL               /*!< PLL clock source select HXTAL */
+
+/* HXTAL divider for PLL source clock selection */
+#define RCU_PLLPREDV                (uint32_t)0x00000000U         /*!< HXTAL clock selected */
+#define RCU_PLLPREDV_DIV2           RCU_CFG0_PLLPREDV             /*!< HXTAL/2 clock selected */
+
+/* PLL multiply factor */
+#define CFG0_PLLMF(regval)          (BITS(18,21) & ((uint32_t)(regval) << 18))
+#define RCU_PLL_MUL2                CFG0_PLLMF(0)                       /*!< PLL source clock multiply by 2 */
+#define RCU_PLL_MUL3                CFG0_PLLMF(1)                       /*!< PLL source clock multiply by 3 */
+#define RCU_PLL_MUL4                CFG0_PLLMF(2)                       /*!< PLL source clock multiply by 4 */
+#define RCU_PLL_MUL5                CFG0_PLLMF(3)                       /*!< PLL source clock multiply by 5 */
+#define RCU_PLL_MUL6                CFG0_PLLMF(4)                       /*!< PLL source clock multiply by 6 */
+#define RCU_PLL_MUL7                CFG0_PLLMF(5)                       /*!< PLL source clock multiply by 7 */
+#define RCU_PLL_MUL8                CFG0_PLLMF(6)                       /*!< PLL source clock multiply by 8 */
+#define RCU_PLL_MUL9                CFG0_PLLMF(7)                       /*!< PLL source clock multiply by 9 */
+#define RCU_PLL_MUL10               CFG0_PLLMF(8)                       /*!< PLL source clock multiply by 10 */
+#define RCU_PLL_MUL11               CFG0_PLLMF(9)                       /*!< PLL source clock multiply by 11 */
+#define RCU_PLL_MUL12               CFG0_PLLMF(10)                      /*!< PLL source clock multiply by 12 */
+#define RCU_PLL_MUL13               CFG0_PLLMF(11)                      /*!< PLL source clock multiply by 13 */
+#define RCU_PLL_MUL14               CFG0_PLLMF(12)                      /*!< PLL source clock multiply by 14 */
+#define RCU_PLL_MUL15               CFG0_PLLMF(13)                      /*!< PLL source clock multiply by 15 */
+#define RCU_PLL_MUL16               CFG0_PLLMF(14)                      /*!< PLL source clock multiply by 16 */
+#define RCU_PLL_MUL17               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(0))   /*!< PLL source clock multiply by 17 */
+#define RCU_PLL_MUL18               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(1))   /*!< PLL source clock multiply by 18 */
+#define RCU_PLL_MUL19               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(2))   /*!< PLL source clock multiply by 19 */
+#define RCU_PLL_MUL20               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(3))   /*!< PLL source clock multiply by 20 */
+#define RCU_PLL_MUL21               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(4))   /*!< PLL source clock multiply by 21 */
+#define RCU_PLL_MUL22               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(5))   /*!< PLL source clock multiply by 22 */
+#define RCU_PLL_MUL23               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(6))   /*!< PLL source clock multiply by 23 */
+#define RCU_PLL_MUL24               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(7))   /*!< PLL source clock multiply by 24 */
+#define RCU_PLL_MUL25               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(8))   /*!< PLL source clock multiply by 25 */
+#define RCU_PLL_MUL26               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(9))   /*!< PLL source clock multiply by 26 */
+#define RCU_PLL_MUL27               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(10))  /*!< PLL source clock multiply by 27 */
+#define RCU_PLL_MUL28               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(11))  /*!< PLL source clock multiply by 28 */
+#define RCU_PLL_MUL29               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(12))  /*!< PLL source clock multiply by 29 */
+#define RCU_PLL_MUL30               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(13))  /*!< PLL source clock multiply by 30 */
+#define RCU_PLL_MUL31               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(14))  /*!< PLL source clock multiply by 31 */
+#define RCU_PLL_MUL32               (RCU_CFG0_PLLMF4 | CFG0_PLLMF(15))  /*!< PLL source clock multiply by 32 */
+
+/* CK_OUT clock source selection */
+#define CFG0_CKOUTSEL(regval)       (BITS(24,26) & ((uint32_t)(regval) << 24))
+#define RCU_CKOUTSRC_NONE           CFG0_CKOUTSEL(0)                    /*!< no clock selected */
+#define RCU_CKOUTSRC_IRC28M         CFG0_CKOUTSEL(1)                    /*!< CK_OUT clock source select IRC28M */
+#define RCU_CKOUTSRC_IRC40K         CFG0_CKOUTSEL(2)                    /*!< CK_OUT clock source select IRC40K */
+#define RCU_CKOUTSRC_LXTAL          CFG0_CKOUTSEL(3)                    /*!< CK_OUT clock source select LXTAL */
+#define RCU_CKOUTSRC_CKSYS          CFG0_CKOUTSEL(4)                    /*!< CK_OUT clock source select CKSYS */
+#define RCU_CKOUTSRC_IRC8M          CFG0_CKOUTSEL(5)                    /*!< CK_OUT clock source select IRC8M */
+#define RCU_CKOUTSRC_HXTAL          CFG0_CKOUTSEL(6)                    /*!< CK_OUT clock source select HXTAL */
+#define RCU_CKOUTSRC_CKPLL_DIV1     (RCU_CFG0_PLLDV | CFG0_CKOUTSEL(7)) /*!< CK_OUT clock source select CK_PLL */
+#define RCU_CKOUTSRC_CKPLL_DIV2     CFG0_CKOUTSEL(7)                    /*!< CK_OUT clock source select CK_PLL/2 */
+
+/* CK_OUT divider */
+#define CFG0_CKOUTDIV(regval)       (BITS(28,30) & ((uint32_t)(regval) << 28))
+#define RCU_CKOUT_DIV1              CFG0_CKOUTDIV(0)                    /*!< CK_OUT is divided by 1 */
+#define RCU_CKOUT_DIV2              CFG0_CKOUTDIV(1)                    /*!< CK_OUT is divided by 2 */
+#define RCU_CKOUT_DIV4              CFG0_CKOUTDIV(2)                    /*!< CK_OUT is divided by 4 */
+#define RCU_CKOUT_DIV8              CFG0_CKOUTDIV(3)                    /*!< CK_OUT is divided by 8 */
+#define RCU_CKOUT_DIV16             CFG0_CKOUTDIV(4)                    /*!< CK_OUT is divided by 16 */
+#define RCU_CKOUT_DIV32             CFG0_CKOUTDIV(5)                    /*!< CK_OUT is divided by 32 */
+#define RCU_CKOUT_DIV64             CFG0_CKOUTDIV(6)                    /*!< CK_OUT is divided by 64 */
+#define RCU_CKOUT_DIV128            CFG0_CKOUTDIV(7)                    /*!< CK_OUT is divided by 128 */
+
+/* CK_PLL divide by 1 or 2 for CK_OUT */
+#define RCU_PLLDV_CKPLL_DIV2        (uint32_t)0x00000000U               /*!< CK_PLL divide by 2 for CK_OUT */
+#define RCU_PLLDV_CKPLL             RCU_CFG0_PLLDV                      /*!< CK_PLL divide by 1 for CK_OUT */
+
+/* LXTAL drive capability */
+#define BDCTL_LXTALDRI(regval)      (BITS(3,4) & ((uint32_t)(regval) << 3))
+#define RCU_LXTAL_LOWDRI            BDCTL_LXTALDRI(0)                   /*!< lower driving capability */
+#define RCU_LXTAL_MED_LOWDRI        BDCTL_LXTALDRI(1)                   /*!< medium low driving capability */
+#define RCU_LXTAL_MED_HIGHDRI       BDCTL_LXTALDRI(2)                   /*!< medium high driving capability */
+#define RCU_LXTAL_HIGHDRI           BDCTL_LXTALDRI(3)                   /*!< higher driving capability */
+
+/* RTC clock entry selection */
+#define BDCTL_RTCSRC(regval)        (BITS(8,9) & ((uint32_t)(regval) << 8))
+#define RCU_RTCSRC_NONE             BDCTL_RTCSRC(0)                     /*!< no clock selected */
+#define RCU_RTCSRC_LXTAL            BDCTL_RTCSRC(1)                     /*!< LXTAL selected as RTC source clock */
+#define RCU_RTCSRC_IRC40K           BDCTL_RTCSRC(2)                     /*!< IRC40K selected as RTC source clock */
+#define RCU_RTCSRC_HXTAL_DIV32      BDCTL_RTCSRC(3)                     /*!< HXTAL/32 selected as RTC source clock */
+
+/* CK_HXTAL divider previous PLL */
+#define CFG1_PREDV(regval)         (BITS(0,3) & ((uint32_t)(regval) << 0))
+#define RCU_PLL_PREDV1              CFG1_PREDV(0)                       /*!< PLL not divided */
+#define RCU_PLL_PREDV2              CFG1_PREDV(1)                       /*!< PLL divided by 2 */
+#define RCU_PLL_PREDV3              CFG1_PREDV(2)                       /*!< PLL divided by 3 */
+#define RCU_PLL_PREDV4              CFG1_PREDV(3)                       /*!< PLL divided by 4 */
+#define RCU_PLL_PREDV5              CFG1_PREDV(4)                       /*!< PLL divided by 5 */
+#define RCU_PLL_PREDV6              CFG1_PREDV(5)                       /*!< PLL divided by 6 */
+#define RCU_PLL_PREDV7              CFG1_PREDV(6)                       /*!< PLL divided by 7 */
+#define RCU_PLL_PREDV8              CFG1_PREDV(7)                       /*!< PLL divided by 8 */
+#define RCU_PLL_PREDV9              CFG1_PREDV(8)                       /*!< PLL divided by 9 */
+#define RCU_PLL_PREDV10             CFG1_PREDV(9)                       /*!< PLL divided by 10 */
+#define RCU_PLL_PREDV11             CFG1_PREDV(10)                      /*!< PLL divided by 11 */
+#define RCU_PLL_PREDV12             CFG1_PREDV(11)                      /*!< PLL divided by 12 */
+#define RCU_PLL_PREDV13             CFG1_PREDV(12)                      /*!< PLL divided by 13 */
+#define RCU_PLL_PREDV14             CFG1_PREDV(13)                      /*!< PLL divided by 14 */
+#define RCU_PLL_PREDV15             CFG1_PREDV(14)                      /*!< PLL divided by 15 */
+#define RCU_PLL_PREDV16             CFG1_PREDV(15)                      /*!< PLL divided by 16 */
+
+/* USART0 clock source selection */
+#define CFG2_USART0SEL(regval)      (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define RCU_USART0SRC_CKAPB2        CFG2_USART0SEL(0)                   /*!< CK_USART0 select CK_APB2 */
+#define RCU_USART0SRC_CKSYS         CFG2_USART0SEL(1)                   /*!< CK_USART0 select CK_SYS */
+#define RCU_USART0SRC_LXTAL         CFG2_USART0SEL(2)                   /*!< CK_USART0 select LXTAL */
+#define RCU_USART0SRC_IRC8M         CFG2_USART0SEL(3)                   /*!< CK_USART0 select IRC8M */
+
+/* ADC clock source selection */
+#define RCU_ADCSRC_IRC28M           (uint32_t)0x00000000U               /*!< ADC clock source select */
+#define RCU_ADCSRC_AHB_APB2DIV      RCU_CFG2_ADCSEL                     /*!< ADC clock source select */
+
+/* IRC28M clock divider for ADC */
+#define RCU_ADC_IRC28M_DIV2         (uint32_t)0x00000000U               /*!< IRC28M/2 select to ADC clock */
+#define RCU_ADC_IRC28M_DIV1         RCU_CFG2_IRC28MDIV                  /*!< IRC28M select to ADC clock */
+
+/* Deep-sleep mode voltage */
+#define DSV_DSLPVS(regval)          (BITS(0,1) & ((uint32_t)(regval) << 0))
+#define RCU_DEEPSLEEP_V_1_0         DSV_DSLPVS(0)                       /*!< core voltage is 1.0V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_0_9         DSV_DSLPVS(1)                       /*!< core voltage is 0.9V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_0_8         DSV_DSLPVS(2)                       /*!< core voltage is 0.8V in deep-sleep mode */
+#define RCU_DEEPSLEEP_V_1_2         DSV_DSLPVS(3)                       /*!< core voltage is 1.2V in deep-sleep mode */
+
+/* function declarations */
+/* deinitialize the RCU */
+void rcu_deinit(void);
+/* enable the peripherals clock */
+void rcu_periph_clock_enable(rcu_periph_enum periph);
+/* disable the peripherals clock */
+void rcu_periph_clock_disable(rcu_periph_enum periph);
+/* enable the peripherals clock when sleep mode */
+void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph);
+/* disable the peripherals clock when sleep mode */
+void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph);
+/* reset the peripherals */
+void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset);
+/* disable reset the peripheral */
+void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset);
+/* reset the BKP */
+void rcu_bkp_reset_enable(void);
+/* disable the BKP reset */
+void rcu_bkp_reset_disable(void);
+
+/* configure the system clock source */
+void rcu_system_clock_source_config(uint32_t ck_sys);
+/* get the system clock source */
+uint32_t rcu_system_clock_source_get(void);
+/* configure the AHB prescaler selection */
+void rcu_ahb_clock_config(uint32_t ck_ahb);
+/* configure the APB1 prescaler selection */
+void rcu_apb1_clock_config(uint32_t ck_apb1);
+/* configure the APB2 prescaler selection */
+void rcu_apb2_clock_config(uint32_t ck_apb2);
+/* configure the ADC clock source and prescaler selection */
+void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc);
+/* configure the CK_OUT clock source and divider */
+void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div);
+
+/* configure the PLL clock source selection and PLL multiply factor */
+void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul);
+/* configure the USART clock source selection */
+void rcu_usart_clock_config(uint32_t ck_usart);
+/* configure the RTC clock source selection */
+void rcu_rtc_clock_config(uint32_t rtc_clock_source);
+/* configure the HXTAL divider used as input of PLL */
+void rcu_hxtal_prediv_config(uint32_t hxtal_prediv);
+/* configure the LXTAL drive capability */
+void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap);
+
+/* get the clock stabilization and periphral reset flags */
+FlagStatus rcu_flag_get(rcu_flag_enum flag);
+/* clear the reset flag */
+void rcu_all_reset_flag_clear(void);
+/* get the clock stabilization interrupt and ckm flags */
+FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag);
+/* clear the interrupt flags */
+void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear);
+/* enable the stabilization interrupt */
+void rcu_interrupt_enable(rcu_int_enum stab_int);
+/* disable the stabilization interrupt */
+void rcu_interrupt_disable(rcu_int_enum stab_int);
+
+/* wait until oscillator stabilization flags is SET */
+ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci);
+/* turn on the oscillator */
+void rcu_osci_on(rcu_osci_type_enum osci);
+/* turn off the oscillator */
+void rcu_osci_off(rcu_osci_type_enum osci);
+/* enable the oscillator bypass mode */
+void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci);
+/* disable the oscillator bypass mode */
+void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci);
+/* enable the HXTAL clock monitor */
+void rcu_hxtal_clock_monitor_enable(void);
+/* disable the HXTAL clock monitor */
+void rcu_hxtal_clock_monitor_disable(void);
+
+/* set the IRC8M adjust value */
+void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval);
+/* set the IRC28M adjust value */
+void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval);
+/* unlock the voltage key */
+void rcu_voltage_key_unlock(void);
+/* set the deep sleep mode voltage */
+void rcu_deepsleep_voltage_set(uint32_t dsvol);
+
+/* get the system clock, bus and peripheral clock frequency */
+uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock);
+
+#endif /* GD32E230_RCU_H */

+ 561 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h

@@ -0,0 +1,561 @@
+/*!
+    \file  gd32e230_rtc.h
+    \brief definitions for the RTC 
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_RTC_H
+#define GD32E230_RTC_H
+
+#include "gd32e230.h"
+
+/* RTC definitions */
+#define RTC                                RTC_BASE
+
+/* registers definitions */
+#define RTC_TIME                           REG32((RTC) + 0x00000000U)                  /*!< RTC time of day register */
+#define RTC_DATE                           REG32((RTC) + 0x00000004U)                  /*!< RTC date register */
+#define RTC_CTL                            REG32((RTC) + 0x00000008U)                  /*!< RTC control register */
+#define RTC_STAT                           REG32((RTC) + 0x0000000CU)                  /*!< RTC status register */
+#define RTC_PSC                            REG32((RTC) + 0x00000010U)                  /*!< RTC time prescaler register */
+#define RTC_ALRM0TD                        REG32((RTC) + 0x0000001CU)                  /*!< RTC alarm 0 time and date register */
+#define RTC_WPK                            REG32((RTC) + 0x00000024U)                  /*!< RTC write protection key register */
+#define RTC_SS                             REG32((RTC) + 0x00000028U)                  /*!< RTC sub second register */
+#define RTC_SHIFTCTL                       REG32((RTC) + 0x0000002CU)                  /*!< RTC shift function control register */
+#define RTC_TTS                            REG32((RTC) + 0x00000030U)                  /*!< RTC time of timestamp register */
+#define RTC_DTS                            REG32((RTC) + 0x00000034U)                  /*!< RTC date of timestamp register */
+#define RTC_SSTS                           REG32((RTC) + 0x00000038U)                  /*!< RTC sub second of timestamp register */
+#define RTC_HRFC                           REG32((RTC) + 0x0000003CU)                  /*!< RTC high resolution frequency compensation registor */
+#define RTC_TAMP                           REG32((RTC) + 0x00000040U)                  /*!< RTC tamper register */
+#define RTC_ALRM0SS                        REG32((RTC) + 0x00000044U)                  /*!< RTC alarm 0 sub second register */
+#define RTC_BKP0                           REG32((RTC) + 0x00000050U)                  /*!< RTC backup 0 register */
+#define RTC_BKP1                           REG32((RTC) + 0x00000054U)                  /*!< RTC backup 1 register */
+#define RTC_BKP2                           REG32((RTC) + 0x00000058U)                  /*!< RTC backup 2 register */
+#define RTC_BKP3                           REG32((RTC) + 0x0000005CU)                  /*!< RTC backup 3 register */
+#define RTC_BKP4                           REG32((RTC) + 0x00000060U)                  /*!< RTC backup 4 register */
+
+/* bits definitions */
+/* RTC_TIME */
+#define RTC_TIME_SCU                       BITS(0,3)                                   /*!< second units in BCD code */
+#define RTC_TIME_SCT                       BITS(4,6)                                   /*!< second tens in BCD code */
+#define RTC_TIME_MNU                       BITS(8,11)                                  /*!< minute units in BCD code */
+#define RTC_TIME_MNT                       BITS(12,14)                                 /*!< minute tens in BCD code */
+#define RTC_TIME_HRU                       BITS(16,19)                                 /*!< hour units in BCD code */
+#define RTC_TIME_HRT                       BITS(20,21)                                 /*!< hour tens in BCD code */
+#define RTC_TIME_PM                        BIT(22)                                     /*!< AM/PM notation */
+
+/* RTC_DATE */
+#define RTC_DATE_DAYU                      BITS(0,3)                                   /*!< date units in BCD code */
+#define RTC_DATE_DAYT                      BITS(4,5)                                   /*!< date tens in BCD code */
+#define RTC_DATE_MONU                      BITS(8,11)                                  /*!< month units in BCD code */
+#define RTC_DATE_MONT                      BIT(12)                                     /*!< month tens in BCD code */
+#define RTC_DATE_DOW                       BITS(13,15)                                 /*!< day of week units */
+#define RTC_DATE_YRU                       BITS(16,19)                                 /*!< year units in BCD code */
+#define RTC_DATE_YRT                       BITS(20,23)                                 /*!< year tens in BCD code */
+
+/* RTC_CTL */
+#define RTC_CTL_TSEG                       BIT(3)                                      /*!< valid event edge of time-stamp */
+#define RTC_CTL_REFEN                      BIT(4)                                      /*!< reference clock detection function enable */
+#define RTC_CTL_BPSHAD                     BIT(5)                                      /*!< shadow registers bypass control */
+#define RTC_CTL_CS                         BIT(6)                                      /*!< display format of clock system */
+#define RTC_CTL_ALRM0EN                    BIT(8)                                      /*!< alarm function enable */
+#define RTC_CTL_TSEN                       BIT(11)                                     /*!< time-stamp function enable */
+#define RTC_CTL_ALRM0IE                    BIT(12)                                     /*!< RTC alarm interrupt enable */
+#define RTC_CTL_TSIE                       BIT(15)                                     /*!< time-stamp interrupt enable */
+#define RTC_CTL_A1H                        BIT(16)                                     /*!< add 1 hour(summer time change) */
+#define RTC_CTL_S1H                        BIT(17)                                     /*!< subtract 1 hour(winter time change) */
+#define RTC_CTL_DSM                        BIT(18)                                     /*!< daylight saving mark */
+#define RTC_CTL_COS                        BIT(19)                                     /*!< calibration output selection */
+#define RTC_CTL_OPOL                       BIT(20)                                     /*!< output polarity */
+#define RTC_CTL_OS                         BITS(21,22)                                 /*!< output selection */
+#define RTC_CTL_COEN                       BIT(23)                                     /*!< calibration output enable */
+
+/* RTC_STAT */
+#define RTC_STAT_ALRM0WF                   BIT(0)                                      /*!< alarm configuration can be write flag */
+#define RTC_STAT_SOPF                      BIT(3)                                      /*!< shift function operation pending flag */
+#define RTC_STAT_YCM                       BIT(4)                                      /*!< year configuration mark status flag */
+#define RTC_STAT_RSYNF                     BIT(5)                                      /*!< register synchronization flag */
+#define RTC_STAT_INITF                     BIT(6)                                      /*!< initialization state flag */
+#define RTC_STAT_INITM                     BIT(7)                                      /*!< enter initialization mode */
+#define RTC_STAT_ALRM0F                    BIT(8)                                      /*!< alarm occurs flag */
+#define RTC_STAT_TSF                       BIT(11)                                     /*!< time-stamp flag */
+#define RTC_STAT_TSOVRF                    BIT(12)                                     /*!< time-stamp overflow flag */
+#define RTC_STAT_TP0F                      BIT(13)                                     /*!< RTC tamp 0 detected flag */
+#define RTC_STAT_TP1F                      BIT(14)                                     /*!< RTC tamp 1 detected flag */
+#define RTC_STAT_SCPF                      BIT(16)                                     /*!< recalibration pending flag */
+
+/* RTC_PSC */
+#define RTC_PSC_FACTOR_S                   BITS(0,14)                                  /*!< synchronous prescaler factor */
+#define RTC_PSC_FACTOR_A                   BITS(16,22)                                 /*!< asynchronous prescaler factor */
+
+/* RTC_ALRM0TD */
+#define RTC_ALRM0TD_SCU                    BITS(0,3)                                   /*!< second units in BCD code */
+#define RTC_ALRM0TD_SCT                    BITS(4,6)                                   /*!< second tens in BCD code */
+#define RTC_ALRM0TD_MSKS                   BIT(7)                                      /*!< alarm second mask bit */
+#define RTC_ALRM0TD_MNU                    BITS(8,11)                                  /*!< minutes units in BCD code */
+#define RTC_ALRM0TD_MNT                    BITS(12,14)                                 /*!< minutes tens in BCD code */
+#define RTC_ALRM0TD_MSKM                   BIT(15)                                     /*!< alarm minutes mask bit */
+#define RTC_ALRM0TD_HRU                    BITS(16,19)                                 /*!< hour units in BCD code */
+#define RTC_ALRM0TD_HRT                    BITS(20,21)                                 /*!< hour units in BCD code */
+#define RTC_ALRM0TD_PM                     BIT(22)                                     /*!< AM/PM flag */
+#define RTC_ALRM0TD_MSKH                   BIT(23)                                     /*!< alarm hour mask bit */
+#define RTC_ALRM0TD_DAYU                   BITS(24,27)                                 /*!< date units or week day in BCD code */
+#define RTC_ALRM0TD_DAYT                   BITS(28,29)                                 /*!< date tens in BCD code */
+#define RTC_ALRM0TD_DOWS                   BIT(30)                                     /*!< day of week  selection */
+#define RTC_ALRM0TD_MSKD                   BIT(31)                                     /*!< alarm date mask bit */
+
+/* RTC_WPK */
+#define RTC_WPK_WPK                        BITS(0,7)                                   /*!< key for write protection */
+
+/* RTC_SS */
+#define RTC_SS_SSC                         BITS(0,15)                                  /*!< sub second value */
+
+/* RTC_SHIFTCTL */
+#define RTC_SHIFTCTL_SFS                   BITS(0,14)                                  /*!< subtract a fraction of a second */
+#define RTC_SHIFTCTL_A1S                   BIT(31)                                     /*!< one second add */
+
+/* RTC_TTS */
+#define RTC_TTS_SCU                        BITS(0,3)                                   /*!< second units in BCD code */
+#define RTC_TTS_SCT                        BITS(4,6)                                   /*!< second units in BCD code */
+#define RTC_TTS_MNU                        BITS(8,11)                                  /*!< minute units in BCD code */
+#define RTC_TTS_MNT                        BITS(12,14)                                 /*!< minute tens in BCD code */
+#define RTC_TTS_HRU                        BITS(16,19)                                 /*!< hour units in BCD code */
+#define RTC_TTS_HRT                        BITS(20,21)                                 /*!< hour tens in BCD code */
+#define RTC_TTS_PM                         BIT(22)                                     /*!< AM/PM notation */
+
+/* RTC_DTS */
+#define RTC_DTS_DAYU                       BITS(0,3)                                   /*!< date units in BCD code */
+#define RTC_DTS_DAYT                       BITS(4,5)                                   /*!< date tens in BCD code */
+#define RTC_DTS_MONU                       BITS(8,11)                                  /*!< month units in BCD code */
+#define RTC_DTS_MONT                       BIT(12)                                     /*!< month tens in BCD code */
+#define RTC_DTS_DOW                        BITS(13,15)                                 /*!< day of week units */
+
+/* RTC_SSTS */
+#define RTC_SSTS_SSC                       BITS(0,15)                                  /*!< timestamp sub second units */
+
+/* RTC_HRFC */
+#define RTC_HRFC_CMSK                      BITS(0,8)                                   /*!< calibration mask number */
+#define RTC_HRFC_CWND16                    BIT(13)                                     /*!< calibration window select 16 seconds */
+#define RTC_HRFC_CWND8                     BIT(14)                                     /*!< calibration window select 16 seconds */
+#define RTC_HRFC_FREQI                     BIT(15)                                     /*!< increase RTC frequency by 488.5ppm */
+
+/* RTC_TAMP */
+#define RTC_TAMP_TP0EN                     BIT(0)                                      /*!< tamper 0 detection enable */
+#define RTC_TAMP_TP0EG                     BIT(1)                                      /*!< tamper 0 event trigger edge for RTC tamp 0 input */
+#define RTC_TAMP_TPIE                      BIT(2)                                      /*!< tamper detection interrupt enable */
+#define RTC_TAMP_TP1EN                     BIT(3)                                      /*!< tamper 1 detection enable */
+#define RTC_TAMP_TP1EG                     BIT(4)                                      /*!< tamper 1 event trigger edge for RTC tamp 1 input */
+#define RTC_TAMP_TPTS                      BIT(7)                                      /*!< make tamper function used for timestamp function */
+#define RTC_TAMP_FREQ                      BITS(8,10)                                  /*!< sample frequency of tamper event detection */
+#define RTC_TAMP_FLT                       BITS(11,12)                                 /*!< RTC tamp x filter count setting */
+#define RTC_TAMP_PRCH                      BITS(13,14)                                 /*!< precharge duration time of RTC tamp x */
+#define RTC_TAMP_DISPU                     BIT(15)                                     /*!< RTC tamp x pull up disable bit */
+#define RTC_TAMP_PC13VAL                   BIT(18)                                     /*!< alarm output type control/PC13 output value */
+#define RTC_TAMP_PC13MDE                   BIT(19)                                     /*!< PC13 mode */
+#define RTC_TAMP_PC14VAL                   BIT(20)                                     /*!< PC14 output value */
+#define RTC_TAMP_PC14MDE                   BIT(21)                                     /*!< PC14 mode */
+#define RTC_TAMP_PC15VAL                   BIT(22)                                     /*!< PC15 output value */
+#define RTC_TAMP_PC15MDE                   BIT(23)                                     /*!< PC15 mode */
+
+/* RTC_ALRM0SS */
+#define RTC_ALRM0SS_SSC                    BITS(0,14)                                  /*!< alarm sub second value */
+#define RTC_ALRM0SS_MASKSSC                BITS(24,27)                                 /*!< mask control bit of SS */
+
+/* RTC_BKP0 */
+#define RTC_BKP0_DATA                      BITS(0,31)                                  /*!< backup domain registers */
+
+/* RTC_BKP1 */
+#define RTC_BKP1_DATA                      BITS(0,31)                                  /*!< backup domain registers */
+
+/* RTC_BKP2 */
+#define RTC_BKP2_DATA                      BITS(0,31)                                  /*!< backup domain registers */
+
+/* RTC_BKP3 */
+#define RTC_BKP3_DATA                      BITS(0,31)                                  /*!< backup domain registers */
+
+/* RTC_BKP4 */
+#define RTC_BKP4_DATA                      BITS(0,31)                                  /*!< backup domain registers */
+
+/* constants definitions */
+/* structure for initialization of the RTC */
+typedef struct
+{
+    uint8_t rtc_year;                                                                  /*!< RTC year value: 0x0 - 0x99(BCD format) */
+    uint8_t rtc_month;                                                                 /*!< RTC month value */
+    uint8_t rtc_date;                                                                  /*!< RTC date value: 0x1 - 0x31(BCD format) */
+    uint8_t rtc_day_of_week;                                                           /*!< RTC weekday value */
+    uint8_t rtc_hour;                                                                  /*!< RTC hour value */
+    uint8_t rtc_minute;                                                                /*!< RTC minute value: 0x0 - 0x59(BCD format) */
+    uint8_t rtc_second;                                                                /*!< RTC second value: 0x0 - 0x59(BCD format) */
+    uint16_t rtc_factor_asyn;                                                          /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */
+    uint16_t rtc_factor_syn;                                                           /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */
+    uint32_t rtc_am_pm;                                                                /*!< RTC AM/PM value */
+    uint32_t rtc_display_format;                                                       /*!< RTC time notation */
+}rtc_parameter_struct;
+
+/* structure for RTC alarm configuration */
+typedef struct
+{
+    uint32_t rtc_alarm_mask;                                                           /*!< RTC alarm mask */
+    uint32_t rtc_weekday_or_date;                                                      /*!< specify RTC alarm is on date or weekday */
+    uint8_t rtc_alarm_day;                                                             /*!< RTC alarm date or weekday value*/
+    uint8_t rtc_alarm_hour;                                                            /*!< RTC alarm hour value */
+    uint8_t rtc_alarm_minute;                                                          /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */
+    uint8_t rtc_alarm_second;                                                          /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */
+    uint32_t rtc_am_pm;                                                                /*!< RTC alarm AM/PM value */
+}rtc_alarm_struct;
+
+/* structure for RTC time-stamp configuration */
+typedef struct
+{
+    uint8_t rtc_timestamp_month;                                                       /*!< RTC time-stamp month value */
+    uint8_t rtc_timestamp_date;                                                        /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */
+    uint8_t rtc_timestamp_day;                                                         /*!< RTC time-stamp weekday value */
+    uint8_t rtc_timestamp_hour;                                                        /*!< RTC time-stamp hour value */
+    uint8_t rtc_timestamp_minute;                                                      /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */
+    uint8_t rtc_timestamp_second;                                                      /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */
+    uint32_t rtc_am_pm;                                                                /*!< RTC time-stamp AM/PM value */
+}rtc_timestamp_struct;
+
+/* structure for RTC tamper configuration */
+typedef struct
+{
+    uint32_t rtc_tamper_source;                                                        /*!< RTC tamper source */
+    uint32_t rtc_tamper_trigger;                                                       /*!< RTC tamper trigger */
+    uint32_t rtc_tamper_filter;                                                        /*!< RTC tamper consecutive samples needed during a voltage level detection */
+    uint32_t rtc_tamper_sample_frequency;                                              /*!< RTC tamper sampling frequency during a voltage level detection */
+    ControlStatus rtc_tamper_precharge_enable;                                         /*!< RTC tamper precharge feature during a voltage level detection */
+    uint32_t rtc_tamper_precharge_time;                                                /*!< RTC tamper precharge duration if precharge feature is enabled */
+    ControlStatus rtc_tamper_with_timestamp;                                           /*!< RTC tamper time-stamp feature */
+}rtc_tamper_struct; 
+
+/* time register value */
+#define TIME_SC(regval)                    (BITS(0,6) & ((uint32_t)(regval) << 0U))     /*!< write value to RTC_TIME_SC bit field */
+#define GET_TIME_SC(regval)                GET_BITS((regval),0,6)                      /*!< get value of RTC_TIME_SC bit field */
+
+#define TIME_MN(regval)                    (BITS(8,14) & ((uint32_t)(regval) << 8U))    /*!< write value to RTC_TIME_MN bit field */
+#define GET_TIME_MN(regval)                GET_BITS((regval),8,14)                     /*!< get value of RTC_TIME_MN bit field */
+
+#define TIME_HR(regval)                    (BITS(16,21) & ((uint32_t)(regval) << 16U))  /*!< write value to RTC_TIME_HR bit field */
+#define GET_TIME_HR(regval)                GET_BITS((regval),16,21)                    /*!< get value of RTC_TIME_HR bit field */
+
+#define RTC_AM                             ((uint32_t)0x00000000U)                      /*!< AM format */
+#define RTC_PM                             RTC_TIME_PM                                 /*!< PM format */
+
+/* date register value */
+#define DATE_DAY(regval)                   (BITS(0,5) & ((uint32_t)(regval) << 0U))     /*!< write value to RTC_DATE_DAY bit field */
+#define GET_DATE_DAY(regval)               GET_BITS((regval),0,5)                      /*!< get value of RTC_DATE_DAY bit field */
+
+#define DATE_MON(regval)                   (BITS(8,12) & ((uint32_t)(regval) << 8U))    /*!< write value to RTC_DATE_MON bit field */
+#define GET_DATE_MON(regval)               GET_BITS((regval),8,12)                     /*!< get value of RTC_DATE_MON bit field */
+#define RTC_JAN                            ((uint8_t)0x01U)                            /*!< Janurary */
+#define RTC_FEB                            ((uint8_t)0x02U)                            /*!< February */
+#define RTC_MAR                            ((uint8_t)0x03U)                            /*!< March */
+#define RTC_APR                            ((uint8_t)0x04U)                            /*!< April */
+#define RTC_MAY                            ((uint8_t)0x05U)                            /*!< May */
+#define RTC_JUN                            ((uint8_t)0x06U)                            /*!< June */
+#define RTC_JUL                            ((uint8_t)0x07U)                            /*!< July */
+#define RTC_AUG                            ((uint8_t)0x08U)                            /*!< August */
+#define RTC_SEP                            ((uint8_t)0x09U)                            /*!< September */
+#define RTC_OCT                            ((uint8_t)0x10U)                            /*!< October */
+#define RTC_NOV                            ((uint8_t)0x11U)                            /*!< November */
+#define RTC_DEC                            ((uint8_t)0x12U)                            /*!< December */
+
+#define DATE_DOW(regval)                   (BITS(13,15) & ((uint32_t)(regval) << 13U))  /*!< write value to RTC_DATE_DOW bit field */
+#define GET_DATE_DOW(regval)               GET_BITS((regval),13,15)                    /*!< get value of RTC_DATE_DOW bit field */
+#define RTC_MONDAY                         ((uint8_t)0x01U)                            /*!< Monday */
+#define RTC_TUESDAY                        ((uint8_t)0x02U)                            /*!< Tuesday */
+#define RTC_WEDSDAY                        ((uint8_t)0x03U)                            /*!< Wednesday */
+#define RTC_THURSDAY                       ((uint8_t)0x04U)                            /*!< Thursday */
+#define RTC_FRIDAY                         ((uint8_t)0x05U)                            /*!< Friday */
+#define RTC_SATURDAY                       ((uint8_t)0x06U)                            /*!< Saturday */
+#define RTC_SUNDAY                         ((uint8_t)0x07U)                            /*!< Sunday */
+
+#define DATE_YR(regval)                    (BITS(16,23) & ((uint32_t)(regval) << 16U))  /*!< write value to RTC_DATE_YR bit field */
+#define GET_DATE_YR(regval)                GET_BITS((regval),16,23)                    /*!< get value of RTC_DATE_YR bit field */
+
+/* ctl register value */
+#define CTL_OS(regval)                     (BITS(21,22) & ((uint32_t)(regval) << 21U))   /*!< write value to RTC_CTL_OS bit field */
+#define RTC_OS_DISABLE                     CTL_OS(0)                                   /*!< disable output RTC_ALARM */
+#define RTC_OS_ENABLE                      CTL_OS(1)                                   /*!< enable alarm flag output */
+
+#define RTC_CALIBRATION_512HZ              RTC_CTL_COEN                                /*!< calibration output of 512Hz is enable */
+#define RTC_CALIBRATION_1HZ                (RTC_CTL_COEN | RTC_CTL_COS)                /*!< calibration output of 1Hz is enable */
+#define RTC_ALARM_HIGH                     RTC_CTL_OS                                  /*!< enable alarm flag output with high level */
+#define RTC_ALARM_LOW                      (RTC_CTL_OS | RTC_CTL_OPOL)                 /*!< enable alarm flag output with low level*/
+
+#define RTC_24HOUR                         ((uint32_t)0x00000000U)                     /*!< 24-hour format */
+#define RTC_12HOUR                         RTC_CTL_CS                                  /*!< 12-hour format */
+
+#define RTC_TIMESTAMP_RISING_EDGE          ((uint32_t)0x00000000U)                     /*!< rising edge is valid event edge for time-stamp event */
+#define RTC_TIMESTAMP_FALLING_EDGE         RTC_CTL_TSEG                                /*!< falling edge is valid event edge for time-stamp event */
+ 
+/* psc register value */
+#define PSC_FACTOR_S(regval)               (BITS(0,14) & ((uint32_t)(regval) << 0U))    /*!< write value to RTC_PSC_FACTOR_S bit field */
+#define GET_PSC_FACTOR_S(regval)           GET_BITS((regval),0,14)                     /*!< get value of RTC_PSC_FACTOR_S bit field */
+
+#define PSC_FACTOR_A(regval)               (BITS(16,22) & ((uint32_t)(regval) << 16U))  /*!< write value to RTC_PSC_FACTOR_A bit field */
+#define GET_PSC_FACTOR_A(regval)           GET_BITS((regval),16,22)                    /*!< get value of RTC_PSC_FACTOR_A bit field */
+
+/* alrm0td register value */
+#define ALRM0TD_SC(regval)                 (BITS(0,6) & ((uint32_t)(regval)<< 0U))      /*!< write value to RTC_ALRM0TD_SC bit field */
+#define GET_ALRM0TD_SC(regval)             GET_BITS((regval),0,6)                      /*!< get value of RTC_ALRM0TD_SC bit field */
+
+#define ALRM0TD_MN(regval)                 (BITS(8,14) & ((uint32_t)(regval) << 8U))    /*!< write value to RTC_ALRM0TD_MN bit field */
+#define GET_ALRM0TD_MN(regval)             GET_BITS((regval),8,14)                     /*!< get value of RTC_ALRM0TD_MN bit field */
+
+#define ALRM0TD_HR(regval)                 (BITS(16,21) & ((uint32_t)(regval) << 16U))  /*!< write value to RTC_ALRM0TD_HR bit field */
+#define GET_ALRM0TD_HR(regval)             GET_BITS((regval),16,21)                    /*!< get value of RTC_ALRM0TD_HR bit field */
+
+#define ALRM0TD_DAY(regval)                (BITS(24,29) & ((uint32_t)(regval) << 24U))  /*!< write value to RTC_ALRM0TD_DAY bit field */
+#define GET_ALRM0TD_DAY(regval)            GET_BITS((regval),24,29)                    /*!< get value of RTC_ALRM0TD_DAY bit field */
+
+#define RTC_ALARM_NONE_MASK                ((uint32_t)0x00000000U)                     /*!< alarm none mask */
+#define RTC_ALARM_DATE_MASK                RTC_ALRM0TD_MSKD                            /*!< alarm date mask */
+#define RTC_ALARM_HOUR_MASK                RTC_ALRM0TD_MSKH                            /*!< alarm hour mask */
+#define RTC_ALARM_MINUTE_MASK              RTC_ALRM0TD_MSKM                            /*!< alarm minute mask */
+#define RTC_ALARM_SECOND_MASK              RTC_ALRM0TD_MSKS                            /*!< alarm second mask */
+#define RTC_ALARM_ALL_MASK                 (RTC_ALRM0TD_MSKD|RTC_ALRM0TD_MSKH|RTC_ALRM0TD_MSKM|RTC_ALRM0TD_MSKS)    /*!< alarm all mask */
+
+#define RTC_ALARM_DATE_SELECTED            ((uint32_t)0x00000000U)                     /*!< alarm date format selected */
+#define RTC_ALARM_WEEKDAY_SELECTED         RTC_ALRM0TD_DOWS                            /*!< alarm weekday format selected */
+
+/* wpk register value */
+#define WPK_WPK(regval)                    (BITS(0,7) & ((uint32_t)(regval) << 0U))     /*!< write value to RTC_WPK_WPK bit field */
+
+/* ss register value */
+#define SS_SSC(regval)                     (BITS(0,15) & ((uint32_t)(regval) << 0U))    /*!< write value to RTC_SS_SSC bit field */
+
+/* shiftctl register value */
+#define SHIFTCTL_SFS(regval)               (BITS(0,14) & ((uint32_t)(regval) << 0U))    /*!< write value to RTC_SHIFTCTL_SFS bit field */
+
+#define RTC_SHIFT_ADD1S_RESET              ((uint32_t)0x00000000U)                     /*!< not add 1 second */
+#define RTC_SHIFT_ADD1S_SET                RTC_SHIFTCTL_A1S                            /*!< add one second to the clock */
+
+/* tts register value */
+#define TTS_SC(regval)                     (BITS(0,6) & ((uint32_t)(regval) << 0U))     /*!< write value to RTC_TTS_SC bit field */
+#define GET_TTS_SC(regval)                 GET_BITS((regval),0,6)                      /*!< get value of RTC_TTS_SC bit field */
+
+#define TTS_MN(regval)                     (BITS(8,14) & ((uint32_t)(regval) << 8U))    /*!< write value to RTC_TTS_MN bit field */
+#define GET_TTS_MN(regval)                 GET_BITS((regval),8,14)                     /*!< get value of RTC_TTS_MN bit field */
+
+#define TTS_HR(regval)                     (BITS(16,21) & ((uint32_t)(regval) << 16U))  /*!< write value to RTC_TTS_HR bit field */
+#define GET_TTS_HR(regval)                 GET_BITS((regval),16,21)                    /*!< get value of RTC_TTS_HR bit field */
+
+/* dts register value */
+#define DTS_DAY(regval)                    (BITS(0,5) & ((uint32_t)(regval) << 0U))     /*!< write value to RTC_DTS_DAY bit field */
+#define GET_DTS_DAY(regval)                GET_BITS((regval),0,5)                      /*!< get value of RTC_DTS_DAY bit field */
+
+#define DTS_MON(regval)                    (BITS(8,12) & ((uint32_t)(regval) << 8U))    /*!< write value to RTC_DTS_MON bit field */
+#define GET_DTS_MON(regval)                GET_BITS((regval),8,12)                     /*!< get value of RTC_DTS_MON bit field */
+
+#define DTS_DOW(regval)                    (BITS(13,15) & ((uint32_t)(regval) << 13U))  /*!< write value to RTC_DTS_DOW bit field */
+#define GET_DTS_DOW(regval)                GET_BITS((regval),13,15)                    /*!< get value of RTC_DTS_DOW bit field */
+
+/* ssts register value */
+#define SSTS_SSC(regval)                   (BITS(0,15) & ((uint32_t)(regval) << 0U))    /*!< write value to RTC_SSTS_SSC bit field */
+
+/* hrfc register value */
+#define HRFC_CMSK(regval)                  (BITS(0,8) & ((uint32_t)(regval) << 0U))     /*!< write value to RTC_HRFC_CMSK bit field */
+
+#define RTC_CALIBRATION_WINDOW_32S         ((uint32_t)0x00000000U)                     /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */
+#define RTC_CALIBRATION_WINDOW_16S         RTC_HRFC_CWND16                             /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */
+#define RTC_CALIBRATION_WINDOW_8S          RTC_HRFC_CWND8                              /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */
+
+#define RTC_CALIBRATION_PLUS_SET           RTC_HRFC_FREQI                              /*!< increase RTC frequency by 488.5ppm */
+#define RTC_CALIBRATION_PLUS_RESET         ((uint32_t)0x00000000U)                     /*!< no effect */
+
+/* tamp register value */
+#define TAMP_FREQ(regval)                  (BITS(8,10) & ((uint32_t)(regval) << 8U))    /*!< write value to RTC_TAMP_FREQ bit field */
+#define RTC_FREQ_DIV32768                  TAMP_FREQ(0)                                /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV16384                  TAMP_FREQ(1)                                /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV8192                   TAMP_FREQ(2)                                /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV4096                   TAMP_FREQ(3)                                /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV2048                   TAMP_FREQ(4)                                /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV1024                   TAMP_FREQ(5)                                /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV512                    TAMP_FREQ(6)                                /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */
+#define RTC_FREQ_DIV256                    TAMP_FREQ(7)                                /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */
+
+#define TAMP_FLT(regval)                   (BITS(11,12) & ((uint32_t)(regval) << 11U))  /*!< write value to RTC_TAMP_FLT bit field */
+#define RTC_FLT_EDGE                       TAMP_FLT(0)                                 /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */
+#define RTC_FLT_2S                         TAMP_FLT(1)                                 /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event  */
+#define RTC_FLT_4S                         TAMP_FLT(2)                                 /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */
+#define RTC_FLT_8S                         TAMP_FLT(3)                                 /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event  */
+
+#define TAMP_PRCH(regval)                  (BITS(13,14) & ((uint32_t)(regval) << 13U))  /*!< write value to RTC_TAMP_PRCH bit field */
+#define RTC_PRCH_1C                        TAMP_PRCH(0)                                /*!< 1 RTC clock prechagre time before each sampling */
+#define RTC_PRCH_2C                        TAMP_PRCH(1)                                /*!< 2 RTC clock prechagre time before each sampling  */
+#define RTC_PRCH_4C                        TAMP_PRCH(2)                                /*!< 4 RTC clock prechagre time before each sampling */
+#define RTC_PRCH_8C                        TAMP_PRCH(3)                                /*!< 8 RTC clock prechagre time before each sampling */
+
+#define RTC_TAMPER0                        RTC_TAMP_TP0EN                              /*!< tamper 0 detection enable */
+#define RTC_TAMPER1                        RTC_TAMP_TP1EN                              /*!< tamper 1 detection enable */
+
+#define RTC_TAMPER_TRIGGER_EDGE_RISING     ((uint32_t)0x00000000U)                     /*!< tamper detection is in rising edge mode */
+#define RTC_TAMPER_TRIGGER_EDGE_FALLING    RTC_TAMP_TP0EG                              /*!< tamper detection is in falling edge mode */
+#define RTC_TAMPER_TRIGGER_LEVEL_LOW       ((uint32_t)0x00000000U)                     /*!< tamper detection is in low level mode */
+#define RTC_TAMPER_TRIGGER_LEVEL_HIGH      RTC_TAMP_TP0EG                              /*!< tamper detection is in high level mode */
+
+#define RTC_TAMPER_TRIGGER_POS             ((uint32_t)0x00000001U)                     /* shift position of trigger relative to source */
+
+#define RTC_ALARM_OUTPUT_OD                ((uint32_t)0x00000000U)                     /*!< RTC alarm output open-drain mode */
+#define RTC_ALARM_OUTPUT_PP                RTC_TAMP_PC13VAL                            /*!< RTC alarm output push-pull mode */
+
+/* alrm0ss register value */
+#define ALRM0SS_SSC(regval)                (BITS(0,14) & ((uint32_t)(regval)<< 0U))     /*!< write value to RTC_ALRM0SS_SSC bit field */
+
+#define ALRM0SS_MASKSSC(regval)            (BITS(24,27) & ((uint32_t)(regval) << 24U))  /*!< write value to RTC_ALRM0SS_MASKSSC bit field */
+#define RTC_MASKSSC_0_14                   ALRM0SS_MASKSSC(0)                          /*!< mask alarm subsecond configuration */
+#define RTC_MASKSSC_1_14                   ALRM0SS_MASKSSC(1)                          /*!< mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared */
+#define RTC_MASKSSC_2_14                   ALRM0SS_MASKSSC(2)                          /*!< mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared */
+#define RTC_MASKSSC_3_14                   ALRM0SS_MASKSSC(3)                          /*!< mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared */
+#define RTC_MASKSSC_4_14                   ALRM0SS_MASKSSC(4)                          /*!< mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared */
+#define RTC_MASKSSC_5_14                   ALRM0SS_MASKSSC(5)                          /*!< mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared */
+#define RTC_MASKSSC_6_14                   ALRM0SS_MASKSSC(6)                          /*!< mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared */
+#define RTC_MASKSSC_7_14                   ALRM0SS_MASKSSC(7)                          /*!< mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared */
+#define RTC_MASKSSC_8_14                   ALRM0SS_MASKSSC(8)                          /*!< mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared */
+#define RTC_MASKSSC_9_14                   ALRM0SS_MASKSSC(9)                          /*!< mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared */
+#define RTC_MASKSSC_10_14                  ALRM0SS_MASKSSC(10)                         /*!< mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared */
+#define RTC_MASKSSC_11_14                  ALRM0SS_MASKSSC(11)                         /*!< mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared */
+#define RTC_MASKSSC_12_14                  ALRM0SS_MASKSSC(12)                         /*!< mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared */
+#define RTC_MASKSSC_13_14                  ALRM0SS_MASKSSC(13)                         /*!< mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared */
+#define RTC_MASKSSC_14                     ALRM0SS_MASKSSC(14)                         /*!< mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared */
+#define RTC_MASKSSC_NONE                   ALRM0SS_MASKSSC(15)                         /*!< mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared */
+
+/* RTC interrupt source */
+#define RTC_INT_TIMESTAMP                  RTC_CTL_TSIE                                /*!< time-stamp interrupt enable */
+#define RTC_INT_ALARM                      RTC_CTL_ALRM0IE                             /*!< RTC alarm interrupt enable */
+#define RTC_INT_TAMP                       RTC_TAMP_TPIE                               /*!< tamper detection interrupt enable */
+
+/* write protect key */
+#define RTC_UNLOCK_KEY1                    ((uint8_t)0xCAU)                            /*!< RTC unlock key1 */
+#define RTC_UNLOCK_KEY2                    ((uint8_t)0x53U)                            /*!< RTC unlock key2 */
+#define RTC_LOCK_KEY                       ((uint8_t)0xFFU)                            /*!< RTC lock key */
+
+/* registers reset value */
+#define RTC_REGISTER_RESET                 ((uint32_t)0x00000000U)                     /*!< RTC common register reset value */
+#define RTC_DATE_RESET                     ((uint32_t)0x00002101U)                     /*!< RTC_DATE register reset value */
+#define RTC_STAT_RESET                     ((uint32_t)0x00000007U)                     /*!< RTC_STAT register reset value */
+#define RTC_PSC_RESET                      ((uint32_t)0x007F00FFU)                     /*!< RTC_PSC register reset value */
+
+/* RTC timeout value */
+#define RTC_INITM_TIMEOUT                  ((uint32_t)0x00004000U)                     /*!< initialization state flag timeout */
+#define RTC_RSYNF_TIMEOUT                  ((uint32_t)0x00008000U)                     /*!< register synchronization flag timeout */
+#define RTC_HRFC_TIMEOUT                   ((uint32_t)0x00001000U)                     /*!< recalibration pending flag timeout */
+#define RTC_SHIFTCTL_TIMEOUT               ((uint32_t)0x00001000U)                     /*!< shift function operation pending flag timeout */
+#define RTC_ALRM0WF_TIMEOUT                ((uint32_t)0x00008000U)                     /*!< alarm configuration can be write flag timeout */
+
+/* RTC flag */
+#define RTC_FLAG_RECALIBRATION             RTC_STAT_SCPF                               /*!< recalibration pending flag */
+#define RTC_FLAG_TAMP1                     RTC_STAT_TP1F                               /*!< tamper 1 event flag */
+#define RTC_FLAG_TAMP0                     RTC_STAT_TP0F                               /*!< tamper 0 event flag */
+#define RTC_FLAG_TIMESTAMP_OVERFLOW        RTC_STAT_TSOVRF                             /*!< time-stamp overflow event flag */
+#define RTC_FLAG_TIMESTAMP                 RTC_STAT_TSF                                /*!< time-stamp event flag */
+#define RTC_FLAG_ALARM0                    RTC_STAT_ALRM0F                             /*!< alarm event flag */
+#define RTC_FLAG_INIT                      RTC_STAT_INITF                              /*!< init mode event flag */
+#define RTC_FLAG_RSYN                      RTC_STAT_RSYNF                              /*!< registers synchronized flag */
+#define RTC_FLAG_YCM                       RTC_STAT_YCM                                /*!< year parameter configured event flag */
+#define RTC_FLAG_SHIFT                     RTC_STAT_SOPF                               /*!< shift operation pending flag */
+#define RTC_FLAG_ALARM0_WRITTEN            RTC_STAT_ALRM0WF                            /*!< alarm written available flag */
+
+/* function declarations */
+/* reset most of the RTC registers */
+ErrStatus rtc_deinit(void);
+/* initialize RTC registers */
+ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct);
+/* enter RTC init mode */
+ErrStatus rtc_init_mode_enter(void);
+/* exit RTC init mode */
+void rtc_init_mode_exit(void);
+/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */
+ErrStatus rtc_register_sync_wait(void);
+
+/* get current time and date */
+void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct);
+/* get current subsecond value */
+uint32_t rtc_subsecond_get(void);
+
+/* configure RTC alarm */
+void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time);
+/* configure subsecond of RTC alarm */
+void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond);
+/* get RTC alarm */
+void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time);
+/* get RTC alarm subsecond */
+uint32_t rtc_alarm_subsecond_get(void);
+/* enable RTC alarm */
+void rtc_alarm_enable(void);
+/* disable RTC alarm */
+ErrStatus rtc_alarm_disable(void);
+
+/* enable RTC time-stamp */
+void rtc_timestamp_enable(uint32_t edge);
+/* disable RTC time-stamp */
+void rtc_timestamp_disable(void);
+/* get RTC timestamp time and date */
+void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp);
+/* get RTC time-stamp subsecond */
+uint32_t rtc_timestamp_subsecond_get(void);
+
+/* enable RTC tamper */
+void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper);
+/* disable RTC tamper */
+void rtc_tamper_disable(uint32_t source);
+
+/* enable specified RTC interrupt */
+void rtc_interrupt_enable(uint32_t interrupt);
+/* disble specified RTC interrupt */
+void rtc_interrupt_disable(uint32_t interrupt);
+/* check specified flag */
+FlagStatus rtc_flag_get(uint32_t flag);
+/* clear specified flag */
+void rtc_flag_clear(uint32_t flag);
+
+/* configure RTC alternate output source */
+void rtc_alter_output_config(uint32_t source, uint32_t mode);
+/* configure RTC calibration register */
+ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus);
+/* ajust the daylight saving time by adding or substracting one hour from the current time */
+void rtc_hour_adjust(uint32_t operation);
+/* ajust RTC second or subsecond value of current time */
+ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus);
+/* enable RTC bypass shadow registers function */
+void rtc_bypass_shadow_enable(void);
+/* disable RTC bypass shadow registers function */
+void rtc_bypass_shadow_disable(void);
+/* enable RTC reference clock detection function */
+ErrStatus rtc_refclock_detection_enable(void);
+/* disable RTC reference clock detection function */
+ErrStatus rtc_refclock_detection_disable(void);
+
+#endif /* GD32E230_RTC_H */

+ 424 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h

@@ -0,0 +1,424 @@
+/*!
+    \file  gd32e230_spi.h
+    \brief definitions for the SPI
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_SPI_H
+#define GD32E230_SPI_H
+
+#include "gd32e230.h"
+
+/* SPIx(x=0,1) definitions */
+#define SPI0                            (SPI_BASE + 0x0000F800U)
+#define SPI1                            SPI_BASE
+
+/* SPI registers definitions */
+#define SPI_CTL0(spix)                  REG32((spix) + 0x00U)                   /*!< SPI control register 0 */
+#define SPI_CTL1(spix)                  REG32((spix) + 0x04U)                   /*!< SPI control register 1*/
+#define SPI_STAT(spix)                  REG32((spix) + 0x08U)                   /*!< SPI status register */
+#define SPI_DATA(spix)                  REG32((spix) + 0x0CU)                   /*!< SPI data register */
+#define SPI_CRCPOLY(spix)               REG32((spix) + 0x10U)                   /*!< SPI CRC polynomial register */
+#define SPI_RCRC(spix)                  REG32((spix) + 0x14U)                   /*!< SPI receive CRC register */
+#define SPI_TCRC(spix)                  REG32((spix) + 0x18U)                   /*!< SPI transmit CRC register */
+#define SPI_I2SCTL(spix)                REG32((spix) + 0x1CU)                   /*!< SPI I2S control register */
+#define SPI_I2SPSC(spix)                REG32((spix) + 0x20U)                   /*!< SPI I2S clock prescaler register */
+#define SPI_QCTL(spix)                  REG32((spix) + 0x80U)                   /*!< SPI quad mode control register(only SPI1) */
+
+/* bits definitions */
+/* SPI_CTL0 */
+#define SPI_CTL0_CKPH                   BIT(0)                                  /*!< clock phase selection */
+#define SPI_CTL0_CKPL                   BIT(1)                                  /*!< clock polarity selection */
+#define SPI_CTL0_MSTMOD                 BIT(2)                                  /*!< master mode enable */
+#define SPI_CTL0_PSC                    BITS(3,5)                               /*!< master clock prescaler selection */
+#define SPI_CTL0_SPIEN                  BIT(6)                                  /*!< SPI enable*/
+#define SPI_CTL0_LF                     BIT(7)                                  /*!< LSB first mode */
+#define SPI_CTL0_SWNSS                  BIT(8)                                  /*!< NSS pin selection in NSS software mode */
+#define SPI_CTL0_SWNSSEN                BIT(9)                                  /*!< NSS software mode selection */
+#define SPI_CTL0_RO                     BIT(10)                                 /*!< receive only */
+/* only available in SPI0*/
+#define SPI_CTL0_FF16                   BIT(11)                                 /*!< data frame size */
+/* only available in SPI1*/
+#define SPI_CTL0_CRCL                   BIT(11)                                 /*!< CRC length */
+#define SPI_CTL0_CRCNT                  BIT(12)                                 /*!< CRC next transfer */
+#define SPI_CTL0_CRCEN                  BIT(13)                                 /*!< CRC calculation enable */
+#define SPI_CTL0_BDOEN                  BIT(14)                                 /*!< bidirectional transmit output enable*/
+#define SPI_CTL0_BDEN                   BIT(15)                                 /*!< bidirectional enable */
+
+/* SPI_CTL1 */
+#define SPI_CTL1_DMAREN                 BIT(0)                                  /*!< receive buffer dma enable */
+#define SPI_CTL1_DMATEN                 BIT(1)                                  /*!< transmit buffer dma enable */
+#define SPI_CTL1_NSSDRV                 BIT(2)                                  /*!< drive NSS output */
+#define SPI_CTL1_NSSP                   BIT(3)                                  /*!< SPI NSS pulse mode enable */
+#define SPI_CTL1_TMOD                   BIT(4)                                  /*!< SPI TI mode enable */
+#define SPI_CTL1_ERRIE                  BIT(5)                                  /*!< errors interrupt enable */
+#define SPI_CTL1_RBNEIE                 BIT(6)                                  /*!< receive buffer not empty interrupt enable */
+#define SPI_CTL1_TBEIE                  BIT(7)                                  /*!< transmit buffer empty interrupt enable */
+/* only available in SPI1 */
+#define SPI_CTL1_DZ                     BITS(8,11)                              /*!< data size */
+#define SPI_CTL1_BYTEN                  BIT(12)                                 /*!< byte access to FIFO enable */
+#define SPI_CTL1_RXDMA_ODD              BIT(13)                                 /*!< odd bytes in RX DMA channel */
+#define SPI_CTL1_TXDMA_ODD              BIT(14)                                 /*!< odd bytes in TX DMA channel */
+
+/* SPI_STAT */
+#define SPI_STAT_RBNE                   BIT(0)                                  /*!< receive buffer not empty */
+#define SPI_STAT_TBE                    BIT(1)                                  /*!< transmit buffer empty */
+#define SPI_STAT_I2SCH                  BIT(2)                                  /*!< I2S channel side */
+#define SPI_STAT_TXURERR                BIT(3)                                  /*!< I2S transmission underrun error bit */
+#define SPI_STAT_CRCERR                 BIT(4)                                  /*!< SPI CRC error bit */
+#define SPI_STAT_CONFERR                BIT(5)                                  /*!< SPI configuration error bit */
+#define SPI_STAT_RXORERR                BIT(6)                                  /*!< SPI reception overrun error bit */
+#define SPI_STAT_TRANS                  BIT(7)                                  /*!< transmitting on-going bit */
+#define SPI_STAT_FERR                   BIT(8)                                  /*!< format error bit */
+/* only available in SPI1 */
+#define SPI_STAT_RXLVL                  BITS(9,10)                              /*!< RXFIFO level */
+#define SPI_STAT_TXLVL                  BITS(11,12)                             /*!< TXFIFO level */
+
+/* SPI_DATA */
+#define SPI_DATA_DATA                   BITS(0,15)                              /*!< data transfer register */
+
+/* SPI_CRCPOLY */
+#define SPI_CRCPOLY_CRCPOLY             BITS(0,15)                              /*!< CRC polynomial value */
+
+/* SPI_RCRC */
+#define SPI_RCRC_RCRC                   BITS(0,15)                              /*!< RX CRC value */
+
+/* SPI_TCRC */
+#define SPI_TCRC_TCRC                   BITS(0,15)                              /*!< TX CRC value */
+
+/* SPI_I2SCTL */
+#define SPI_I2SCTL_CHLEN                BIT(0)                                  /*!< channel length */
+#define SPI_I2SCTL_DTLEN                BITS(1,2)                               /*!< data length */
+#define SPI_I2SCTL_CKPL                 BIT(3)                                  /*!< idle state clock polarity */
+#define SPI_I2SCTL_I2SSTD               BITS(4,5)                               /*!< I2S standard selection */
+#define SPI_I2SCTL_PCMSMOD              BIT(7)                                  /*!< PCM frame synchronization mode */
+#define SPI_I2SCTL_I2SOPMOD             BITS(8,9)                               /*!< I2S operation mode */
+#define SPI_I2SCTL_I2SEN                BIT(10)                                 /*!< I2S enable */
+#define SPI_I2SCTL_I2SSEL               BIT(11)                                 /*!< I2S mode selection */
+
+/* SPI_I2SPSC */
+#define SPI_I2SPSC_DIV                  BITS(0,7)                               /*!< dividing factor for the prescaler */
+#define SPI_I2SPSC_OF                   BIT(8)                                  /*!< odd factor for the prescaler */
+#define SPI_I2SPSC_MCKOEN               BIT(9)                                  /*!< I2S MCK output enable */
+
+/* SPIx_QCTL(x=1) */
+#define SPI_QCTL_QMOD                   BIT(0)                                  /*!< quad-SPI mode enable */
+#define SPI_QCTL_QRD                    BIT(1)                                  /*!< quad-SPI mode read select */
+#define SPI_QCTL_IO23_DRV               BIT(2)                                  /*!< drive SPI_IO2 and SPI_IO3 enable */
+
+/* constants definitions */
+/* SPIx and I2Sx parameter struct definitions */
+typedef struct
+{   
+    uint32_t device_mode;                                                       /*!< SPI master or slave */
+    uint32_t trans_mode;                                                        /*!< SPI transtype */
+    uint32_t frame_size;                                                        /*!< SPI frame size */
+    uint32_t nss;                                                               /*!< SPI NSS control by handware or software */
+    uint32_t endian;                                                            /*!< SPI big endian or little endian */
+    uint32_t clock_polarity_phase;                                              /*!< SPI clock phase and polarity */
+    uint32_t prescale;                                                          /*!< SPI prescale factor */
+}spi_parameter_struct;
+
+/* SPI mode definitions */
+#define SPI_MASTER                      (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS)      /*!< SPI as master */
+#define SPI_SLAVE                       ((uint32_t)0x00000000U)                 /*!< SPI as slave */
+
+/* SPI bidirectional transfer direction */
+#define SPI_BIDIRECTIONAL_TRANSMIT      SPI_CTL0_BDOEN                          /*!< SPI work in transmit-only mode */
+#define SPI_BIDIRECTIONAL_RECEIVE       (~SPI_CTL0_BDOEN)                       /*!< SPI work in receive-only mode */
+
+/* SPI transmit type */
+#define SPI_TRANSMODE_FULLDUPLEX        ((uint32_t)0x00000000U)                 /*!< SPI receive and send data at fullduplex communication */
+#define SPI_TRANSMODE_RECEIVEONLY       SPI_CTL0_RO                             /*!< SPI only receive data */
+#define SPI_TRANSMODE_BDRECEIVE         SPI_CTL0_BDEN                           /*!< bidirectional receive data */
+#define SPI_TRANSMODE_BDTRANSMIT        (SPI_CTL0_BDEN | SPI_CTL0_BDOEN)        /*!< bidirectional transmit data*/
+
+/* SPI NSS control mode */
+#define SPI_NSS_SOFT                    SPI_CTL0_SWNSSEN                        /*!< SPI NSS control by sofrware */
+#define SPI_NSS_HARD                    ((uint32_t)0x00000000U)                 /*!< SPI NSS control by hardware */
+
+/* SPI transmit way */
+#define SPI_ENDIAN_MSB                  ((uint32_t)0x00000000U)                 /*!< SPI transmit way is big endian: transmit MSB first */
+#define SPI_ENDIAN_LSB                  SPI_CTL0_LF                             /*!< SPI transmit way is little endian: transmit LSB first */
+
+/* SPI clock phase and polarity */
+#define SPI_CK_PL_LOW_PH_1EDGE          ((uint32_t)0x00000000U)                 /*!< SPI clock polarity is low level and phase is first edge */
+#define SPI_CK_PL_HIGH_PH_1EDGE         SPI_CTL0_CKPL                           /*!< SPI clock polarity is high level and phase is first edge */
+#define SPI_CK_PL_LOW_PH_2EDGE          SPI_CTL0_CKPH                           /*!< SPI clock polarity is low level and phase is second edge */
+#define SPI_CK_PL_HIGH_PH_2EDGE         (SPI_CTL0_CKPL | SPI_CTL0_CKPH)         /*!< SPI clock polarity is high level and phase is second edge */
+
+/* SPI clock prescale factor */
+#define CTL0_PSC(regval)                (BITS(3,5) & ((uint32_t)(regval) << 3))
+#define SPI_PSC_2                       CTL0_PSC(0)                             /*!< SPI clock prescale factor is 2 */
+#define SPI_PSC_4                       CTL0_PSC(1)                             /*!< SPI clock prescale factor is 4 */
+#define SPI_PSC_8                       CTL0_PSC(2)                             /*!< SPI clock prescale factor is 8 */
+#define SPI_PSC_16                      CTL0_PSC(3)                             /*!< SPI clock prescale factor is 16 */
+#define SPI_PSC_32                      CTL0_PSC(4)                             /*!< SPI clock prescale factor is 32 */
+#define SPI_PSC_64                      CTL0_PSC(5)                             /*!< SPI clock prescale factor is 64 */
+#define SPI_PSC_128                     CTL0_PSC(6)                             /*!< SPI clock prescale factor is 128 */
+#define SPI_PSC_256                     CTL0_PSC(7)                             /*!< SPI clock prescale factor is 256 */
+
+/* SPIx frame size */
+#define CTL1_FRAMESIZE(regval)           (BITS(8,11) & ((uint32_t)(regval) << 8))        
+#define SPI_FRAMESIZE_4BIT               CTL1_FRAMESIZE(3)                      /*!< SPI frame size is 4 bits */
+#define SPI_FRAMESIZE_5BIT               CTL1_FRAMESIZE(4)                      /*!< SPI frame size is 5 bits */
+#define SPI_FRAMESIZE_6BIT               CTL1_FRAMESIZE(5)                      /*!< SPI frame size is 6 bits */
+#define SPI_FRAMESIZE_7BIT               CTL1_FRAMESIZE(6)                      /*!< SPI frame size is 7 bits */
+#define SPI_FRAMESIZE_8BIT               CTL1_FRAMESIZE(7)                      /*!< SPI frame size is 8 bits */
+#define SPI_FRAMESIZE_9BIT               CTL1_FRAMESIZE(8)                      /*!< SPI frame size is 9 bits */
+#define SPI_FRAMESIZE_10BIT              CTL1_FRAMESIZE(9)                      /*!< SPI frame size is 10 bits */
+#define SPI_FRAMESIZE_11BIT              CTL1_FRAMESIZE(10)                     /*!< SPI frame size is 11 bits */
+#define SPI_FRAMESIZE_12BIT              CTL1_FRAMESIZE(11)                     /*!< SPI frame size is 12 bits */
+#define SPI_FRAMESIZE_13BIT              CTL1_FRAMESIZE(12)                     /*!< SPI frame size is 13 bits */
+#define SPI_FRAMESIZE_14BIT              CTL1_FRAMESIZE(13)                     /*!< SPI frame size is 14 bits */
+#define SPI_FRAMESIZE_15BIT              CTL1_FRAMESIZE(14)                     /*!< SPI frame size is 15 bits */
+#define SPI_FRAMESIZE_16BIT              CTL1_FRAMESIZE(15)                     /*!< SPI frame size is 16 bits */
+
+/* SPIx CRC length(x=1) */
+#define SPI_CRC_8BIT                    ((uint32_t)0x00000000U)                 /*!< SPI CRC length is 8 bits */
+#define SPI_CRC_16BIT                   SPI_CTL0_CRCL                           /*!< SPI CRC length is 16 bits */
+
+/* SPIx byte access enable(x=1) */
+#define SPI_HALFWORD_ACCESS             ((uint32_t)0x00000000U)                 /*!< SPI half-word access to FIFO */
+#define SPI_BYTE_ACCESS                 SPI_CTL1_BYTEN                          /*!< SPI byte access to FIFO */
+
+/* SPIx odd bytes in TX DMA channel(x=1) */
+#define SPI_TXDMA_EVEN                  ((uint32_t)0x00000000U)                 /*!< SPI number of byte in TX DMA channel is even */
+#define SPI_TXDMA_ODD                   SPI_CTL1_TXDMA_ODD                      /*!< SPI number of byte in TX DMA channel is odd */
+
+/* SPIx odd bytes in RX DMA channel(x=1) */
+#define SPI_RXDMA_EVEN                  ((uint32_t)0x00000000U)                 /*!< SPI number of byte in RX DMA channel is even */
+#define SPI_RXDMA_ODD                   SPI_CTL1_RXDMA_ODD                      /*!< SPI number of byte in RX DMA channel is odd */
+
+/* SPIx TXFIFO level(x=1) */
+#define CTL1_TXLVL(regval)              (BITS(11,12) & ((uint32_t)(regval) << 11))
+#define SPI_TXLVL_EMPTY                 CTL1_RXLVL(0)                           /*!< SPI TXFIFO is empty */
+#define SPI_TXLVL_QUARTER_FULL          CTL1_RXLVL(1)                           /*!< SPI TXFIFO is a quarter of full */
+#define SPI_TXLVL_HAlF_FULL             CTL1_RXLVL(2)                           /*!< SPI TXFIFO is a half of full */
+#define SPI_TXLVL_FULL                  CTL1_RXLVL(3)                           /*!< SPI TXFIFO is full */
+
+/* SPIx RXFIFO level(x=1) */
+#define CTL1_RXLVL(regval)              (BITS(9,10) & ((uint32_t)(regval) << 9))
+#define SPI_RXLVL_EMPTY                 CTL1_RXLVL(0)                           /*!< SPI RXFIFO is empty */
+#define SPI_RXLVL_QUARTER_FULL          CTL1_RXLVL(1)                           /*!< SPI RXFIFO is a quarter of full */
+#define SPI_RXLVL_HAlF_FULL             CTL1_RXLVL(2)                           /*!< SPI RXFIFO is a half of full */
+#define SPI_RXLVL_FULL                  CTL1_RXLVL(3)                           /*!< SPI RXFIFO is full */
+
+/* I2S audio sample rate */
+#define I2S_AUDIOSAMPLE_8K              ((uint32_t)8000U)                       /*!< I2S audio sample rate is 8KHz */
+#define I2S_AUDIOSAMPLE_11K             ((uint32_t)11025U)                      /*!< I2S audio sample rate is 11KHz */
+#define I2S_AUDIOSAMPLE_16K             ((uint32_t)16000U)                      /*!< I2S audio sample rate is 16KHz */
+#define I2S_AUDIOSAMPLE_22K             ((uint32_t)22050U)                      /*!< I2S audio sample rate is 22KHz */
+#define I2S_AUDIOSAMPLE_32K             ((uint32_t)32000U)                      /*!< I2S audio sample rate is 32KHz */
+#define I2S_AUDIOSAMPLE_44K             ((uint32_t)44100U)                      /*!< I2S audio sample rate is 44KHz */
+#define I2S_AUDIOSAMPLE_48K             ((uint32_t)48000U)                      /*!< I2S audio sample rate is 48KHz */
+#define I2S_AUDIOSAMPLE_96K             ((uint32_t)96000U)                      /*!< I2S audio sample rate is 96KHz */
+#define I2S_AUDIOSAMPLE_192K            ((uint32_t)192000U)                     /*!< I2S audio sample rate is 192KHz */
+
+/* I2S frame format */
+#define I2SCTL_DTLEN(regval)            (BITS(1,2) & ((uint32_t)(regval) << 1))
+#define I2S_FRAMEFORMAT_DT16B_CH16B     I2SCTL_DTLEN(0)                         /*!< I2S data length is 16 bit and channel length is 16 bit */
+#define I2S_FRAMEFORMAT_DT16B_CH32B     (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN)    /*!< I2S data length is 16 bit and channel length is 32 bit */
+#define I2S_FRAMEFORMAT_DT24B_CH32B     (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN)    /*!< I2S data length is 24 bit and channel length is 32 bit */
+#define I2S_FRAMEFORMAT_DT32B_CH32B     (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN)    /*!< I2S data length is 32 bit and channel length is 32 bit */
+
+/* I2S master clock output */
+#define I2S_MCKOUT_DISABLE              ((uint32_t)0x00000000U)                 /*!< I2S master clock output disable */
+#define I2S_MCKOUT_ENABLE               SPI_I2SPSC_MCKOEN                       /*!< I2S master clock output enable */
+
+/* I2S operation mode */
+#define I2SCTL_I2SOPMOD(regval)         (BITS(8,9) & ((uint32_t)(regval) << 8))
+#define I2S_MODE_SLAVETX                I2SCTL_I2SOPMOD(0)                      /*!< I2S slave transmit mode */
+#define I2S_MODE_SLAVERX                I2SCTL_I2SOPMOD(1)                      /*!< I2S slave receive mode */
+#define I2S_MODE_MASTERTX               I2SCTL_I2SOPMOD(2)                      /*!< I2S master transmit mode */
+#define I2S_MODE_MASTERRX               I2SCTL_I2SOPMOD(3)                      /*!< I2S master receive mode */
+
+/* I2S standard */
+#define I2SCTL_I2SSTD(regval)           (BITS(4,5) & ((uint32_t)(regval) << 4))
+#define I2S_STD_PHILLIPS                I2SCTL_I2SSTD(0)                        /*!< I2S phillips standard */
+#define I2S_STD_MSB                     I2SCTL_I2SSTD(1)                        /*!< I2S MSB standard */
+#define I2S_STD_LSB                     I2SCTL_I2SSTD(2)                        /*!< I2S LSB standard */
+#define I2S_STD_PCMSHORT                I2SCTL_I2SSTD(3)                        /*!< I2S PCM short standard */
+#define I2S_STD_PCMLONG                 (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */
+
+/* I2S clock polarity */
+#define I2S_CKPL_LOW                    ((uint32_t)0x00000000U)                 /*!< I2S clock polarity low level */
+#define I2S_CKPL_HIGH                   SPI_I2SCTL_CKPL                         /*!< I2S clock polarity high level */
+
+/* SPI DMA constants definitions */                                    
+#define SPI_DMA_TRANSMIT                ((uint8_t)0x00U)                        /*!< SPI transmit data use DMA */
+#define SPI_DMA_RECEIVE                 ((uint8_t)0x01U)                        /*!< SPI receive data use DMA */
+
+/* SPI CRC constants definitions */
+#define SPI_CRC_TX                      ((uint8_t)0x00U)                        /*!< SPI transmit CRC value */
+#define SPI_CRC_RX                      ((uint8_t)0x01U)                        /*!< SPI receive CRC value */
+
+/* SPI/I2S interrupt enable/disable constants definitions */
+#define SPI_I2S_INT_TBE                 ((uint8_t)0x00U)                        /*!< transmit buffer empty interrupt */
+#define SPI_I2S_INT_RBNE                ((uint8_t)0x01U)                        /*!< receive buffer not empty interrupt */
+#define SPI_I2S_INT_ERR                 ((uint8_t)0x02U)                        /*!< error interrupt */
+
+/* SPI/I2S interrupt flag constants definitions */
+#define SPI_I2S_INT_FLAG_TBE            ((uint8_t)0x00U)                        /*!< transmit buffer empty interrupt flag */
+#define SPI_I2S_INT_FLAG_RBNE           ((uint8_t)0x01U)                        /*!< receive buffer not empty interrupt flag */
+#define SPI_I2S_INT_FLAG_RXORERR        ((uint8_t)0x02U)                        /*!< overrun interrupt flag */
+#define SPI_INT_FLAG_CONFERR            ((uint8_t)0x03U)                        /*!< config error interrupt flag */
+#define SPI_INT_FLAG_CRCERR             ((uint8_t)0x04U)                        /*!< CRC error interrupt flag */
+#define I2S_INT_FLAG_TXURERR            ((uint8_t)0x05U)                        /*!< underrun error interrupt flag */
+#define SPI_I2S_INT_FLAG_FERR           ((uint8_t)0x06U)                        /*!< format error interrupt flag */
+
+/* SPI/I2S flag definitions */                                                  
+#define SPI_FLAG_RBNE                   SPI_STAT_RBNE                           /*!< receive buffer not empty flag */
+#define SPI_FLAG_TBE                    SPI_STAT_TBE                            /*!< transmit buffer empty flag */
+#define SPI_FLAG_CRCERR                 SPI_STAT_CRCERR                         /*!< CRC error flag */
+#define SPI_FLAG_CONFERR                SPI_STAT_CONFERR                        /*!< mode config error flag */
+#define SPI_FLAG_RXORERR                SPI_STAT_RXORERR                        /*!< receive overrun error flag */
+#define SPI_FLAG_TRANS                  SPI_STAT_TRANS                          /*!< transmit on-going flag */
+#define SPI_FLAG_FERR                   SPI_STAT_FERR                           /*!< format error interrupt flag */
+#define I2S_FLAG_RBNE                   SPI_STAT_RBNE                           /*!< receive buffer not empty flag */
+#define I2S_FLAG_TBE                    SPI_STAT_TBE                            /*!< transmit buffer empty flag */
+#define I2S_FLAG_CH                     SPI_STAT_I2SCH                          /*!< channel side flag */
+#define I2S_FLAG_TXURERR                SPI_STAT_TXURERR                        /*!< underrun error flag */
+#define I2S_FLAG_RXORERR                SPI_STAT_RXORERR                        /*!< overrun error flag */
+#define I2S_FLAG_TRANS                  SPI_STAT_TRANS                          /*!< transmit on-going flag */
+#define I2S_FLAG_FERR                   SPI_STAT_FERR                           /*!< format error interrupt flag */
+
+/* function declarations */
+/* SPI/I2S deinitialization and initialization functions */
+/* reset SPI and I2S */
+void spi_i2s_deinit(uint32_t spi_periph);
+/* initialize the parameters of SPI struct with the default values */
+void spi_struct_para_init(spi_parameter_struct* spi_struct);
+/* initialize SPI parameter */
+ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct);
+/* enable SPI */
+void spi_enable(uint32_t spi_periph);
+/* disable SPI */
+void spi_disable(uint32_t spi_periph);
+
+/* initialize I2S parameter */
+void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl);
+/* configure I2S prescaler */
+void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout);
+/* enable I2S */
+void i2s_enable(uint32_t spi_periph);
+/* disable I2S */
+void i2s_disable(uint32_t spi_periph);
+
+/* NSS functions */
+/* enable SPI NSS output */
+void spi_nss_output_enable(uint32_t spi_periph);
+/* disable SPI NSS output */
+void spi_nss_output_disable(uint32_t spi_periph);
+/* SPI NSS pin high level in software mode */
+void spi_nss_internal_high(uint32_t spi_periph);
+/* SPI NSS pin low level in software mode */
+void spi_nss_internal_low(uint32_t spi_periph);
+
+/* enable SPI DMA */
+void spi_dma_enable(uint32_t spi_periph, uint8_t dma);
+/* disable SPI DMA */
+void spi_dma_disable(uint32_t spi_periph, uint8_t dma);
+
+/* configure SPI/I2S data frame format */
+ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format);
+/* SPI transmit data */
+void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data);
+/* SPI receive data */
+uint16_t spi_i2s_data_receive(uint32_t spi_periph); 
+/* configure SPI bidirectional transfer direction */
+void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction);
+
+/* SPI CRC functions */
+/* set SPI CRC polynomial */
+void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly);
+/* get SPI CRC polynomial */
+uint16_t spi_crc_polynomial_get(uint32_t spi_periph);
+/* turn on SPI CRC function */
+void spi_crc_on(uint32_t spi_periph);
+/* turn off SPI CRC function */
+void spi_crc_off(uint32_t spi_periph);
+/* SPI next data is CRC value */
+void spi_crc_next(uint32_t spi_periph);
+/* get SPI CRC send value or receive value */
+uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc);
+
+/* SPI TI mode functions */
+/* enable SPI TI mode */
+void spi_ti_mode_enable(uint32_t spi_periph);
+/* disable SPI TI mode */
+void spi_ti_mode_disable(uint32_t spi_periph);
+
+/* SPI NSS pulse mode functions */
+/* enable SPI NSS pulse mode */
+void spi_nssp_mode_enable(uint32_t spi_periph);
+/* disable SPI NSS pulse mode */
+void spi_nssp_mode_disable(uint32_t spi_periph);
+
+/* quad wire SPI functions */
+/* enable quad wire SPI */
+void qspi_enable(uint32_t spi_periph);
+/* disable quad wire SPI */
+void qspi_disable(uint32_t spi_periph);
+/* enable quad wire SPI write */
+void qspi_write_enable(uint32_t spi_periph);
+/* enable quad wire SPI read */
+void qspi_read_enable(uint32_t spi_periph);
+/* enable quad wire SPI_IO2 and SPI_IO3 pin output */
+void qspi_io23_output_enable(uint32_t spi_periph);
+/* disable quad wire SPI_IO2 and SPI_IO3 pin output */
+void qspi_io23_output_disable(uint32_t spi_periph);
+
+/* flag and interrupt functions */
+/* enable SPI and I2S interrupt */
+void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt);
+/* disable SPI and I2S interrupt */
+void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt);
+/* get SPI and I2S interrupt status */
+FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt);
+/* get SPI and I2S flag status */
+FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag);
+/* clear SPI CRC error flag status */
+void spi_crc_error_clear(uint32_t spi_periph);
+
+/* only for SPI1 FIFO added */
+/* configure SPI access size to FIFO(8-bit or 16-bit) */
+void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size);
+/* configure SPI total number of data transmitting by DMA is odd or not */
+void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd);
+/* configure SPI total number of data receiving by DMA is odd or not */
+void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd);
+/* set CRC length */
+void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length);
+
+#endif /* GD32E230_SPI_H */

+ 187 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h

@@ -0,0 +1,187 @@
+/*!
+    \file  GD32e230_syscfg.h
+    \brief definitions for the SYSCFG
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_SYSCFG_H
+#define GD32E230_SYSCFG_H
+
+#include "gd32e230.h"
+
+/* SYSCFG definitions */
+#define SYSCFG                              SYSCFG_BASE
+
+/* registers definitions */
+#define SYSCFG_CFG0                         REG32(SYSCFG + 0x00U)               /*!< system configuration register 0 */
+#define SYSCFG_EXTISS0                      REG32(SYSCFG + 0x08U)               /*!< EXTI sources selection register 0 */
+#define SYSCFG_EXTISS1                      REG32(SYSCFG + 0x0CU)               /*!< EXTI sources selection register 1 */
+#define SYSCFG_EXTISS2                      REG32(SYSCFG + 0x10U)               /*!< EXTI sources selection register 2 */
+#define SYSCFG_EXTISS3                      REG32(SYSCFG + 0x14U)               /*!< EXTI sources selection register 3 */
+#define SYSCFG_CFG2                         REG32(SYSCFG + 0x18U)               /*!< system configuration register 2 */
+#define SYSCFG_CPU_IRQ_LAT                  REG32(SYSCFG + 0x100U)              /*!< IRQ Latency register */
+
+/* SYSCFG_CFG0 bits definitions */
+#define SYSCFG_CFG0_BOOT_MODE               BITS(0,1)                           /*!< SYSCFG memory remap config */
+#define SYSCFG_CFG0_PA11_PA12_RMP           BIT(4)                              /*!< PA11 and PA12 remapping bit for small packages (28 and 20 pins) */
+#define SYSCFG_CFG0_ADC_DMA_RMP             BIT(8)                              /*!< ADC DMA remap config */
+#define SYSCFG_CFG0_USART0_TX_DMA_RMP       BIT(9)                              /*!< USART0 Tx DMA remap config */
+#define SYSCFG_CFG0_USART0_RX_DMA_RMP       BIT(10)                             /*!< USART0 Rx DMA remap config */
+#define SYSCFG_CFG0_TIMER15_DMA_RMP         BIT(11)                             /*!< TIMER 15 DMA remap config */
+#define SYSCFG_CFG0_TIMER16_DMA_RMP         BIT(12)                             /*!< TIMER 16 DMA remap config */
+#define SYSCFG_CFG0_PB9_HCCE                BIT(19)                             /*!< PB9 pin high current capability enable */
+
+/* SYSCFG_EXTISS0 bits definitions */
+#define SYSCFG_EXTISS0_EXTI0_SS             BITS(0,3)                           /*!< EXTI 0 configuration */
+#define SYSCFG_EXTISS0_EXTI1_SS             BITS(4,7)                           /*!< EXTI 1 configuration */
+#define SYSCFG_EXTISS0_EXTI2_SS             BITS(8,11)                          /*!< EXTI 2 configuration */
+#define SYSCFG_EXTISS0_EXTI3_SS             BITS(12,15)                         /*!< EXTI 3 configuration */
+
+/* SYSCFG_EXTISS1 bits definitions */
+#define SYSCFG_EXTISS1_EXTI4_SS             BITS(0,3)                           /*!< EXTI 4 configuration */
+#define SYSCFG_EXTISS1_EXTI5_SS             BITS(4,7)                           /*!< EXTI 5 configuration */
+#define SYSCFG_EXTISS1_EXTI6_SS             BITS(8,11)                          /*!< EXTI 6 configuration */
+#define SYSCFG_EXTISS1_EXTI7_SS             BITS(12,15)                         /*!< EXTI 7 configuration */
+
+/* SYSCFG_EXTISS2 bits definitions */
+#define SYSCFG_EXTISS2_EXTI8_SS             BITS(0,3)                           /*!< EXTI 8 configuration */
+#define SYSCFG_EXTISS2_EXTI9_SS             BITS(4,7)                           /*!< EXTI 9 configuration */
+#define SYSCFG_EXTISS2_EXTI10_SS            BITS(8,11)                          /*!< EXTI 10 configuration */
+#define SYSCFG_EXTISS2_EXTI11_SS            BITS(12,15)                         /*!< EXTI 11 configuration */
+
+/* SYSCFG_EXTISS3 bits definitions */
+#define SYSCFG_EXTISS3_EXTI12_SS            BITS(0,3)                           /*!< EXTI 12 configuration */
+#define SYSCFG_EXTISS3_EXTI13_SS            BITS(4,7)                           /*!< EXTI 13 configuration */
+#define SYSCFG_EXTISS3_EXTI14_SS            BITS(8,11)                          /*!< EXTI 14 configuration */
+#define SYSCFG_EXTISS3_EXTI15_SS            BITS(12,15)                         /*!< EXTI 15 configuration */
+
+/* SYSCFG_CFG2 bits definitions */
+#define SYSCFG_CFG2_LOCKUP_LOCK             BIT(0)                              /*!< enable and lock the LOCKUP (Hardfault) output of Cortex-M23 with break input of TIMER0/14/15/16 */
+#define SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK  BIT(1)                              /*!< enable and lock the SRAM_PARITY error signal with break input of TIMER0/14/15/16 */
+#define SYSCFG_CFG2_LVD_LOCK                BIT(2)                              /*!< enable and lock the LVD connection with TIMER0 break input and also the LVD_EN and LVDSEL[2:0] bits of the power control interface */
+#define SYSCFG_CFG2_SRAM_PCEF               BIT(8)                              /*!< SRAM parity check error flag */
+
+/* SYSCFG_CPU_IRQ_LAT bits definitions */
+#define SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY      BITS(0,7)                           /*!< IRQ_LATENCY specifies the minimum number of cycles between an interrupt */
+
+/* constants definitions */
+/* DMA remap definitions */
+#define SYSCFG_PA11_REMAP_PA12              SYSCFG_CFG0_PA11_PA12_RMP           /*!< PA11 PA12 remap */
+#define SYSCFG_DMA_REMAP_ADC                SYSCFG_CFG0_ADC_DMA_RMP             /*!< ADC DMA remap */
+#define SYSCFG_DMA_REMAP_USART0TX           SYSCFG_CFG0_USART0_TX_DMA_RMP       /*!< USART0_TX DMA remap */
+#define SYSCFG_DMA_REMAP_USART0RX           SYSCFG_CFG0_USART0_RX_DMA_RMP       /*!< USART0_RX DMA remap */
+#define SYSCFG_DMA_REMAP_TIMER15            SYSCFG_CFG0_TIMER15_DMA_RMP         /*!< TIMER15 DMA remap */
+#define SYSCFG_DMA_REMAP_TIMER16            SYSCFG_CFG0_TIMER16_DMA_RMP         /*!< TIMER16 DMA remap */
+
+/* high current definitions */
+#define SYSCFG_HIGH_CURRENT_ENABLE          SYSCFG_CFG0_PB9_HCCE                /*!< high current enable */
+#define SYSCFG_HIGH_CURRENT_DISABLE         (~SYSCFG_CFG0_PB9_HCCE)             /*!< high current disable */
+
+/* EXTI source select definition */
+#define EXTISS0                             ((uint8_t)0x00U)                    /*!< EXTI source select register 0 */
+#define EXTISS1                             ((uint8_t)0x01U)                    /*!< EXTI source select register 1 */
+#define EXTISS2                             ((uint8_t)0x02U)                    /*!< EXTI source select register 2 */
+#define EXTISS3                             ((uint8_t)0x03U)                    /*!< EXTI source select register 3 */
+
+/* EXTI source select mask bits definition */
+#define EXTI_SS_MASK                        BITS(0,3)                           /*!< EXTI source select mask */
+
+/* EXTI source select jumping step definition */
+#define EXTI_SS_JSTEP                       ((uint8_t)(0x04U))                  /*!< EXTI source select jumping step */
+
+/* EXTI source select moving step definition */
+#define EXTI_SS_MSTEP(pin)                  (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP))   /*!< EXTI source select moving step */
+
+/* EXTI source port definitions */
+#define EXTI_SOURCE_GPIOA                   ((uint8_t)0x00U)                    /*!< EXTI GPIOA configuration */
+#define EXTI_SOURCE_GPIOB                   ((uint8_t)0x01U)                    /*!< EXTI GPIOB configuration */
+#define EXTI_SOURCE_GPIOC                   ((uint8_t)0x02U)                    /*!< EXTI GPIOC configuration */
+#define EXTI_SOURCE_GPIOF                   ((uint8_t)0x05U)                    /*!< EXTI GPIOF configuration */
+
+/* EXTI source pin definitions */
+#define EXTI_SOURCE_PIN0                    ((uint8_t)0x00U)                    /*!< EXTI GPIO pin0 configuration */
+#define EXTI_SOURCE_PIN1                    ((uint8_t)0x01U)                    /*!< EXTI GPIO pin1 configuration */
+#define EXTI_SOURCE_PIN2                    ((uint8_t)0x02U)                    /*!< EXTI GPIO pin2 configuration */
+#define EXTI_SOURCE_PIN3                    ((uint8_t)0x03U)                    /*!< EXTI GPIO pin3 configuration */
+#define EXTI_SOURCE_PIN4                    ((uint8_t)0x04U)                    /*!< EXTI GPIO pin4 configuration */
+#define EXTI_SOURCE_PIN5                    ((uint8_t)0x05U)                    /*!< EXTI GPIO pin5 configuration */
+#define EXTI_SOURCE_PIN6                    ((uint8_t)0x06U)                    /*!< EXTI GPIO pin6 configuration */
+#define EXTI_SOURCE_PIN7                    ((uint8_t)0x07U)                    /*!< EXTI GPIO pin7 configuration */
+#define EXTI_SOURCE_PIN8                    ((uint8_t)0x08U)                    /*!< EXTI GPIO pin8 configuration */
+#define EXTI_SOURCE_PIN9                    ((uint8_t)0x09U)                    /*!< EXTI GPIO pin9 configuration */
+#define EXTI_SOURCE_PIN10                   ((uint8_t)0x0AU)                    /*!< EXTI GPIO pin10 configuration */
+#define EXTI_SOURCE_PIN11                   ((uint8_t)0x0BU)                    /*!< EXTI GPIO pin11 configuration */
+#define EXTI_SOURCE_PIN12                   ((uint8_t)0x0CU)                    /*!< EXTI GPIO pin12 configuration */
+#define EXTI_SOURCE_PIN13                   ((uint8_t)0x0DU)                    /*!< EXTI GPIO pin13 configuration */
+#define EXTI_SOURCE_PIN14                   ((uint8_t)0x0EU)                    /*!< EXTI GPIO pin14 configuration */
+#define EXTI_SOURCE_PIN15                   ((uint8_t)0x0FU)                    /*!< EXTI GPIO pin15 configuration */
+
+/* lock definitions */
+#define SYSCFG_LOCK_LOCKUP                  SYSCFG_CFG2_LOCKUP_LOCK             /*!< LOCKUP output lock */
+#define SYSCFG_LOCK_SRAM_PARITY_ERROR       SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK  /*!< SRAM parity error lock */
+#define SYSCFG_LOCK_LVD                     SYSCFG_CFG2_LVD_LOCK                /*!< LVD lock */
+
+/* SRAM parity check error flag definitions */
+#define SYSCFG_SRAM_PCEF                    SYSCFG_CFG2_SRAM_PCEF               /*!< SRAM parity check error flag */
+
+/* SYSCFG_CPU_IRQ_LAT register IRQ_LATENCY value */
+#define IRQ_LATENCY(regval)                (BITS(0,7) & ((uint32_t)(regval) << 0U))     /*!< write value to IRQ_LATENCY bits field */
+
+/* function declarations */
+/* deinit syscfg module */
+void syscfg_deinit(void);
+
+/* enable the DMA channels remapping */
+void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap);
+/* disable the DMA channels remapping */
+void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap);
+
+/* enable PB9 high current capability */
+void syscfg_high_current_enable(void);
+/* disable PB9 high current capability */
+void syscfg_high_current_disable(void);
+
+/* configure the GPIO pin as EXTI Line */
+void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin);
+/* connect TIMER0/14/15/16 break input to the selected parameter */
+void syscfg_lock_config(uint32_t syscfg_lock);
+
+/* set the IRQ_LATENCY value */
+void irq_latency_set(uint8_t irq_latency);
+
+/* check if the specified flag in SYSCFG_CFG2 is set or not */
+FlagStatus syscfg_flag_get(uint32_t syscfg_flag);
+/* clear the flag in SYSCFG_CFG2 by writing 1 */
+void syscfg_flag_clear(uint32_t syscfg_flag);
+
+#endif /* GD32E230_SYSCFG_H */

+ 760 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h

@@ -0,0 +1,760 @@
+/*!
+    \file    gd32e230_timer.h
+    \brief   definitions for the TIMER
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_TIMER_H
+#define GD32E230_TIMER_H
+
+#include "gd32e230.h"
+
+/* TIMERx(x=0,1,2,5,13..16) definitions */
+#define TIMER0                           (TIMER_BASE + 0x00012C00U)
+#define TIMER2                           (TIMER_BASE + 0x00000400U)
+#define TIMER5                           (TIMER_BASE + 0x00001000U)
+#define TIMER13                          (TIMER_BASE + 0x00002000U)
+#define TIMER14                          (TIMER_BASE + 0x00014000U)
+#define TIMER15                          (TIMER_BASE + 0x00014400U)
+#define TIMER16                          (TIMER_BASE + 0x00014800U)
+
+/* registers definitions */
+#define TIMER_CTL0(timerx)               REG32((timerx) + 0x00U)           /*!< TIMER control register 0 */
+#define TIMER_CTL1(timerx)               REG32((timerx) + 0x04U)           /*!< TIMER control register 1 */
+#define TIMER_SMCFG(timerx)              REG32((timerx) + 0x08U)           /*!< TIMER slave mode configuration register */
+#define TIMER_DMAINTEN(timerx)           REG32((timerx) + 0x0CU)           /*!< TIMER DMA and interrupt enable register */
+#define TIMER_INTF(timerx)               REG32((timerx) + 0x10U)           /*!< TIMER interrupt flag register */
+#define TIMER_SWEVG(timerx)              REG32((timerx) + 0x14U)           /*!< TIMER software event generation register */
+#define TIMER_CHCTL0(timerx)             REG32((timerx) + 0x18U)           /*!< TIMER channel control register 0 */
+#define TIMER_CHCTL1(timerx)             REG32((timerx) + 0x1CU)           /*!< TIMER channel control register 1 */
+#define TIMER_CHCTL2(timerx)             REG32((timerx) + 0x20U)           /*!< TIMER channel control register 2 */
+#define TIMER_CNT(timerx)                REG32((timerx) + 0x24U)           /*!< TIMER counter register */
+#define TIMER_PSC(timerx)                REG32((timerx) + 0x28U)           /*!< TIMER prescaler register */
+#define TIMER_CAR(timerx)                REG32((timerx) + 0x2CU)           /*!< TIMER counter auto reload register */
+#define TIMER_CREP(timerx)               REG32((timerx) + 0x30U)           /*!< TIMER counter repetition register */
+#define TIMER_CH0CV(timerx)              REG32((timerx) + 0x34U)           /*!< TIMER channel 0 capture/compare value register */
+#define TIMER_CH1CV(timerx)              REG32((timerx) + 0x38U)           /*!< TIMER channel 1 capture/compare value register */
+#define TIMER_CH2CV(timerx)              REG32((timerx) + 0x3CU)           /*!< TIMER channel 2 capture/compare value register */
+#define TIMER_CH3CV(timerx)              REG32((timerx) + 0x40U)           /*!< TIMER channel 3 capture/compare value register */
+#define TIMER_CCHP(timerx)               REG32((timerx) + 0x44U)           /*!< TIMER complementary channel protection register */
+#define TIMER_DMACFG(timerx)             REG32((timerx) + 0x48U)           /*!< TIMER DMA configuration register */
+#define TIMER_DMATB(timerx)              REG32((timerx) + 0x4CU)           /*!< TIMER DMA transfer buffer register */
+#define TIMER_IRMP(timerx)               REG32((timerx) + 0x50U)           /*!< TIMER channel input remap register */
+#define TIMER_CFG(timerx)                REG32((timerx) + 0xFCU)           /*!< TIMER configuration register */
+
+/* bits definitions */
+/* TIMER_CTL0 */
+#define TIMER_CTL0_CEN                   BIT(0)              /*!< TIMER counter enable */
+#define TIMER_CTL0_UPDIS                 BIT(1)              /*!< update disable */
+#define TIMER_CTL0_UPS                   BIT(2)              /*!< update source */
+#define TIMER_CTL0_SPM                   BIT(3)              /*!< single pulse mode */
+#define TIMER_CTL0_DIR                   BIT(4)              /*!< timer counter direction */
+#define TIMER_CTL0_CAM                   BITS(5,6)           /*!< center-aligned mode selection */
+#define TIMER_CTL0_ARSE                  BIT(7)              /*!< auto-reload shadow enable */
+#define TIMER_CTL0_CKDIV                 BITS(8,9)           /*!< clock division */
+
+/* TIMER_CTL1 */
+#define TIMER_CTL1_CCSE                  BIT(0)              /*!< commutation control shadow enable */
+#define TIMER_CTL1_CCUC                  BIT(2)              /*!< commutation control shadow register update control */
+#define TIMER_CTL1_DMAS                  BIT(3)              /*!< DMA request source selection */
+#define TIMER_CTL1_MMC                   BITS(4,6)           /*!< master mode control */
+#define TIMER_CTL1_TI0S                  BIT(7)              /*!< channel 0 trigger input selection(hall mode selection) */
+#define TIMER_CTL1_ISO0                  BIT(8)              /*!< idle state of channel 0 output */
+#define TIMER_CTL1_ISO0N                 BIT(9)              /*!< idle state of channel 0 complementary output */
+#define TIMER_CTL1_ISO1                  BIT(10)             /*!< idle state of channel 1 output */
+#define TIMER_CTL1_ISO1N                 BIT(11)             /*!< idle state of channel 1 complementary output */
+#define TIMER_CTL1_ISO2                  BIT(12)             /*!< idle state of channel 2 output */
+#define TIMER_CTL1_ISO2N                 BIT(13)             /*!< idle state of channel 2 complementary output */
+#define TIMER_CTL1_ISO3                  BIT(14)             /*!< idle state of channel 3 output */
+
+/* TIMER_SMCFG */
+#define TIMER_SMCFG_SMC                  BITS(0,2)           /*!< slave mode control */
+#define TIMER_SMCFG_OCRC                 BIT(3)              /*!< OCPRE clear source selection */
+#define TIMER_SMCFG_TRGS                 BITS(4,6)           /*!< trigger selection */
+#define TIMER_SMCFG_MSM                  BIT(7)              /*!< master-slave mode */
+#define TIMER_SMCFG_ETFC                 BITS(8,11)          /*!< external trigger filter control */
+#define TIMER_SMCFG_ETPSC                BITS(12,13)         /*!< external trigger prescaler */
+#define TIMER_SMCFG_SMC1                 BIT(14)             /*!< part of SMC for enable external clock mode 1 */
+#define TIMER_SMCFG_ETP                  BIT(15)             /*!< external trigger polarity */
+ 
+/* TIMER_DMAINTEN */
+#define TIMER_DMAINTEN_UPIE              BIT(0)              /*!< update interrupt enable */
+#define TIMER_DMAINTEN_CH0IE             BIT(1)              /*!< channel 0 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CH1IE             BIT(2)              /*!< channel 1 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CH2IE             BIT(3)              /*!< channel 2 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CH3IE             BIT(4)              /*!< channel 3 capture/compare interrupt enable */
+#define TIMER_DMAINTEN_CMTIE             BIT(5)              /*!< commutation interrupt request enable */
+#define TIMER_DMAINTEN_TRGIE             BIT(6)              /*!< trigger interrupt enable */
+#define TIMER_DMAINTEN_BRKIE             BIT(7)              /*!< break interrupt enable */
+#define TIMER_DMAINTEN_UPDEN             BIT(8)              /*!< update DMA request enable */
+#define TIMER_DMAINTEN_CH0DEN            BIT(9)              /*!< channel 0 DMA request enable */
+#define TIMER_DMAINTEN_CH1DEN            BIT(10)             /*!< channel 1 DMA request enable */
+#define TIMER_DMAINTEN_CH2DEN            BIT(11)             /*!< channel 2 DMA request enable */
+#define TIMER_DMAINTEN_CH3DEN            BIT(12)             /*!< channel 3 DMA request enable */
+#define TIMER_DMAINTEN_CMTDEN            BIT(13)             /*!< commutation DMA request enable */
+#define TIMER_DMAINTEN_TRGDEN            BIT(14)             /*!< trigger DMA request enable */
+
+/* TIMER_INTF */
+#define TIMER_INTF_UPIF                  BIT(0)              /*!< update interrupt flag */
+#define TIMER_INTF_CH0IF                 BIT(1)              /*!< channel 0 capture/compare interrupt flag */
+#define TIMER_INTF_CH1IF                 BIT(2)              /*!< channel 1 capture/compare interrupt flag */
+#define TIMER_INTF_CH2IF                 BIT(3)              /*!< channel 2 capture/compare interrupt flag */
+#define TIMER_INTF_CH3IF                 BIT(4)              /*!< channel 3 capture/compare interrupt flag */
+#define TIMER_INTF_CMTIF                 BIT(5)              /*!< channel commutation interrupt flag */
+#define TIMER_INTF_TRGIF                 BIT(6)              /*!< trigger interrupt flag */
+#define TIMER_INTF_BRKIF                 BIT(7)              /*!< break interrupt flag */
+#define TIMER_INTF_CH0OF                 BIT(9)              /*!< channel 0 overcapture flag */
+#define TIMER_INTF_CH1OF                 BIT(10)             /*!< channel 1 overcapture flag */
+#define TIMER_INTF_CH2OF                 BIT(11)             /*!< channel 2 overcapture flag */
+#define TIMER_INTF_CH3OF                 BIT(12)             /*!< channel 3 overcapture flag */
+
+/* TIMER_SWEVG */
+#define TIMER_SWEVG_UPG                  BIT(0)              /*!< update event generate */
+#define TIMER_SWEVG_CH0G                 BIT(1)              /*!< channel 0 capture or compare event generation */
+#define TIMER_SWEVG_CH1G                 BIT(2)              /*!< channel 1 capture or compare event generation */
+#define TIMER_SWEVG_CH2G                 BIT(3)              /*!< channel 2 capture or compare event generation */
+#define TIMER_SWEVG_CH3G                 BIT(4)              /*!< channel 3 capture or compare event generation */
+#define TIMER_SWEVG_CMTG                 BIT(5)              /*!< channel commutation event generation */
+#define TIMER_SWEVG_TRGG                 BIT(6)              /*!< trigger event generation */
+#define TIMER_SWEVG_BRKG                 BIT(7)              /*!< break event generation */
+
+/* TIMER_CHCTL0 */
+/* output compare mode */
+#define TIMER_CHCTL0_CH0MS               BITS(0,1)           /*!< channel 0 mode selection */
+#define TIMER_CHCTL0_CH0COMFEN           BIT(2)              /*!< channel 0 output compare fast enable */
+#define TIMER_CHCTL0_CH0COMSEN           BIT(3)              /*!< channel 0 output compare shadow enable */
+#define TIMER_CHCTL0_CH0COMCTL           BITS(4,6)           /*!< channel 0 output compare mode */
+#define TIMER_CHCTL0_CH0COMCEN           BIT(7)              /*!< channel 0 output compare clear enable */
+#define TIMER_CHCTL0_CH1MS               BITS(8,9)           /*!< channel 1 mode selection */
+#define TIMER_CHCTL0_CH1COMFEN           BIT(10)             /*!< channel 1 output compare fast enable */
+#define TIMER_CHCTL0_CH1COMSEN           BIT(11)             /*!< channel 1 output compare shadow enable */
+#define TIMER_CHCTL0_CH1COMCTL           BITS(12,14)         /*!< channel 1 output compare mode */
+#define TIMER_CHCTL0_CH1COMCEN           BIT(15)             /*!< channel 1 output compare clear enable */
+/* input capture mode */
+#define TIMER_CHCTL0_CH0CAPPSC           BITS(2,3)           /*!< channel 0 input capture prescaler */
+#define TIMER_CHCTL0_CH0CAPFLT           BITS(4,7)           /*!< channel 0 input capture filter control */
+#define TIMER_CHCTL0_CH1CAPPSC           BITS(10,11)         /*!< channel 1 input capture prescaler */
+#define TIMER_CHCTL0_CH1CAPFLT           BITS(12,15)         /*!< channel 1 input capture filter control */
+
+/* TIMER_CHCTL1 */
+/* output compare mode */
+#define TIMER_CHCTL1_CH2MS               BITS(0,1)           /*!< channel 2 mode selection */
+#define TIMER_CHCTL1_CH2COMFEN           BIT(2)              /*!< channel 2 output compare fast enable */
+#define TIMER_CHCTL1_CH2COMSEN           BIT(3)              /*!< channel 2 output compare shadow enable */
+#define TIMER_CHCTL1_CH2COMCTL           BITS(4,6)           /*!< channel 2 output compare mode */
+#define TIMER_CHCTL1_CH2COMCEN           BIT(7)              /*!< channel 2 output compare clear enable */
+#define TIMER_CHCTL1_CH3MS               BITS(8,9)           /*!< channel 3 mode selection */
+#define TIMER_CHCTL1_CH3COMFEN           BIT(10)             /*!< channel 3 output compare fast enable */
+#define TIMER_CHCTL1_CH3COMSEN           BIT(11)             /*!< channel 3 output compare shadow enable */
+#define TIMER_CHCTL1_CH3COMCTL           BITS(12,14)         /*!< channel 3 output compare mode */
+#define TIMER_CHCTL1_CH3COMCEN           BIT(15)             /*!< channel 3 output compare clear enable */
+/* input capture mode */
+#define TIMER_CHCTL1_CH2CAPPSC           BITS(2,3)           /*!< channel 2 input capture prescaler */
+#define TIMER_CHCTL1_CH2CAPFLT           BITS(4,7)           /*!< channel 2 input capture filter control */
+#define TIMER_CHCTL1_CH3CAPPSC           BITS(10,11)         /*!< channel 3 input capture prescaler */
+#define TIMER_CHCTL1_CH3CAPFLT           BITS(12,15)         /*!< channel 3 input capture filter control */
+
+/* TIMER_CHCTL2 */
+#define TIMER_CHCTL2_CH0EN               BIT(0)              /*!< channel 0 capture/compare function enable */
+#define TIMER_CHCTL2_CH0P                BIT(1)              /*!< channel 0 capture/compare function polarity */
+#define TIMER_CHCTL2_CH0NEN              BIT(2)              /*!< channel 0 complementary output enable */
+#define TIMER_CHCTL2_CH0NP               BIT(3)              /*!< channel 0 complementary output polarity */
+#define TIMER_CHCTL2_CH1EN               BIT(4)              /*!< channel 1 capture/compare function enable  */
+#define TIMER_CHCTL2_CH1P                BIT(5)              /*!< channel 1 capture/compare function polarity */
+#define TIMER_CHCTL2_CH1NEN              BIT(6)              /*!< channel 1 complementary output enable */
+#define TIMER_CHCTL2_CH1NP               BIT(7)              /*!< channel 1 complementary output polarity */
+#define TIMER_CHCTL2_CH2EN               BIT(8)              /*!< channel 2 capture/compare function enable  */
+#define TIMER_CHCTL2_CH2P                BIT(9)              /*!< channel 2 capture/compare function polarity */
+#define TIMER_CHCTL2_CH2NEN              BIT(10)             /*!< channel 2 complementary output enable */
+#define TIMER_CHCTL2_CH2NP               BIT(11)             /*!< channel 2 complementary output polarity */
+#define TIMER_CHCTL2_CH3EN               BIT(12)             /*!< channel 3 capture/compare function enable  */
+#define TIMER_CHCTL2_CH3P                BIT(13)             /*!< channel 3 capture/compare function polarity */
+#define TIMER_CHCTL2_CH3NP               BIT(15)             /*!< channel 3 complementary output polarity */
+
+/* TIMER_CNT */
+#define TIMER_CNT_CNT16                  BITS(0,15)          /*!< 16 bit timer counter */
+
+/* TIMER_PSC */
+#define TIMER_PSC_PSC                    BITS(0,15)          /*!< prescaler value of the counter clock */
+
+/* TIMER_CAR */
+#define TIMER_CAR_CARL16                 BITS(0,15)          /*!< 16 bit counter auto reload value */
+
+/* TIMER_CREP */
+#define TIMER_CREP_CREP                  BITS(0,7)           /*!< counter repetition value */
+
+/* TIMER_CH0CV */
+#define TIMER_CH0CV_CH0VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 0 */
+
+/* TIMER_CH1CV */
+#define TIMER_CH1CV_CH1VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 1 */
+
+/* TIMER_CH2CV */
+#define TIMER_CH2CV_CH2VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 2 */
+
+/* TIMER_CH3CV */
+#define TIMER_CH3CV_CH3VAL16             BITS(0,15)          /*!< 16 bit capture/compare value of channel 3 */
+
+/* TIMER_CCHP */
+#define TIMER_CCHP_DTCFG                 BITS(0,7)           /*!< dead time configure */
+#define TIMER_CCHP_PROT                  BITS(8,9)           /*!< complementary register protect control */
+#define TIMER_CCHP_IOS                   BIT(10)             /*!< idle mode off-state configure */
+#define TIMER_CCHP_ROS                   BIT(11)             /*!< run mode off-state configure */
+#define TIMER_CCHP_BRKEN                 BIT(12)             /*!< break enable */
+#define TIMER_CCHP_BRKP                  BIT(13)             /*!< break polarity */
+#define TIMER_CCHP_OAEN                  BIT(14)             /*!< output automatic enable */
+#define TIMER_CCHP_POEN                  BIT(15)             /*!< primary output enable */
+
+/* TIMER_DMACFG */
+#define TIMER_DMACFG_DMATA               BITS(0,4)           /*!< DMA transfer access start address */
+#define TIMER_DMACFG_DMATC               BITS(8,12)          /*!< DMA transfer count */
+
+/* TIMER_DMATB */
+#define TIMER_DMATB_DMATB                BITS(0,15)          /*!< DMA transfer buffer address */
+
+/* TIMER_IRMP */
+#define TIMER13_IRMP_CI0_RMP             BITS(0,1)           /*!< TIMER13 channel 0 input remap */
+
+/* TIMER_CFG */
+#define TIMER_CFG_OUTSEL                 BIT(0)              /*!< the output value selection */
+#define TIMER_CFG_CHVSEL                 BIT(1)              /*!< write CHxVAL register selection */
+
+/* constants definitions */
+/* TIMER init parameter struct definitions*/
+typedef struct
+{ 
+    uint16_t prescaler;                         /*!< prescaler value */
+    uint16_t alignedmode;                       /*!< aligned mode */
+    uint16_t counterdirection;                  /*!< counter direction */
+    uint16_t clockdivision;                     /*!< clock division value */
+    uint32_t period;                            /*!< period value */
+    uint8_t  repetitioncounter;                 /*!< the counter repetition value */
+}timer_parameter_struct;
+
+/* break parameter struct definitions*/
+typedef struct
+{ 
+    uint16_t runoffstate;                       /*!< run mode off-state */
+    uint16_t ideloffstate;                      /*!< idle mode off-state */
+    uint16_t deadtime;                          /*!< dead time */
+    uint16_t breakpolarity;                     /*!< break polarity */
+    uint16_t outputautostate;                   /*!< output automatic enable */
+    uint16_t protectmode;                       /*!< complementary register protect control */
+    uint16_t breakstate;                        /*!< break enable */
+}timer_break_parameter_struct;
+
+/* channel output parameter struct definitions */
+typedef struct
+{ 
+    uint16_t outputstate;                       /*!< channel output state */
+    uint16_t outputnstate;                      /*!< channel complementary output state */
+    uint16_t ocpolarity;                        /*!< channel output polarity */
+    uint16_t ocnpolarity;                       /*!< channel complementary output polarity */
+    uint16_t ocidlestate;                       /*!< idle state of channel output */
+    uint16_t ocnidlestate;                      /*!< idle state of channel complementary output */
+}timer_oc_parameter_struct;
+
+/* channel input parameter struct definitions */
+typedef struct
+{ 
+    uint16_t icpolarity;                        /*!< channel input polarity */
+    uint16_t icselection;                       /*!< channel input mode selection */
+    uint16_t icprescaler;                       /*!< channel input capture prescaler */
+    uint16_t icfilter;                          /*!< channel input capture filter control */
+}timer_ic_parameter_struct;
+
+/* TIMER interrupt enable or disable */
+#define TIMER_INT_UP                        TIMER_DMAINTEN_UPIE                     /*!< update interrupt */
+#define TIMER_INT_CH0                       TIMER_DMAINTEN_CH0IE                    /*!< channel 0 interrupt */
+#define TIMER_INT_CH1                       TIMER_DMAINTEN_CH1IE                    /*!< channel 1 interrupt */
+#define TIMER_INT_CH2                       TIMER_DMAINTEN_CH2IE                    /*!< channel 2 interrupt */
+#define TIMER_INT_CH3                       TIMER_DMAINTEN_CH3IE                    /*!< channel 3 interrupt */
+#define TIMER_INT_CMT                       TIMER_DMAINTEN_CMTIE                    /*!< channel commutation interrupt flag */
+#define TIMER_INT_TRG                       TIMER_DMAINTEN_TRGIE                    /*!< trigger interrupt */
+#define TIMER_INT_BRK                       TIMER_DMAINTEN_BRKIE                    /*!< break interrupt */
+
+/* TIMER flag */
+#define TIMER_FLAG_UP                       TIMER_INTF_UPIF                         /*!< update flag */
+#define TIMER_FLAG_CH0                      TIMER_INTF_CH0IF                        /*!< channel 0 flag */
+#define TIMER_FLAG_CH1                      TIMER_INTF_CH1IF                        /*!< channel 1 flag */
+#define TIMER_FLAG_CH2                      TIMER_INTF_CH2IF                        /*!< channel 2 flag */
+#define TIMER_FLAG_CH3                      TIMER_INTF_CH3IF                        /*!< channel 3 flag */
+#define TIMER_FLAG_CMT                      TIMER_INTF_CMTIF                        /*!< channel commutation flag */
+#define TIMER_FLAG_TRG                      TIMER_INTF_TRGIF                        /*!< trigger flag */
+#define TIMER_FLAG_BRK                      TIMER_INTF_BRKIF                        /*!< break flag */
+#define TIMER_FLAG_CH0O                     TIMER_INTF_CH0OF                        /*!< channel 0 overcapture flag */
+#define TIMER_FLAG_CH1O                     TIMER_INTF_CH1OF                        /*!< channel 1 overcapture flag */
+#define TIMER_FLAG_CH2O                     TIMER_INTF_CH2OF                        /*!< channel 2 overcapture flag */
+#define TIMER_FLAG_CH3O                     TIMER_INTF_CH3OF                        /*!< channel 3 overcapture flag */
+
+/* TIMER interrupt flag */
+#define TIMER_INT_FLAG_UP                   TIMER_INTF_UPIF                         /*!< update interrupt flag */
+#define TIMER_INT_FLAG_CH0                  TIMER_INTF_CH0IF                        /*!< channel 0 interrupt flag */
+#define TIMER_INT_FLAG_CH1                  TIMER_INTF_CH1IF                        /*!< channel 1 interrupt flag */
+#define TIMER_INT_FLAG_CH2                  TIMER_INTF_CH2IF                        /*!< channel 2 interrupt flag */
+#define TIMER_INT_FLAG_CH3                  TIMER_INTF_CH3IF                        /*!< channel 3 interrupt flag */
+#define TIMER_INT_FLAG_CMT                  TIMER_INTF_CMTIF                        /*!< channel commutation interrupt flag */
+#define TIMER_INT_FLAG_TRG                  TIMER_INTF_TRGIF                        /*!< trigger interrupt flag */
+#define TIMER_INT_FLAG_BRK                  TIMER_INTF_BRKIF
+
+/* TIMER DMA source enable */
+#define TIMER_DMA_UPD                       ((uint16_t)TIMER_DMAINTEN_UPDEN)        /*!< update DMA enable */
+#define TIMER_DMA_CH0D                      ((uint16_t)TIMER_DMAINTEN_CH0DEN)       /*!< channel 0 DMA enable */
+#define TIMER_DMA_CH1D                      ((uint16_t)TIMER_DMAINTEN_CH1DEN)       /*!< channel 1 DMA enable */
+#define TIMER_DMA_CH2D                      ((uint16_t)TIMER_DMAINTEN_CH2DEN)       /*!< channel 2 DMA enable */
+#define TIMER_DMA_CH3D                      ((uint16_t)TIMER_DMAINTEN_CH3DEN)       /*!< channel 3 DMA enable */
+#define TIMER_DMA_CMTD                      ((uint16_t)TIMER_DMAINTEN_CMTDEN)       /*!< commutation DMA request enable */
+#define TIMER_DMA_TRGD                      ((uint16_t)TIMER_DMAINTEN_TRGDEN)       /*!< trigger DMA enable */
+
+/* channel DMA request source selection */ 
+#define TIMER_DMAREQUEST_UPDATEEVENT        TIMER_CTL1_DMAS                         /*!< DMA request of channel y is sent when update event occurs */
+#define TIMER_DMAREQUEST_CHANNELEVENT       ((uint32_t)0x00000000U)                 /*!< DMA request of channel y is sent when channel y event occurs */
+
+/* DMA access base address */
+#define DMACFG_DMATA(regval)                (BITS(0, 4) & ((uint32_t)(regval) << 0U))
+#define TIMER_DMACFG_DMATA_CTL0             DMACFG_DMATA(0)                         /*!< DMA transfer address is TIMER_CTL0 */
+#define TIMER_DMACFG_DMATA_CTL1             DMACFG_DMATA(1)                         /*!< DMA transfer address is TIMER_CTL1 */
+#define TIMER_DMACFG_DMATA_SMCFG            DMACFG_DMATA(2)                         /*!< DMA transfer address is TIMER_SMCFG */
+#define TIMER_DMACFG_DMATA_DMAINTEN         DMACFG_DMATA(3)                         /*!< DMA transfer address is TIMER_DMAINTEN */
+#define TIMER_DMACFG_DMATA_INTF             DMACFG_DMATA(4)                         /*!< DMA transfer address is TIMER_INTF */
+#define TIMER_DMACFG_DMATA_SWEVG            DMACFG_DMATA(5)                         /*!< DMA transfer address is TIMER_SWEVG */
+#define TIMER_DMACFG_DMATA_CHCTL0           DMACFG_DMATA(6)                         /*!< DMA transfer address is TIMER_CHCTL0 */
+#define TIMER_DMACFG_DMATA_CHCTL1           DMACFG_DMATA(7)                         /*!< DMA transfer address is TIMER_CHCTL1 */
+#define TIMER_DMACFG_DMATA_CHCTL2           DMACFG_DMATA(8)                         /*!< DMA transfer address is TIMER_CHCTL2 */
+#define TIMER_DMACFG_DMATA_CNT              DMACFG_DMATA(9)                         /*!< DMA transfer address is TIMER_CNT */
+#define TIMER_DMACFG_DMATA_PSC              DMACFG_DMATA(10)                        /*!< DMA transfer address is TIMER_PSC */
+#define TIMER_DMACFG_DMATA_CAR              DMACFG_DMATA(11)                        /*!< DMA transfer address is TIMER_CAR */
+#define TIMER_DMACFG_DMATA_CREP             DMACFG_DMATA(12)                        /*!< DMA transfer address is TIMER_CREP */
+#define TIMER_DMACFG_DMATA_CH0CV            DMACFG_DMATA(13)                        /*!< DMA transfer address is TIMER_CH0CV */
+#define TIMER_DMACFG_DMATA_CH1CV            DMACFG_DMATA(14)                        /*!< DMA transfer address is TIMER_CH1CV */
+#define TIMER_DMACFG_DMATA_CH2CV            DMACFG_DMATA(15)                        /*!< DMA transfer address is TIMER_CH2CV */
+#define TIMER_DMACFG_DMATA_CH3CV            DMACFG_DMATA(16)                        /*!< DMA transfer address is TIMER_CH3CV */
+#define TIMER_DMACFG_DMATA_CCHP             DMACFG_DMATA(17)                        /*!< DMA transfer address is TIMER_CCHP */
+#define TIMER_DMACFG_DMATA_DMACFG           DMACFG_DMATA(18)                        /*!< DMA transfer address is TIMER_DMACFG */
+
+/* DMA access burst length */
+#define DMACFG_DMATC(regval)                (BITS(8, 12) & ((uint32_t)(regval) << 8U))
+#define TIMER_DMACFG_DMATC_1TRANSFER        DMACFG_DMATC(0)                         /*!< DMA transfer 1 time */
+#define TIMER_DMACFG_DMATC_2TRANSFER        DMACFG_DMATC(1)                         /*!< DMA transfer 2 times */
+#define TIMER_DMACFG_DMATC_3TRANSFER        DMACFG_DMATC(2)                         /*!< DMA transfer 3 times */
+#define TIMER_DMACFG_DMATC_4TRANSFER        DMACFG_DMATC(3)                         /*!< DMA transfer 4 times */
+#define TIMER_DMACFG_DMATC_5TRANSFER        DMACFG_DMATC(4)                         /*!< DMA transfer 5 times */
+#define TIMER_DMACFG_DMATC_6TRANSFER        DMACFG_DMATC(5)                         /*!< DMA transfer 6 times */
+#define TIMER_DMACFG_DMATC_7TRANSFER        DMACFG_DMATC(6)                         /*!< DMA transfer 7 times */
+#define TIMER_DMACFG_DMATC_8TRANSFER        DMACFG_DMATC(7)                         /*!< DMA transfer 8 times */
+#define TIMER_DMACFG_DMATC_9TRANSFER        DMACFG_DMATC(8)                         /*!< DMA transfer 9 times */
+#define TIMER_DMACFG_DMATC_10TRANSFER       DMACFG_DMATC(9)                         /*!< DMA transfer 10 times */
+#define TIMER_DMACFG_DMATC_11TRANSFER       DMACFG_DMATC(10)                        /*!< DMA transfer 11 times */
+#define TIMER_DMACFG_DMATC_12TRANSFER       DMACFG_DMATC(11)                        /*!< DMA transfer 12 times */
+#define TIMER_DMACFG_DMATC_13TRANSFER       DMACFG_DMATC(12)                        /*!< DMA transfer 13 times */
+#define TIMER_DMACFG_DMATC_14TRANSFER       DMACFG_DMATC(13)                        /*!< DMA transfer 14 times */
+#define TIMER_DMACFG_DMATC_15TRANSFER       DMACFG_DMATC(14)                        /*!< DMA transfer 15 times */
+#define TIMER_DMACFG_DMATC_16TRANSFER       DMACFG_DMATC(15)                        /*!< DMA transfer 16 times */
+#define TIMER_DMACFG_DMATC_17TRANSFER       DMACFG_DMATC(16)                        /*!< DMA transfer 17 times */
+#define TIMER_DMACFG_DMATC_18TRANSFER       DMACFG_DMATC(17)                        /*!< DMA transfer 18 times */
+
+/* TIMER software event generation source */
+#define TIMER_EVENT_SRC_UPG                 ((uint16_t)0x0001U)                     /*!< update event generation */
+#define TIMER_EVENT_SRC_CH0G                ((uint16_t)0x0002U)                     /*!< channel 0 capture or compare event generation */
+#define TIMER_EVENT_SRC_CH1G                ((uint16_t)0x0004U)                     /*!< channel 1 capture or compare event generation */
+#define TIMER_EVENT_SRC_CH2G                ((uint16_t)0x0008U)                     /*!< channel 2 capture or compare event generation */
+#define TIMER_EVENT_SRC_CH3G                ((uint16_t)0x0010U)                     /*!< channel 3 capture or compare event generation */
+#define TIMER_EVENT_SRC_CMTG                ((uint16_t)0x0020U)                     /*!< channel commutation event generation */
+#define TIMER_EVENT_SRC_TRGG                ((uint16_t)0x0040U)                     /*!< trigger event generation */
+#define TIMER_EVENT_SRC_BRKG                ((uint16_t)0x0080U)                     /*!< break event generation */
+
+/* center-aligned mode selection */
+#define CTL0_CAM(regval)                    ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U)))
+#define TIMER_COUNTER_EDGE                  CTL0_CAM(0)                             /*!< edge-aligned mode */
+#define TIMER_COUNTER_CENTER_DOWN           CTL0_CAM(1)                             /*!< center-aligned and counting down assert mode */
+#define TIMER_COUNTER_CENTER_UP             CTL0_CAM(2)                             /*!< center-aligned and counting up assert mode */
+#define TIMER_COUNTER_CENTER_BOTH           CTL0_CAM(3)                             /*!< center-aligned and counting up/down assert mode */
+
+/* TIMER prescaler reload mode */
+#define TIMER_PSC_RELOAD_NOW                TIMER_SWEVG_UPG                         /*!< the prescaler is loaded right now */
+#define TIMER_PSC_RELOAD_UPDATE             ((uint32_t)0x00000000U)                 /*!< the prescaler is loaded at the next update event */
+
+/* count direction */
+#define TIMER_COUNTER_UP                    ((uint16_t)0x0000U)                     /*!< counter up direction */
+#define TIMER_COUNTER_DOWN                  ((uint16_t)TIMER_CTL0_DIR)              /*!< counter down direction */
+
+/* specify division ratio between TIMER clock and dead-time and sampling clock */
+#define CTL0_CKDIV(regval)                  ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U)))
+#define TIMER_CKDIV_DIV1                    CTL0_CKDIV(0)                           /*!< clock division value is 1, fDTS=fTIMER_CK */
+#define TIMER_CKDIV_DIV2                    CTL0_CKDIV(1)                           /*!< clock division value is 2, fDTS= fTIMER_CK/2 */
+#define TIMER_CKDIV_DIV4                    CTL0_CKDIV(2)                           /*!< clock division value is 4, fDTS= fTIMER_CK/4 */
+
+/* single pulse mode */
+#define TIMER_SP_MODE_SINGLE                TIMER_CTL0_SPM                          /*!< single pulse mode */
+#define TIMER_SP_MODE_REPETITIVE            ((uint32_t)0x00000000U)                 /*!< repetitive pulse mode */
+
+/* update source */
+#define TIMER_UPDATE_SRC_REGULAR            TIMER_CTL0_UPS                          /*!< update generate only by counter overflow/underflow */
+#define TIMER_UPDATE_SRC_GLOBAL            ((uint32_t)0x00000000U)                  /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */
+
+/* run mode off-state configure */
+#define TIMER_ROS_STATE_ENABLE              ((uint16_t)TIMER_CCHP_ROS)              /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */
+#define TIMER_ROS_STATE_DISABLE             ((uint16_t)0x0000U)                     /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are disabled */
+
+/* idle mode off-state configure */                                                 
+#define TIMER_IOS_STATE_ENABLE              ((uint16_t)TIMER_CCHP_IOS)              /*!< when POEN bit is reset, he channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */
+#define TIMER_IOS_STATE_DISABLE             ((uint16_t)0x0000U)                     /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are disabled */
+
+/* break input polarity */
+#define TIMER_BREAK_POLARITY_LOW            ((uint16_t)0x0000U)                     /*!< break input polarity is low */
+#define TIMER_BREAK_POLARITY_HIGH           ((uint16_t)TIMER_CCHP_BRKP)             /*!< break input polarity is high */
+
+/* output automatic enable */
+#define TIMER_OUTAUTO_ENABLE                ((uint16_t)TIMER_CCHP_OAEN)             /*!< output automatic enable */
+#define TIMER_OUTAUTO_DISABLE               ((uint16_t)0x0000U)                     /*!< output automatic disable */
+
+/* complementary register protect control */
+#define CCHP_PROT(regval)                   ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U)))
+#define TIMER_CCHP_PROT_OFF                 CCHP_PROT(0)                            /*!< protect disable */
+#define TIMER_CCHP_PROT_0                   CCHP_PROT(1)                            /*!< PROT mode 0 */
+#define TIMER_CCHP_PROT_1                   CCHP_PROT(2)                            /*!< PROT mode 1 */
+#define TIMER_CCHP_PROT_2                   CCHP_PROT(3)                            /*!< PROT mode 2 */
+
+/* break input enable */
+#define TIMER_BREAK_ENABLE                  ((uint16_t)TIMER_CCHP_BRKEN)            /*!< break input enable */
+#define TIMER_BREAK_DISABLE                 ((uint16_t)0x0000U)                     /*!< break input disable */
+
+/* TIMER channel n(n=0,1,2,3) */
+#define TIMER_CH_0                          ((uint16_t)0x0000U)                     /*!< TIMER channel 0(TIMERx(x=0,2,13..16)) */
+#define TIMER_CH_1                          ((uint16_t)0x0001U)                     /*!< TIMER channel 1(TIMERx(x=0,2,14)) */
+#define TIMER_CH_2                          ((uint16_t)0x0002U)                     /*!< TIMER channel 2(TIMERx(x=0,2)) */
+#define TIMER_CH_3                          ((uint16_t)0x0003U)                     /*!< TIMER channel 3(TIMERx(x=0,2)) */
+#define TIMER_CH_0_1                        ((uint16_t)0x0004U)                     /*!< TIMER channel 0 and 1 for function parameter */
+
+/* channel enable state*/
+#define TIMER_CCX_ENABLE                    ((uint32_t)0x00000001U)                 /*!< channel enable */
+#define TIMER_CCX_DISABLE                   ((uint32_t)0x00000000U)                 /*!< channel disable */
+
+/* channel complementary output enable state*/
+#define TIMER_CCXN_ENABLE                   ((uint16_t)0x0004U)                     /*!< channel complementary enable */
+#define TIMER_CCXN_DISABLE                  ((uint16_t)0x0000U)                     /*!< channel complementary disable */
+
+/* channel output polarity */
+#define TIMER_OC_POLARITY_HIGH              ((uint16_t)0x0000U)                     /*!< channel output polarity is high */
+#define TIMER_OC_POLARITY_LOW               ((uint16_t)0x0002U)                     /*!< channel output polarity is low */
+
+/* channel complementary output polarity */
+#define TIMER_OCN_POLARITY_HIGH             ((uint16_t)0x0000U)                     /*!< channel complementary output polarity is high */
+#define TIMER_OCN_POLARITY_LOW              ((uint16_t)0x0008U)                     /*!< channel complementary output polarity is low */
+
+/* idle state of channel output */ 
+#define TIMER_OC_IDLE_STATE_HIGH            ((uint16_t)0x0100)                      /*!< idle state of channel output is high */
+#define TIMER_OC_IDLE_STATE_LOW             ((uint16_t)0x0000)                      /*!< idle state of channel output is low */
+
+/* idle state of channel complementary output */ 
+#define TIMER_OCN_IDLE_STATE_HIGH           ((uint16_t)0x0200U)                     /*!< idle state of channel complementary output is high */
+#define TIMER_OCN_IDLE_STATE_LOW            ((uint16_t)0x0000U)                     /*!< idle state of channel complementary output is low */
+
+/* channel output compare mode */
+#define TIMER_OC_MODE_TIMING                ((uint16_t)0x0000U)                     /*!< timing mode */
+#define TIMER_OC_MODE_ACTIVE                ((uint16_t)0x0010U)                     /*!< active mode */
+#define TIMER_OC_MODE_INACTIVE              ((uint16_t)0x0020U)                     /*!< inactive mode */
+#define TIMER_OC_MODE_TOGGLE                ((uint16_t)0x0030U)                     /*!< toggle mode */
+#define TIMER_OC_MODE_LOW                   ((uint16_t)0x0040U)                     /*!< force low mode */
+#define TIMER_OC_MODE_HIGH                  ((uint16_t)0x0050U)                     /*!< force high mode */
+#define TIMER_OC_MODE_PWM0                  ((uint16_t)0x0060U)                     /*!< PWM0 mode */
+#define TIMER_OC_MODE_PWM1                  ((uint16_t)0x0070U)                     /*!< PWM1 mode*/
+
+/* channel output compare shadow enable */
+#define TIMER_OC_SHADOW_ENABLE              ((uint16_t)0x0008U)                     /*!< channel output shadow state enable */
+#define TIMER_OC_SHADOW_DISABLE             ((uint16_t)0x0000U)                     /*!< channel output shadow state disable */
+
+/* channel output compare fast enable */
+#define TIMER_OC_FAST_ENABLE                ((uint16_t)0x0004)                      /*!< channel output fast function enable */
+#define TIMER_OC_FAST_DISABLE               ((uint16_t)0x0000)                      /*!< channel output fast function disable */
+
+/* channel output compare clear enable */
+#define TIMER_OC_CLEAR_ENABLE               ((uint16_t)0x0080U)                     /*!< channel output clear function enable */
+#define TIMER_OC_CLEAR_DISABLE              ((uint16_t)0x0000U)                     /*!< channel output clear function disable */
+
+/* channel control shadow register update control */ 
+#define TIMER_UPDATECTL_CCU                 ((uint32_t)0x00000000U)                 /*!< the shadow registers are updated when CMTG bit is set */
+#define TIMER_UPDATECTL_CCUTRI              TIMER_CTL1_CCUC                         /*!< the shadow registers are updated when CMTG bit is set or an rising edge of TRGI occurs */
+
+/* channel input capture polarity */
+#define TIMER_IC_POLARITY_RISING            ((uint16_t)0x0000U)                     /*!< input capture rising edge */
+#define TIMER_IC_POLARITY_FALLING           ((uint16_t)0x0002U)                     /*!< input capture falling edge */
+#define TIMER_IC_POLARITY_BOTH_EDGE         ((uint16_t)0x000AU)                     /*!< input capture both edge */
+
+/* TIMER input capture selection */
+#define TIMER_IC_SELECTION_DIRECTTI         ((uint16_t)0x0001U)                     /*!< channel y is configured as input and icy is mapped on CIy */
+#define TIMER_IC_SELECTION_INDIRECTTI       ((uint16_t)0x0002U)                     /*!< channel y is configured as input and icy is mapped on opposite input */
+#define TIMER_IC_SELECTION_ITS              ((uint16_t)0x0003U)                     /*!< channel y is configured as input and icy is mapped on ITS */
+
+/* channel input capture prescaler */
+#define TIMER_IC_PSC_DIV1                   ((uint16_t)0x0000U)                     /*!< no prescaler */
+#define TIMER_IC_PSC_DIV2                   ((uint16_t)0x0004U)                     /*!< divided by 2 */
+#define TIMER_IC_PSC_DIV4                   ((uint16_t)0x0008U)                     /*!< divided by 4*/
+#define TIMER_IC_PSC_DIV8                   ((uint16_t)0x000CU)                     /*!< divided by 8 */
+
+/* trigger selection */
+#define SMCFG_TRGSEL(regval)                (BITS(4, 6) & ((uint32_t)(regval) << 4U))
+#define TIMER_SMCFG_TRGSEL_ITI0              SMCFG_TRGSEL(0)                        /*!< internal trigger 0 */
+#define TIMER_SMCFG_TRGSEL_ITI1              SMCFG_TRGSEL(1)                        /*!< internal trigger 1 */
+#define TIMER_SMCFG_TRGSEL_ITI2              SMCFG_TRGSEL(2)                        /*!< internal trigger 2 */
+#define TIMER_SMCFG_TRGSEL_ITI3              SMCFG_TRGSEL(3)                        /*!< internal trigger 3 */
+#define TIMER_SMCFG_TRGSEL_CI0F_ED           SMCFG_TRGSEL(4)                        /*!< TI0 Edge Detector */
+#define TIMER_SMCFG_TRGSEL_CI0FE0            SMCFG_TRGSEL(5)                        /*!< filtered TIMER input 0 */
+#define TIMER_SMCFG_TRGSEL_CI1FE1            SMCFG_TRGSEL(6)                        /*!< filtered TIMER input 1 */
+#define TIMER_SMCFG_TRGSEL_ETIFP             SMCFG_TRGSEL(7)                        /*!< external trigger */
+
+/* master mode control */
+#define CTL1_MMC(regval)                    (BITS(4, 6) & ((uint32_t)(regval) << 4U))
+#define TIMER_TRI_OUT_SRC_RESET             CTL1_MMC(0)                             /*!< the UPG bit as trigger output */
+#define TIMER_TRI_OUT_SRC_ENABLE            CTL1_MMC(1)                             /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */
+#define TIMER_TRI_OUT_SRC_UPDATE            CTL1_MMC(2)                             /*!< update event as trigger output */
+#define TIMER_TRI_OUT_SRC_CH0               CTL1_MMC(3)                             /*!< a capture or a compare match occurred in channal0 as trigger output TRGO */
+#define TIMER_TRI_OUT_SRC_O0CPRE            CTL1_MMC(4)                             /*!< O0CPRE as trigger output */
+#define TIMER_TRI_OUT_SRC_O1CPRE            CTL1_MMC(5)                             /*!< O1CPRE as trigger output */
+#define TIMER_TRI_OUT_SRC_O2CPRE            CTL1_MMC(6)                             /*!< O2CPRE as trigger output */
+#define TIMER_TRI_OUT_SRC_O3CPRE            CTL1_MMC(7)                             /*!< O3CPRE as trigger output */
+
+/* slave mode control */
+#define SMCFG_SMC(regval)                   (BITS(0, 2) & ((uint32_t)(regval) << 0U)) 
+#define TIMER_SLAVE_MODE_DISABLE            SMCFG_SMC(0)                            /*!< slave mode disable */
+#define TIMER_ENCODER_MODE0                 SMCFG_SMC(1)                            /*!< encoder mode 0 */
+#define TIMER_ENCODER_MODE1                 SMCFG_SMC(2)                            /*!< encoder mode 1 */
+#define TIMER_ENCODER_MODE2                 SMCFG_SMC(3)                            /*!< encoder mode 2 */
+#define TIMER_SLAVE_MODE_RESTART            SMCFG_SMC(4)                            /*!< restart mode */
+#define TIMER_SLAVE_MODE_PAUSE              SMCFG_SMC(5)                            /*!< pause mode */
+#define TIMER_SLAVE_MODE_EVENT              SMCFG_SMC(6)                            /*!< event mode */
+#define TIMER_SLAVE_MODE_EXTERNAL0          SMCFG_SMC(7)                            /*!< external clock mode 0 */
+
+/* OCPRE clear source selection */                                                  
+#define TIMER_OCPRE_CLEAR_SOURCE_CLR        ((uint8_t)0x00U)                        /*!< OCPRE_CLR_INT is connected to the OCPRE_CLR input */
+#define TIMER_OCPRE_CLEAR_SOURCE_ETIF       ((uint8_t)0x01U)                        /*!< OCPRE_CLR_INT is connected to ETIF */
+#define TIMER_OCPRE_CLEAR_SOURCE_DISABLE    ((uint8_t)0x02U)                        /*!< OCRC=0, and disable ETI */
+
+/* master slave mode selection */ 
+#define TIMER_MASTER_SLAVE_MODE_ENABLE      TIMER_SMCFG_MSM                         /*!< master slave mode enable */
+#define TIMER_MASTER_SLAVE_MODE_DISABLE     ((uint32_t)0x00000000U)                 /*!< master slave mode disable */
+
+/* external trigger prescaler */
+#define SMCFG_ETPSC(regval)                 (BITS(12, 13) & ((uint32_t)(regval) << 12U))
+#define TIMER_EXT_TRI_PSC_OFF               SMCFG_ETPSC(0)                          /*!< no divided */
+#define TIMER_EXT_TRI_PSC_DIV2              SMCFG_ETPSC(1)                          /*!< divided by 2 */
+#define TIMER_EXT_TRI_PSC_DIV4              SMCFG_ETPSC(2)                          /*!< divided by 4 */
+#define TIMER_EXT_TRI_PSC_DIV8              SMCFG_ETPSC(3)                          /*!< divided by 8 */
+
+/* external trigger polarity */
+#define TIMER_ETP_FALLING                   TIMER_SMCFG_ETP                         /*!< active low or falling edge active */
+#define TIMER_ETP_RISING                    ((uint32_t)0x00000000U)                 /*!< active high or rising edge active */
+
+/* channel 0 trigger input selection */ 
+#define TIMER_HALLINTERFACE_ENABLE          TIMER_CTL1_TI0S                         /*!< TIMER hall sensor mode enable */
+#define TIMER_HALLINTERFACE_DISABLE         ((uint32_t)0x00000000U)                 /*!< TIMER hall sensor mode disable */
+
+/* TIMERx(x=0,2,13,14,15,16) write cc register selection */
+#define TIMER_CHVSEL_ENABLE                 ((uint16_t)TIMER_CFG_OUTSEL)            /*!< write CHxVAL register selection enable */
+#define TIMER_CHVSEL_DISABLE                ((uint16_t)0x0000U)                     /*!< write CC register selection enable */
+
+/* the output value selection */
+#define TIMER_OUTSEL_ENABLE                 ((uint16_t)TIMER_CFG_OUTSEL)            /*!< output value selection enable */
+#define TIMER_OUTSEL_DISABLE                ((uint16_t)0x0000U)                     /*!< output value selection enable */
+
+/* timer13 channel 0 input remap */
+#define TIMER13_IRMP(regval)                (BITS(0, 1) & ((uint32_t)(regval) << 0U))       
+#define TIMER13_CI0_RMP_GPIO                TIMER13_IRMP(0)                         /*!< timer13 channel 0 input is connected to GPIO(TIMER13_CH0) */
+#define TIMER13_CI0_RMP_RTCCLK              TIMER13_IRMP(1)                         /*!< timer13 channel 0 input is connected to the RTCCLK */
+#define TIMER13_CI0_RMP_HXTAL_DIV32         TIMER13_IRMP(2)                         /*!< timer13 channel 0 input is connected to HXTAL/32 clock */
+#define TIMER13_CI0_RMP_CKOUTSEL            TIMER13_IRMP(3)                         /*!< timer13 channel 0 input is connected to CKOUTSEL */
+
+/* function declarations */
+/* TIMER timebase*/
+/* deinit a TIMER */
+void timer_deinit(uint32_t timer_periph);
+/* initialize TIMER init parameter struct */
+void timer_struct_para_init(timer_parameter_struct* initpara);
+/* initialize TIMER counter */
+void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara);
+/* enable a TIMER */
+void timer_enable(uint32_t timer_periph);
+/* disable a TIMER */
+void timer_disable(uint32_t timer_periph);
+/* enable the auto reload shadow function */
+void timer_auto_reload_shadow_enable(uint32_t timer_periph);
+/* disable the auto reload shadow function */
+void timer_auto_reload_shadow_disable(uint32_t timer_periph);
+/* enable the update event */
+void timer_update_event_enable(uint32_t timer_periph);
+/* disable the update event */
+void timer_update_event_disable(uint32_t timer_periph);
+/* set TIMER counter alignment mode */
+void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned);
+/* set TIMER counter up direction */
+void timer_counter_up_direction(uint32_t timer_periph);
+/* set TIMER counter down direction */
+void timer_counter_down_direction(uint32_t timer_periph);
+/* configure TIMER prescaler */
+void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload);
+/* configure TIMER repetition register value */
+void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition);
+/* configure TIMER autoreload register value */
+void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload);
+/* configure TIMER counter register value */
+void timer_counter_value_config(uint32_t timer_periph , uint16_t counter);
+/* read TIMER counter value */
+uint32_t timer_counter_read(uint32_t timer_periph);
+/* read TIMER prescaler value */
+uint16_t timer_prescaler_read(uint32_t timer_periph);
+/* configure TIMER single pulse mode */
+void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode);
+/* configure TIMER update source */
+void timer_update_source_config(uint32_t timer_periph, uint32_t update);
+/* OCPRE clear source selection */
+void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear);
+
+/* TIMER interrupt and flag*/
+/* enable the TIMER interrupt */
+void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt);
+/* disable the TIMER interrupt */
+void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt);
+/* get timer interrupt flag */
+FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt);
+/* clear TIMER interrupt flag */
+void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt);
+/* get TIMER flags */
+FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag);
+/* clear TIMER flags */
+void timer_flag_clear(uint32_t timer_periph, uint32_t flag);
+
+/* timer DMA and event*/
+/* enable the TIMER DMA */
+void timer_dma_enable(uint32_t timer_periph, uint16_t dma);
+/* disable the TIMER DMA */
+void timer_dma_disable(uint32_t timer_periph, uint16_t dma);
+/* channel DMA request source selection */
+void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request);
+/* configure the TIMER DMA transfer */
+void timer_dma_transfer_config(uint32_t timer_periph,uint32_t dma_baseaddr, uint32_t dma_lenth);
+/* software generate events */
+void timer_event_software_generate(uint32_t timer_periph, uint16_t event);
+
+/* TIMER channel complementary protection */
+/* initialize TIMER break parameter struct */
+void timer_break_struct_para_init(timer_break_parameter_struct* breakpara);
+/* configure TIMER break function */
+void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara);
+/* enable TIMER break function */
+void timer_break_enable(uint32_t timer_periph);
+/* disable TIMER break function */
+void timer_break_disable(uint32_t timer_periph);
+/* enable TIMER output automatic function */
+void timer_automatic_output_enable(uint32_t timer_periph);
+/* disable TIMER output automatic function */
+void timer_automatic_output_disable(uint32_t timer_periph);
+/* enable or disable TIMER primary output function */
+void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue);
+/* enable or disable channel capture/compare control shadow register */
+void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue);
+/* configure TIMER channel control shadow register update control */
+void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl);
+
+/* TIMER channel output */
+/* initialize TIMER channel output parameter struct */
+void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara);
+/* configure TIMER channel output function */
+void timer_channel_output_config(uint32_t timer_periph,uint16_t channel, timer_oc_parameter_struct* ocpara);
+/* configure TIMER channel output compare mode */
+void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel,uint16_t ocmode);
+/* configure TIMER channel output pulse value */
+void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse);
+/* configure TIMER channel output shadow function */
+void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow);
+/* configure TIMER channel output fast function */
+void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast);
+/* configure TIMER channel output clear function */
+void timer_channel_output_clear_config(uint32_t timer_periph,uint16_t channel,uint16_t occlear);
+/* configure TIMER channel output polarity */
+void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity);
+/* configure TIMER channel complementary output polarity */
+void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity);
+/* configure TIMER channel enable state */
+void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state);
+/* configure TIMER channel complementary output enable state */
+void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate);
+
+/* TIMER channel input */
+/* initialize TIMER channel input parameter struct */
+void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara);
+/* configure TIMER input capture parameter */
+void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpara);
+/* configure TIMER channel input capture prescaler value */
+void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler);
+/* read TIMER channel capture compare register value */
+uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel);
+/* configure TIMER input pwm capture function */
+void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm);
+/* configure TIMER hall sensor mode */
+void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode);
+
+/* TIMER master and slave */
+/* select TIMER input trigger source */
+void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger);
+/* select TIMER master mode output trigger source */
+void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger);
+/* select TIMER slave mode */
+void timer_slave_mode_select(uint32_t timer_periph,uint32_t slavemode);
+/* configure TIMER master slave mode */
+void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave);
+/* configure TIMER external trigger input */
+void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter);
+/* configure TIMER quadrature decoder mode */
+void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity);
+/* configure TIMER internal clock mode */
+void timer_internal_clock_config(uint32_t timer_periph);
+/* configure TIMER the internal trigger as external clock input */
+void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger);
+/* configure TIMER the external trigger as external clock input */
+void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity,uint32_t extfilter);
+/* configure TIMER the external clock mode 0 */
+void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter);
+/* configure TIMER the external clock mode 1 */
+void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter);
+/* disable TIMER the external clock mode 1 */
+void timer_external_clock_mode1_disable(uint32_t timer_periph);
+/* configure TIMER channel remap function */
+void timer_channel_remap_config(uint32_t timer_periph,uint32_t remap);
+
+/* TIMER configure */
+/* configure TIMER write CHxVAL register selection */
+void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel);
+/* configure TIMER output value selection */
+void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel);
+
+#endif /* GD32E230_TIMER_H */

+ 614 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h

@@ -0,0 +1,614 @@
+/*!
+    \file  gd32e230_usart.h
+    \brief definitions for the USART
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_USART_H
+#define GD32E230_USART_H
+
+#include "gd32e230.h"
+
+/* USARTx(x=0,1) definitions */
+#define USART0                        (USART_BASE + 0x0000F400U)
+#define USART1                        USART_BASE
+
+/* registers definitions */
+#define USART_CTL0(usartx)            REG32((usartx) + 0x00000000U)        /*!< USART control register 0 */
+#define USART_CTL1(usartx)            REG32((usartx) + 0x00000004U)        /*!< USART control register 1 */
+#define USART_CTL2(usartx)            REG32((usartx) + 0x00000008U)        /*!< USART control register 2 */
+#define USART_BAUD(usartx)            REG32((usartx) + 0x0000000CU)        /*!< USART baud rate register */
+#define USART_GP(usartx)              REG32((usartx) + 0x00000010U)        /*!< USART guard time and prescaler register */
+#define USART_RT(usartx)              REG32((usartx) + 0x00000014U)        /*!< USART receiver timeout register */
+#define USART_CMD(usartx)             REG32((usartx) + 0x00000018U)        /*!< USART command register */
+#define USART_STAT(usartx)            REG32((usartx) + 0x0000001CU)        /*!< USART status register */
+#define USART_INTC(usartx)            REG32((usartx) + 0x00000020U)        /*!< USART status clear register */
+#define USART_RDATA(usartx)           REG32((usartx) + 0x00000024U)        /*!< USART receive data register */
+#define USART_TDATA(usartx)           REG32((usartx) + 0x00000028U)        /*!< USART transmit data register */
+#define USART_CHC(usartx)             REG32((usartx) + 0x000000C0U)        /*!< USART coherence control register */
+#define USART_RFCS(usartx)            REG32((usartx) + 0x000000D0U)        /*!< USART receive FIFO control and status register */
+
+/* bits definitions */
+/* USARTx_CTL0 */
+#define USART_CTL0_UEN                BIT(0)                         /*!< USART enable */
+#define USART_CTL0_UESM               BIT(1)                         /*!< USART enable in deep-sleep mode */
+#define USART_CTL0_REN                BIT(2)                         /*!< receiver enable */
+#define USART_CTL0_TEN                BIT(3)                         /*!< transmitter enable */
+#define USART_CTL0_IDLEIE             BIT(4)                         /*!< idle line detected interrupt enable */
+#define USART_CTL0_RBNEIE             BIT(5)                         /*!< read data buffer not empty interrupt and overrun error interrupt enable */
+#define USART_CTL0_TCIE               BIT(6)                         /*!< transmission complete interrupt enable */
+#define USART_CTL0_TBEIE              BIT(7)                         /*!< transmitter register empty interrupt enable */
+#define USART_CTL0_PERRIE             BIT(8)                         /*!< parity error interrupt enable */
+#define USART_CTL0_PM                 BIT(9)                         /*!< parity mode */
+#define USART_CTL0_PCEN               BIT(10)                        /*!< parity control enable */
+#define USART_CTL0_WM                 BIT(11)                        /*!< wakeup method in mute mode */
+#define USART_CTL0_WL                 BIT(12)                        /*!< word length */
+#define USART_CTL0_MEN                BIT(13)                        /*!< mute mode enable */
+#define USART_CTL0_AMIE               BIT(14)                        /*!< address match interrupt enable */
+#define USART_CTL0_OVSMOD             BIT(15)                        /*!< oversample mode */
+#define USART_CTL0_DED                BITS(16,20)                    /*!< driver enable deassertion time */
+#define USART_CTL0_DEA                BITS(21,25)                    /*!< driver enable assertion time */
+#define USART_CTL0_RTIE               BIT(26)                        /*!< receiver timeout interrupt enable */
+#define USART_CTL0_EBIE               BIT(27)                        /*!< end of block interrupt enable */
+
+/* USARTx_CTL1 */
+#define USART_CTL1_ADDM               BIT(4)                         /*!< address detection mode */
+#define USART_CTL1_LBLEN              BIT(5)                         /*!< LIN break frame length */
+#define USART_CTL1_LBDIE              BIT(6)                         /*!< LIN break detection interrupt enable */
+#define USART_CTL1_CLEN               BIT(8)                         /*!< last bit clock pulse */
+#define USART_CTL1_CPH                BIT(9)                         /*!< clock phase */
+#define USART_CTL1_CPL                BIT(10)                        /*!< clock polarity */
+#define USART_CTL1_CKEN               BIT(11)                        /*!< ck pin enable */
+#define USART_CTL1_STB                BITS(12,13)                    /*!< stop bits length */
+#define USART_CTL1_LMEN               BIT(14)                        /*!< LIN mode enable */
+#define USART_CTL1_STRP               BIT(15)                        /*!< swap TX/RX pins */
+#define USART_CTL1_RINV               BIT(16)                        /*!< RX pin level inversion */
+#define USART_CTL1_TINV               BIT(17)                        /*!< TX pin level inversion */
+#define USART_CTL1_DINV               BIT(18)                        /*!< data bit level inversion */
+#define USART_CTL1_MSBF               BIT(19)                        /*!< most significant bit first */
+#define USART_CTL1_ABDEN              BIT(20)                        /*!< auto baud rate enable */
+#define USART_CTL1_ABDM               BITS(21,22)                    /*!< auto baud rate mode */
+#define USART_CTL1_RTEN               BIT(23)                        /*!< receiver timeout enable */
+#define USART_CTL1_ADDR               BITS(24,31)                    /*!< address of the USART terminal */
+
+/* USARTx_CTL2 */
+#define USART_CTL2_ERRIE              BIT(0)                         /*!< error interrupt enable in multibuffer communication */
+#define USART_CTL2_IREN               BIT(1)                         /*!< IrDA mode enable */
+#define USART_CTL2_IRLP               BIT(2)                         /*!< IrDA low-power */
+#define USART_CTL2_HDEN               BIT(3)                         /*!< half-duplex enable */
+#define USART_CTL2_NKEN               BIT(4)                         /*!< NACK enable in smartcard mode */
+#define USART_CTL2_SCEN               BIT(5)                         /*!< smartcard mode enable */
+#define USART_CTL2_DENR               BIT(6)                         /*!< DMA enable for reception */
+#define USART_CTL2_DENT               BIT(7)                         /*!< DMA enable for transmission */
+#define USART_CTL2_RTSEN              BIT(8)                         /*!< RTS enable */
+#define USART_CTL2_CTSEN              BIT(9)                         /*!< CTS enable */
+#define USART_CTL2_CTSIE              BIT(10)                        /*!< CTS interrupt enable */
+#define USART_CTL2_OSB                BIT(11)                        /*!< one sample bit mode */
+#define USART_CTL2_OVRD               BIT(12)                        /*!< overrun disable */
+#define USART_CTL2_DDRE               BIT(13)                        /*!< disable DMA on reception error */
+#define USART_CTL2_DEM                BIT(14)                        /*!< driver enable mode */
+#define USART_CTL2_DEP                BIT(15)                        /*!< driver enable polarity mode */
+#define USART_CTL2_SCRTNUM            BITS(17,19)                    /*!< smartcard auto-retry number */
+#define USART_CTL2_WUM                BITS(20,21)                    /*!< wakeup mode from deep-sleep mode */
+#define USART_CTL2_WUIE               BIT(22)                        /*!< wakeup from deep-sleep mode interrupt enable */
+
+/* USARTx_BAUD */
+#define USART_BAUD_FRADIV             BITS(0,3)                      /*!< fraction of baud-rate divider */
+#define USART_BAUD_INTDIV             BITS(4,15)                     /*!< integer of baud-rate divider */
+
+/* USARTx_GP */
+#define USART_GP_PSC                  BITS(0,7)                      /*!< prescaler value for dividing the system clock */
+#define USART_GP_GUAT                 BITS(8,15)                     /*!< guard time value in smartcard mode */
+
+/* USARTx_RT */
+#define USART_RT_RT                   BITS(0,23)                     /*!< receiver timeout threshold */
+#define USART_RT_BL                   BITS(24,31)                    /*!< block length */
+
+/* USARTx_CMD */
+#define USART_CMD_ABDCMD              BIT(0)                         /*!< auto baudrate detection command */
+#define USART_CMD_SBKCMD              BIT(1)                         /*!< send break command */
+#define USART_CMD_MMCMD               BIT(2)                         /*!< mute mode command */
+#define USART_CMD_RXFCMD              BIT(3)                         /*!< receive data flush command */
+#define USART_CMD_TXFCMD              BIT(4)                         /*!< transmit data flush request */
+
+/* USARTx_STAT */
+#define USART_STAT_PERR               BIT(0)                         /*!< parity error flag */
+#define USART_STAT_FERR               BIT(1)                         /*!< frame error flag */
+#define USART_STAT_NERR               BIT(2)                         /*!< noise error flag */
+#define USART_STAT_ORERR              BIT(3)                         /*!< overrun error */
+#define USART_STAT_IDLEF              BIT(4)                         /*!< idle line detected flag */
+#define USART_STAT_RBNE               BIT(5)                         /*!< read data buffer not empty */
+#define USART_STAT_TC                 BIT(6)                         /*!< transmission completed */
+#define USART_STAT_TBE                BIT(7)                         /*!< transmit data register empty */
+#define USART_STAT_LBDF               BIT(8)                         /*!< LIN break detected flag */
+#define USART_STAT_CTSF               BIT(9)                         /*!< CTS change flag */
+#define USART_STAT_CTS                BIT(10)                        /*!< CTS level */
+#define USART_STAT_RTF                BIT(11)                        /*!< receiver timeout flag */
+#define USART_STAT_EBF                BIT(12)                        /*!< end of block flag */
+#define USART_STAT_ABDE               BIT(14)                        /*!< auto baudrate detection error */
+#define USART_STAT_ABDF               BIT(15)                        /*!< auto baudrate detection flag */
+#define USART_STAT_BSY                BIT(16)                        /*!< busy flag */
+#define USART_STAT_AMF                BIT(17)                        /*!< address match flag */
+#define USART_STAT_SBF                BIT(18)                        /*!< send break flag */
+#define USART_STAT_RWU                BIT(19)                        /*!< receiver wakeup from mute mode */
+#define USART_STAT_WUF                BIT(20)                        /*!< wakeup from deep-sleep mode flag */
+#define USART_STAT_TEA                BIT(21)                        /*!< transmit enable acknowledge flag */
+#define USART_STAT_REA                BIT(22)                        /*!< receive enable acknowledge flag */
+
+/* USARTx_INTC */
+#define USART_INTC_PEC                BIT(0)                         /*!< parity error clear */
+#define USART_INTC_FEC                BIT(1)                         /*!< frame error flag clear */
+#define USART_INTC_NEC                BIT(2)                         /*!< noise detected clear */
+#define USART_INTC_OREC               BIT(3)                         /*!< overrun error clear */
+#define USART_INTC_IDLEC              BIT(4)                         /*!< idle line detected clear */
+#define USART_INTC_TCC                BIT(6)                         /*!< transmission complete clear */
+#define USART_INTC_LBDC               BIT(8)                         /*!< LIN break detected clear */
+#define USART_INTC_CTSC               BIT(9)                         /*!< CTS change clear */
+#define USART_INTC_RTC                BIT(11)                        /*!< receiver timeout clear */
+#define USART_INTC_EBC                BIT(12)                        /*!< end of timeout clear */
+#define USART_INTC_AMC                BIT(17)                        /*!< address match clear */
+#define USART_INTC_WUC                BIT(20)                        /*!< wakeup from deep-sleep mode clear */
+
+/* USARTx_RDATA */
+#define USART_RDATA_RDATA             BITS(0,8)                      /*!< receive data value */
+
+/* USARTx_TDATA */
+#define USART_TDATA_TDATA             BITS(0,8)                      /*!< transmit data value */
+
+/* USARTx_CHC */
+#define USART_CHC_HCM                 BIT(0)                         /*!< hardware flow control coherence mode */
+#define USART_CHC_EPERR               BIT(8)                         /*!< early parity error flag */
+
+/* USARTx_RFCS */
+#define USART_RFCS_ELNACK             BIT(0)                         /*!< early NACK */
+#define USART_RFCS_RFEN               BIT(8)                         /*!< receive FIFO enable */
+#define USART_RFCS_RFFIE              BIT(9)                         /*!< receive FIFO full interrupt enable */
+#define USART_RFCS_RFE                BIT(10)                        /*!< receive FIFO empty flag */
+#define USART_RFCS_RFF                BIT(11)                        /*!< receive FIFO full flag */
+#define USART_RFCS_RFCNT              BITS(12,14)                    /*!< receive FIFO counter number */
+#define USART_RFCS_RFFINT             BIT(15)                        /*!< receive FIFO full interrupt flag */
+
+/* constants definitions */
+
+/* define the USART bit position and its register index offset */
+#define USART_REGIDX_BIT(regidx, bitpos)    (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
+#define USART_REG_VAL(usartx, offset)       (REG32((usartx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6)))
+#define USART_BIT_POS(val)                  ((uint32_t)(val) & 0x0000001FU)
+#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2)   (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\
+                                                              | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)))
+#define USART_REG_VAL2(usartx, offset)       (REG32((usartx) + ((uint32_t)(offset) >> 22)))
+#define USART_BIT_POS2(val)                  (((uint32_t)(val) & 0x001F0000U) >> 16)
+
+/* register offset */
+#define USART_CTL0_REG_OFFSET              0x00000000U                           /*!< CTL0 register offset */
+#define USART_CTL1_REG_OFFSET              0x00000004U                           /*!< CTL1 register offset */
+#define USART_CTL2_REG_OFFSET              0x00000008U                           /*!< CTL2 register offset */
+#define USART_STAT_REG_OFFSET              0x0000001CU                           /*!< STAT register offset */
+#define USART_CHC_REG_OFFSET               0x000000C0U                           /*!< CHC register offset */
+#define USART_RFCS_REG_OFFSET              0x000000D0U                           /*!< RFCS register offset */
+
+/* USART flags */
+typedef enum{
+    /* flags in STAT register */
+    USART_FLAG_REA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 22U),         /*!< receive enable acknowledge flag */
+    USART_FLAG_TEA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 21U),         /*!< transmit enable acknowledge flag */
+    USART_FLAG_WU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 20U),          /*!< wakeup from Deep-sleep mode flag */
+    USART_FLAG_RWU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 19U),         /*!< receiver wakeup from mute mode */
+    USART_FLAG_SB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 18U),          /*!< send break flag */
+    USART_FLAG_AM = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 17U),          /*!< ADDR match flag */
+    USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 16U),         /*!< busy flag */
+    USART_FLAG_ABD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 15U),         /*!< auto baudrate detection flag */
+    USART_FLAG_ABDE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 14U),        /*!< auto baudrate detection error */
+    USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U),          /*!< end of block flag */
+    USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U),          /*!< receiver timeout flag */
+    USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U),         /*!< CTS level */
+    USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U),         /*!< CTS change flag */
+    USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U),          /*!< LIN break detected flag */
+    USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U),          /*!< transmit data buffer empty */
+    USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U),           /*!< transmission complete */
+    USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U),         /*!< read data buffer not empty */
+    USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U),         /*!< IDLE line detected flag */
+    USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U),        /*!< overrun error */
+    USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U),         /*!< noise error flag */
+    USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U),         /*!< frame error flag */
+    USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U),         /*!< parity error flag */
+    /* flags in CHC register */
+    USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U),         /*!< early parity error flag */
+    /* flags in RFCS register */
+    USART_FLAG_RFFINT = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 15U),      /*!< receive FIFO full interrupt flag */
+    USART_FLAG_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 11U),         /*!< receive FIFO full flag */
+    USART_FLAG_RFE = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 10U),         /*!< receive FIFO empty flag */
+}usart_flag_enum;
+
+/* USART interrupt flags */
+typedef enum
+{
+    /* interrupt flags in CTL0 register */
+    USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 27U, USART_STAT_REG_OFFSET, 12U),       /*!< end of block interrupt and flag */
+    USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 26U, USART_STAT_REG_OFFSET, 11U),       /*!< receiver timeout interrupt and flag */
+    USART_INT_FLAG_AM = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 14U, USART_STAT_REG_OFFSET, 17U),       /*!< address match interrupt and flag */
+    USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U),       /*!< parity error interrupt and flag */
+    USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U),        /*!< transmitter buffer empty interrupt and flag */
+    USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U),         /*!< transmission complete interrupt and flag */
+    USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U),       /*!< read data buffer not empty interrupt and flag */
+    USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */
+    USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U),       /*!< IDLE line detected interrupt and flag */
+    /* interrupt flags in CTL1 register */
+    USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 8U),        /*!< LIN break detected interrupt and flag */
+    /* interrupt flags in CTL2 register */
+    USART_INT_FLAG_WU = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 22U, USART_STAT_REG_OFFSET, 20U),       /*!< wakeup from deep-sleep mode interrupt and flag */
+    USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U),       /*!< CTS interrupt and flag */
+    USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U),   /*!< error interrupt and noise error flag */
+    USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U),  /*!< error interrupt and overrun error */
+    USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U),   /*!< error interrupt and frame error flag */
+    /* interrupt flags in RFCS register */
+    USART_INT_FLAG_RFF = USART_REGIDX_BIT2(USART_RFCS_REG_OFFSET, 9U, USART_RFCS_REG_OFFSET, 15U),       /*!< receive FIFO full interrupt and flag */
+}usart_interrupt_flag_enum;
+
+/* USART interrupt enable or disable */
+typedef enum
+{
+    /* interrupt in CTL0 register */
+    USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U),         /*!< end of block interrupt */
+    USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U),         /*!< receiver timeout interrupt */
+    USART_INT_AM = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U),         /*!< address match interrupt */
+    USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U),        /*!< parity error interrupt */
+    USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U),         /*!< transmitter buffer empty interrupt */
+    USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U),          /*!< transmission complete interrupt */
+    USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U),        /*!< read data buffer not empty interrupt and overrun error interrupt */
+    USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U),        /*!< IDLE line detected interrupt */
+    /* interrupt in CTL1 register */
+    USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U),         /*!< LIN break detected interrupt */
+    /* interrupt in CTL2 register */
+    USART_INT_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U),         /*!< wakeup from deep-sleep mode interrupt */
+    USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U),        /*!< CTS interrupt */
+    USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U),         /*!< error interrupt */
+    /* interrupt in RFCS register */
+    USART_INT_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 9U),         /*!< receive FIFO full interrupt */
+}usart_interrupt_enum;
+
+/* USART invert configure */
+typedef enum {
+    /* data bit level inversion */
+    USART_DINV_ENABLE,                                               /*!< data bit level inversion */
+    USART_DINV_DISABLE,                                              /*!< data bit level not inversion */
+    /* TX pin level inversion */
+    USART_TXPIN_ENABLE,                                              /*!< TX pin level inversion */               
+    USART_TXPIN_DISABLE,                                             /*!< TX pin level not inversion */
+    /* RX pin level inversion */
+    USART_RXPIN_ENABLE,                                              /*!< RX pin level inversion */
+    USART_RXPIN_DISABLE,                                             /*!< RX pin level not inversion */
+    /* swap TX/RX pins */
+    USART_SWAP_ENABLE,                                               /*!< swap TX/RX pins */                
+    USART_SWAP_DISABLE,                                              /*!< not swap TX/RX pins */
+}usart_invert_enum;
+
+/* USART receiver configure */
+#define CTL0_REN(regval)              (BIT(2) & ((uint32_t)(regval) << 2))
+#define USART_RECEIVE_ENABLE          CTL0_REN(1)                    /*!< enable receiver */
+#define USART_RECEIVE_DISABLE         CTL0_REN(0)                    /*!< disable receiver */
+
+/* USART transmitter configure */
+#define CTL0_TEN(regval)              (BIT(3) & ((uint32_t)(regval) << 3))
+#define USART_TRANSMIT_ENABLE         CTL0_TEN(1)                    /*!< enable transmitter */
+#define USART_TRANSMIT_DISABLE        CTL0_TEN(0)                    /*!< disable transmitter */
+
+/* USART parity bits definitions */
+#define CTL0_PM(regval)               (BITS(9,10) & ((uint32_t)(regval) << 9))
+#define USART_PM_NONE                 CTL0_PM(0)                     /*!< no parity */
+#define USART_PM_EVEN                 CTL0_PM(2)                     /*!< even parity */
+#define USART_PM_ODD                  CTL0_PM(3)                     /*!< odd parity */
+
+/* USART wakeup method in mute mode */
+#define CTL0_WM(regval)               (BIT(11) & ((uint32_t)(regval) << 11))
+#define USART_WM_IDLE                 CTL0_WM(0)                     /*!< idle line */
+#define USART_WM_ADDR                 CTL0_WM(1)                     /*!< address match */
+
+/* USART word length definitions */
+#define CTL0_WL(regval)               (BIT(12) & ((uint32_t)(regval) << 12))
+#define USART_WL_8BIT                 CTL0_WL(0)                     /*!< 8 bits */
+#define USART_WL_9BIT                 CTL0_WL(1)                     /*!< 9 bits */
+
+/* USART oversample mode */
+#define CTL0_OVSMOD(regval)           (BIT(15) & ((uint32_t)(regval) << 15))
+#define USART_OVSMOD_8                CTL0_OVSMOD(1)                 /*!< oversampling by 8 */
+#define USART_OVSMOD_16               CTL0_OVSMOD(0)                 /*!< oversampling by 16 */
+
+/* USART address detection mode */
+#define CTL1_ADDM(regval)             (BIT(4) & ((uint32_t)(regval) << 4))
+#define USART_ADDM_4BIT               CTL1_ADDM(0)                   /*!< 4-bit address detection */
+#define USART_ADDM_FULLBIT            CTL1_ADDM(1)                   /*!< full-bit address detection */
+
+/* USART LIN break frame length */
+#define CTL1_LBLEN(regval)            (BIT(5) & ((uint32_t)(regval) << 5))
+#define USART_LBLEN_10B               CTL1_LBLEN(0)                  /*!< 10 bits break detection */
+#define USART_LBLEN_11B               CTL1_LBLEN(1)                  /*!< 11 bits break detection */
+
+/* USART last bit clock pulse */
+#define CTL1_CLEN(regval)             (BIT(8) & ((uint32_t)(regval) << 8))
+#define USART_CLEN_NONE               CTL1_CLEN(0)                   /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */
+#define USART_CLEN_EN                 CTL1_CLEN(1)                   /*!< clock pulse of the last data bit (MSB) is output to the CK pin */
+
+/* USART clock phase */
+#define CTL1_CPH(regval)              (BIT(9) & ((uint32_t)(regval) << 9))
+#define USART_CPH_1CK                 CTL1_CPH(0)                    /*!< first clock transition is the first data capture edge */
+#define USART_CPH_2CK                 CTL1_CPH(1)                    /*!< second clock transition is the first data capture edge */
+
+/* USART clock polarity */
+#define CTL1_CPL(regval)              (BIT(10) & ((uint32_t)(regval) << 10))
+#define USART_CPL_LOW                 CTL1_CPL(0)                    /*!< steady low value on CK pin */
+#define USART_CPL_HIGH                CTL1_CPL(1)                    /*!< steady high value on CK pin */
+
+/* USART stop bits definitions */
+#define CTL1_STB(regval)              (BITS(12,13) & ((uint32_t)(regval) << 12))
+#define USART_STB_1BIT                CTL1_STB(0)                    /*!< 1 bit */
+#define USART_STB_0_5BIT              CTL1_STB(1)                    /*!< 0.5 bit */
+#define USART_STB_2BIT                CTL1_STB(2)                    /*!< 2 bits */
+#define USART_STB_1_5BIT              CTL1_STB(3)                    /*!< 1.5 bits */
+
+/* USART data is transmitted/received with the LSB/MSB first */
+#define CTL1_MSBF(regval)             (BIT(19) & ((uint32_t)(regval) << 19))
+#define USART_MSBF_LSB                CTL1_MSBF(0)                   /*!< LSB first */
+#define USART_MSBF_MSB                CTL1_MSBF(1)                   /*!< MSB first */
+
+/* USART auto baud rate detection mode bits definitions */
+#define CTL1_ABDM(regval)             (BITS(21,22) & ((uint32_t)(regval) << 21))
+#define USART_ABDM_FTOR               CTL1_ABDM(0)                   /*!< falling edge to rising edge measurement */
+#define USART_ABDM_FTOF               CTL1_ABDM(1)                   /*!< falling edge to falling edge measurement */
+
+/* USART IrDA low-power enable */
+#define CTL2_IRLP(regval)             (BIT(2) & ((uint32_t)(regval) << 2))
+#define USART_IRLP_LOW                CTL2_IRLP(1)                   /*!< low-power */
+#define USART_IRLP_NORMAL             CTL2_IRLP(0)                   /*!< normal */
+
+/* DMA enable for reception */
+#define CTL2_DENR(regval)             (BIT(6) & ((uint32_t)(regval) << 6))
+#define USART_DENR_ENABLE             CTL2_DENR(1)                   /*!< enable for reception */
+#define USART_DENR_DISABLE            CTL2_DENR(0)                   /*!< disable for reception */
+
+/* DMA enable for transmission */
+#define CTL2_DENT(regval)             (BIT(7) & ((uint32_t)(regval) << 7))
+#define USART_DENT_ENABLE             CTL2_DENT(1)                   /*!< enable for transmission */
+#define USART_DENT_DISABLE            CTL2_DENT(0)                   /*!< disable for transmission */
+
+/* USART RTS hardware flow control configure */
+#define CTL2_RTSEN(regval)            (BIT(8) & ((uint32_t)(regval) << 8))
+#define USART_RTS_ENABLE              CTL2_RTSEN(1)                  /*!< RTS hardware flow control enabled */
+#define USART_RTS_DISABLE             CTL2_RTSEN(0)                  /*!< RTS hardware flow control disabled */
+
+/* USART CTS hardware flow control configure */
+#define CTL2_CTSEN(regval)            (BIT(9) & ((uint32_t)(regval) << 9))
+#define USART_CTS_ENABLE              CTL2_CTSEN(1)                  /*!< CTS hardware flow control enabled */
+#define USART_CTS_DISABLE             CTL2_CTSEN(0)                  /*!< CTS hardware flow control disabled */
+
+/* USART one sample bit method configure */
+#define CTL2_OSB(regval)              (BIT(11) & ((uint32_t)(regval) << 11))
+#define USART_OSB_1BIT                CTL2_OSB(1)                    /*!< 1 sample bit */
+#define USART_OSB_3BIT                CTL2_OSB(0)                    /*!< 3 sample bits */
+
+/* USART driver enable polarity mode */
+#define CTL2_DEP(regval)              (BIT(15) & ((uint32_t)(regval) << 15))
+#define USART_DEP_HIGH                CTL2_DEP(0)                    /*!< DE signal is active high */
+#define USART_DEP_LOW                 CTL2_DEP(1)                    /*!< DE signal is active low */
+
+/* USART wakeup mode from deep-sleep mode */
+#define CTL2_WUM(regval)              (BITS(20,21) & ((uint32_t)(regval) << 20))
+#define USART_WUM_ADDR                CTL2_WUM(0)                    /*!< WUF active on address match */
+#define USART_WUM_STARTB              CTL2_WUM(2)                    /*!< WUF active on start bit */
+#define USART_WUM_RBNE                CTL2_WUM(3)                    /*!< WUF active on RBNE */
+
+/* USART hardware flow control coherence mode */
+#define CHC_HCM(regval)               (BIT(0) & ((uint32_t)(regval) << 0))
+#define USART_HCM_NONE                CHC_HCM(0)                    /*!< nRTS signal equals to the rxne status register */
+#define USART_HCM_EN                  CHC_HCM(1)                    /*!< nRTS signal is set when the last data bit has been sampled */
+
+/* function declarations */
+/* initialization functions */
+/* reset USART */
+void usart_deinit(uint32_t usart_periph);
+/* configure USART baud rate value */
+void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval);
+/* configure USART parity function */
+void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg);
+/* configure USART word length */
+void usart_word_length_set(uint32_t usart_periph, uint32_t wlen);
+/* configure USART stop bit length */
+void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen);
+/* enable USART */
+void usart_enable(uint32_t usart_periph);
+/* disable USART */
+void usart_disable(uint32_t usart_periph);
+/* configure USART transmitter */
+void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig);
+/* configure USART receiver */
+void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig);
+
+/* USART normal mode communication */
+/* data is transmitted/received with the LSB/MSB first */
+void usart_data_first_config(uint32_t usart_periph, uint32_t msbf);
+/* configure USART inverted */
+void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara);
+/* enable the USART overrun function */
+void usart_overrun_enable(uint32_t usart_periph);
+/* disable the USART overrun function */
+void usart_overrun_disable(uint32_t usart_periph);
+/* configure the USART oversample mode */
+void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp);
+/* configure sample bit method */
+void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb);
+/* enable receiver timeout */
+void usart_receiver_timeout_enable(uint32_t usart_periph);
+/* disable receiver timeout */
+void usart_receiver_timeout_disable(uint32_t usart_periph);
+/* configure receiver timeout threshold */
+void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout);
+/* USART transmit data function */
+void usart_data_transmit(uint32_t usart_periph, uint32_t data);
+/* USART receive data function */
+uint16_t usart_data_receive(uint32_t usart_periph);
+
+/* auto baud rate detection */
+/* enable auto baud rate detection */
+void usart_autobaud_detection_enable(uint32_t usart_periph);
+/* disable auto baud rate detection */
+void usart_autobaud_detection_disable(uint32_t usart_periph);
+/* configure auto baud rate detection mode */
+void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod);
+
+/* multi-processor communication */
+/* configure address of the USART */
+void usart_address_config(uint32_t usart_periph, uint8_t addr);
+/* configure address detection mode */
+void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod);
+/* enable mute mode */
+void usart_mute_mode_enable(uint32_t usart_periph);
+/* disable mute mode */
+void usart_mute_mode_disable(uint32_t usart_periph);
+/* configure wakeup method in mute mode */
+void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod);
+
+/* LIN mode communication */
+/* enable LIN mode */
+void usart_lin_mode_enable(uint32_t usart_periph);
+/* disable LIN mode */
+void usart_lin_mode_disable(uint32_t usart_periph);
+/* LIN break detection length */
+void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen);
+
+/* half-duplex communication */
+/* enable half-duplex mode */
+void usart_halfduplex_enable(uint32_t usart_periph);
+/* disable half-duplex mode */
+void usart_halfduplex_disable(uint32_t usart_periph);
+
+/* synchronous communication */
+/* enable clock */
+void usart_clock_enable(uint32_t usart_periph);
+/* disable clock */
+void usart_clock_disable(uint32_t usart_periph);
+/* configure USART synchronous mode parameters */
+void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl);
+
+/* smartcard communication */
+/* configure guard time value in smartcard mode */
+void usart_guard_time_config(uint32_t usart_periph, uint32_t guat);
+/* enable smartcard mode */
+void usart_smartcard_mode_enable(uint32_t usart_periph);
+/* disable smartcard mode */
+void usart_smartcard_mode_disable(uint32_t usart_periph);
+/* enable NACK in smartcard mode */
+void usart_smartcard_mode_nack_enable(uint32_t usart_periph);
+/* disable NACK in smartcard mode */
+void usart_smartcard_mode_nack_disable(uint32_t usart_periph);
+/* enable early NACK in smartcard mode */
+void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph);
+/* disable early NACK in smartcard mode */
+void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph);
+/* configure smartcard auto-retry number */
+void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum);
+/* configure block length */
+void usart_block_length_config(uint32_t usart_periph, uint32_t bl);
+
+/* IrDA communication */
+/* enable IrDA mode */
+void usart_irda_mode_enable(uint32_t usart_periph);
+/* disable IrDA mode */
+void usart_irda_mode_disable(uint32_t usart_periph);
+/* configure the peripheral clock prescaler */
+void usart_prescaler_config(uint32_t usart_periph, uint32_t psc);
+/* configure IrDA low-power */
+void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp);
+
+/* hardware flow communication */
+/* configure hardware flow control RTS */
+void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig);
+/* configure hardware flow control CTS */
+void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig);
+
+/* coherence control */
+/* configure hardware flow control coherence mode */
+void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm);
+
+/* enable RS485 driver */
+void usart_rs485_driver_enable(uint32_t usart_periph);
+/* disable RS485 driver */
+void usart_rs485_driver_disable(uint32_t usart_periph);
+/* configure driver enable assertion time */
+void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime);
+/* configure driver enable de-assertion time */
+void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime);
+/* configure driver enable polarity mode */
+void usart_depolarity_config(uint32_t usart_periph, uint32_t dep);
+
+/* USART DMA */
+/* configure USART DMA for reception */
+void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd);
+/* configure USART DMA for transmission */
+void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd);
+/* disable DMA on reception error */
+void usart_reception_error_dma_disable(uint32_t usart_periph);
+/* enable DMA on reception error */
+void usart_reception_error_dma_enable(uint32_t usart_periph);
+
+/* enable USART to wakeup the mcu from deep-sleep mode */
+void usart_wakeup_enable(uint32_t usart_periph);
+/* disable USART to wakeup the mcu from deep-sleep mode */
+void usart_wakeup_disable(uint32_t usart_periph);
+/* configure the USART wakeup mode from deep-sleep mode */
+void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum);
+
+/* USART receive FIFO */
+/* enable receive FIFO */
+void usart_receive_fifo_enable(uint32_t usart_periph);
+/* disable receive FIFO */
+void usart_receive_fifo_disable(uint32_t usart_periph);
+/* read receive FIFO counter number */
+uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph);
+
+/* flag & interrupt functions */
+/* get flag in STAT/RFCS register */
+FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag);
+/* clear USART status */
+void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag);
+/* enable USART interrupt */
+void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum inttype);
+/* disable USART interrupt */
+void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum inttype);
+/* enable USART command */
+void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype);
+/* get USART interrupt and flag status */
+FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag);
+/* clear USART interrupt flag */
+void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum flag);
+
+#endif /* GD32E230_USART_H */

+ 88 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h

@@ -0,0 +1,88 @@
+/*!
+    \file  gd32e230_wwdgt.h
+    \brief definitions for the WWDGT 
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_WWDGT_H
+#define GD32E230_WWDGT_H
+
+#include "gd32e230.h"
+
+/* WWDGT definitions */
+#define WWDGT                       WWDGT_BASE
+
+/* registers definitions */
+#define WWDGT_CTL                   REG32((WWDGT) + 0x00000000U)                     /*!< WWDGT control register */
+#define WWDGT_CFG                   REG32((WWDGT) + 0x00000004U)                     /*!< WWDGT configuration register */
+#define WWDGT_STAT                  REG32((WWDGT) + 0x00000008U)                     /*!< WWDGT status register */
+
+/* bits definitions */
+/* WWDGT_CTL */
+#define WWDGT_CTL_CNT               BITS(0,6)                                  /*!< WWDGT counter value */
+#define WWDGT_CTL_WDGTEN            BIT(7)                                     /*!< WWDGT counter enable */
+
+/* WWDGT_CFG */
+#define WWDGT_CFG_WIN               BITS(0,6)                                  /*!< WWDGT counter window value */
+#define WWDGT_CFG_PSC               BITS(7,8)                                  /*!< WWDGT prescaler divider value */
+#define WWDGT_CFG_EWIE              BIT(9)                                     /*!< WWDGT early wakeup interrupt enable */
+
+/* WWDGT_STAT */
+#define WWDGT_STAT_EWIF             BIT(0)                                     /*!< WWDGT early wakeup interrupt flag */
+
+/* constants definitions */
+#define CFG_PSC(regval)             (BITS(7,8) & ((uint32_t)(regval) << 7U))    /*!< write value to WWDGT_CFG_PSC bit field */
+#define WWDGT_CFG_PSC_DIV1          ((uint32_t)CFG_PSC(0))                     /*!< the time base of WWDGT = (PCLK1/4096)/1 */
+#define WWDGT_CFG_PSC_DIV2          ((uint32_t)CFG_PSC(1))                     /*!< the time base of WWDGT = (PCLK1/4096)/2 */
+#define WWDGT_CFG_PSC_DIV4          ((uint32_t)CFG_PSC(2))                     /*!< the time base of WWDGT = (PCLK1/4096)/4 */
+#define WWDGT_CFG_PSC_DIV8          ((uint32_t)CFG_PSC(3))                     /*!< the time base of WWDGT = (PCLK1/4096)/8 */
+
+/* function declarations */
+/* reset the window watchdog timer configuration */
+void wwdgt_deinit(void);
+/* start the window watchdog timer counter */
+void wwdgt_enable(void);
+
+/* configure the window watchdog timer counter value */
+void wwdgt_counter_update(uint16_t counter_value);
+/* configure counter value, window value, and prescaler divider value */
+void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler);
+
+/* enable early wakeup interrupt of WWDGT */
+void wwdgt_interrupt_enable(void);
+/* check early wakeup interrupt state of WWDGT */
+FlagStatus wwdgt_flag_get(void);
+/* clear early wakeup interrupt state of WWDGT */
+void wwdgt_flag_clear(void);
+
+#endif /* GD32E230_WWDGT_H */

+ 844 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c

@@ -0,0 +1,844 @@
+/*!
+    \file    gd32e230_adc.c
+    \brief   ADC driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_adc.h"
+
+/*!
+    \brief      reset ADC
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_ADCRST);
+    rcu_periph_reset_disable(RCU_ADCRST);
+}
+
+/*!
+    \brief      enable ADC interface
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_enable(void)
+{
+    if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){
+        ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON;
+    }
+}
+
+/*!
+    \brief      disable ADC interface
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_disable(void)
+{
+    ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ADCON);
+}
+
+/*!
+    \brief      ADC calibration and reset calibration
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_calibration_enable(void)
+{
+    /* reset the selected ADC calibration register */
+    ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB;
+    /* check the RSTCLB bit state */
+    while((ADC_CTL1 & ADC_CTL1_RSTCLB)){
+    }
+
+    /* enable ADC calibration process */
+    ADC_CTL1 |= ADC_CTL1_CLB;
+    /* check the CLB bit state */
+    while((ADC_CTL1 & ADC_CTL1_CLB)){
+    }
+}
+
+/*!
+    \brief      enable DMA request 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_dma_mode_enable(void)
+{
+    ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA);
+}
+
+/*!
+    \brief      disable DMA request 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_dma_mode_disable(void)
+{
+    ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA);
+}
+
+/*!
+    \brief      enable the temperature sensor and Vrefint channel
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_tempsensor_vrefint_enable(void)
+{
+    /* enable the temperature sensor and Vrefint channel */
+    ADC_CTL1 |= ADC_CTL1_TSVREN;
+}
+
+/*!
+    \brief      disable the temperature sensor and Vrefint channel
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_tempsensor_vrefint_disable(void)
+{
+    /* disable the temperature sensor and Vrefint channel */
+    ADC_CTL1 &= ~ADC_CTL1_TSVREN;
+}
+
+/*!
+    \brief      configure ADC discontinuous mode 
+    \param[in]  channel_group: select the channel group
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+      \arg        ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular and inserted channel
+    \param[in]  length: number of conversions in discontinuous mode, the number can be 1..8
+                        for regular channel, the number has no effect for inserted channel
+    \param[out] none
+    \retval     none
+*/
+void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length)
+{
+    ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC));
+    
+    switch(channel_group){
+    case ADC_REGULAR_CHANNEL:
+        /* configure the number of conversions in discontinuous mode */
+        ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM);
+        ADC_CTL0 |= CTL0_DISNUM(((uint32_t)length - 1U));
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC;
+        break;
+    case ADC_CHANNEL_DISCON_DISABLE:
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure ADC special function
+    \param[in]  function: the function to configure
+                one or more parameters can be selected which is shown as below:
+      \arg        ADC_SCAN_MODE: scan mode select
+      \arg        ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
+      \arg        ADC_CONTINUOUS_MODE: continuous mode select
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void adc_special_function_config(uint32_t function, ControlStatus newvalue)
+{
+    if(newvalue){
+        /* enable ADC scan mode */
+        if(RESET != (function & ADC_SCAN_MODE)){
+            ADC_CTL0 |= ADC_SCAN_MODE;
+        }
+        /* enable ADC inserted channel group convert automatically */
+        if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){
+            ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO;
+        }
+        /* enable ADC continuous mode */
+        if(RESET != (function & ADC_CONTINUOUS_MODE)){
+            ADC_CTL1 |= ADC_CONTINUOUS_MODE;
+        }
+    }else{
+        /* disable ADC scan mode */
+        if(RESET != (function & ADC_SCAN_MODE)){
+            ADC_CTL0 &= ~ADC_SCAN_MODE;
+        }
+        /* disable ADC inserted channel group convert automatically */
+        if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){
+            ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO;
+        }
+        /* disable ADC continuous mode */
+        if(RESET != (function & ADC_CONTINUOUS_MODE)){
+            ADC_CTL1 &= ~ADC_CONTINUOUS_MODE;
+        }
+    }
+}
+
+/*!
+    \brief      configure ADC data alignment 
+    \param[in]  data_alignment: data alignment select
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_DATAALIGN_RIGHT: right alignment
+      \arg        ADC_DATAALIGN_LEFT: left alignment
+    \param[out] none
+    \retval     none
+*/
+void adc_data_alignment_config(uint32_t data_alignment)
+{
+    if(ADC_DATAALIGN_RIGHT != data_alignment){
+        ADC_CTL1 |= ADC_CTL1_DAL;
+    }else{
+        ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL);
+    }
+}
+
+/*!
+    \brief      configure the length of regular channel group or inserted channel group
+    \param[in]  channel_group: select the channel group
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  length: the length of the channel
+                        regular channel 1-16
+                        inserted channel 1-4
+    \param[out] none
+    \retval     none
+*/
+void adc_channel_length_config(uint8_t channel_group, uint32_t length)
+{
+    switch(channel_group){
+    case ADC_REGULAR_CHANNEL:
+        /* configure the length of regular channel group */
+        ADC_RSQ0 &= ~((uint32_t)ADC_RSQ0_RL);
+        ADC_RSQ0 |= RSQ0_RL((uint32_t)(length-1U));
+        break;
+    case ADC_INSERTED_CHANNEL:
+        /* configure the length of inserted channel group */
+        ADC_ISQ &= ~((uint32_t)ADC_ISQ_IL);
+        ADC_ISQ |= ISQ_IL((uint32_t)(length-1U));
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure ADC regular channel
+    \param[in]  rank: the regular group sequence rank, this parameter must be between 0 to 15
+    \param[in]  channel: the selected ADC channel
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx
+    \param[in]  sample_time: the sample time value
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_SAMPLETIME_1POINT5: 1.5 cycles
+      \arg        ADC_SAMPLETIME_7POINT5: 7.5 cycles
+      \arg        ADC_SAMPLETIME_13POINT5: 13.5 cycles
+      \arg        ADC_SAMPLETIME_28POINT5: 28.5 cycles
+      \arg        ADC_SAMPLETIME_41POINT5: 41.5 cycles
+      \arg        ADC_SAMPLETIME_55POINT5: 55.5 cycles
+      \arg        ADC_SAMPLETIME_71POINT5: 71.5 cycles
+      \arg        ADC_SAMPLETIME_239POINT5: 239.5 cycles
+    \param[out] none
+    \retval     none
+*/
+void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time)
+{
+    uint32_t rsq,sampt;
+    
+    /* configure ADC regular sequence */
+    if(rank < 6U){
+        rsq = ADC_RSQ2;
+        rsq &=  ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank)));
+        rsq |= ((uint32_t)channel << (5U*rank));
+        ADC_RSQ2 = rsq;
+    }else if(rank < 12U){
+        rsq = ADC_RSQ1;
+        rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U))));
+        rsq |= ((uint32_t)channel << (5U*(rank-6U)));
+        ADC_RSQ1 = rsq;
+    }else if(rank < 16U){
+        rsq = ADC_RSQ0;
+        rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U))));
+        rsq |= ((uint32_t)channel << (5U*(rank-12U)));
+        ADC_RSQ0 = rsq;
+    }else{
+    }
+    
+    /* configure ADC sampling time */
+    if(channel < 10U){
+        sampt = ADC_SAMPT1;
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel)));
+        sampt |= (uint32_t)(sample_time << (3U*channel));
+        ADC_SAMPT1 = sampt;
+    }else if(channel < 19U){
+        sampt = ADC_SAMPT0;
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U))));
+        sampt |= (uint32_t)(sample_time << (3U*(channel-10U)));
+        ADC_SAMPT0 = sampt;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure ADC inserted channel 
+    \param[in]  rank: the inserted group sequencer rank,this parameter must be between 0 to 3
+    \param[in]  channel: the selected ADC channel
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx
+    \param[in]  sample_time: The sample time value
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_SAMPLETIME_1POINT5: 1.5 cycles
+      \arg        ADC_SAMPLETIME_7POINT5: 7.5 cycles
+      \arg        ADC_SAMPLETIME_13POINT5: 13.5 cycles
+      \arg        ADC_SAMPLETIME_28POINT5: 28.5 cycles
+      \arg        ADC_SAMPLETIME_41POINT5: 41.5 cycles
+      \arg        ADC_SAMPLETIME_55POINT5: 55.5 cycles
+      \arg        ADC_SAMPLETIME_71POINT5: 71.5 cycles
+      \arg        ADC_SAMPLETIME_239POINT5: 239.5 cycles
+    \param[out] none
+    \retval     none
+*/
+void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time)
+{
+    uint8_t inserted_length;
+    uint32_t isq,sampt;
+
+    inserted_length = (uint8_t)GET_BITS(ADC_ISQ , 20U , 21U);
+  
+    isq = ADC_ISQ;
+    isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U)));
+    isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U));
+    ADC_ISQ = isq;
+
+    /* configure ADC sampling time */
+    if(channel < 10U){
+        sampt = ADC_SAMPT1;
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel)));
+        sampt |= (uint32_t) sample_time << (3U*channel);
+        ADC_SAMPT1 = sampt;
+    }else if(channel < 19U){
+        sampt = ADC_SAMPT0;
+        sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel - 10U))));
+        sampt |= ((uint32_t)sample_time << (3U*(channel - 10U)));
+        ADC_SAMPT0 = sampt;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure ADC inserted channel offset
+    \param[in]  inserted_channel: insert channel select
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_INSERTED_CHANNEL_0: ADC inserted channel 0
+      \arg        ADC_INSERTED_CHANNEL_1: ADC inserted channel 1
+      \arg        ADC_INSERTED_CHANNEL_2: ADC inserted channel 2
+      \arg        ADC_INSERTED_CHANNEL_3: ADC inserted channel 3
+    \param[in]  offset: the offset data
+    \param[out] none
+    \retval     none
+*/
+void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset)
+{
+    uint8_t inserted_length;
+    uint32_t num = 0U;
+
+    inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U);
+    num = 3U - (inserted_length - inserted_channel);
+    
+    if(num <= 3U){
+        /* calculate the offset of the register */
+        num = num * 4U;
+        /* configure the offset of the selected channels */
+        REG32((ADC) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
+    }
+}
+
+/*!
+    \brief      enable or disable ADC external trigger 
+    \param[in]  channel_group: select the channel group
+                one or more parameters can be selected which is shown as below:
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue)
+{
+    if(newvalue){
+        /* external trigger enable for regular channel */
+        if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
+            ADC_CTL1 |= ADC_CTL1_ETERC;
+        }
+        /* external trigger enable for inserted channel */
+        if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
+            ADC_CTL1 |= ADC_CTL1_ETEIC;
+        }
+    }else{
+        /* external trigger disable for regular channel */
+        if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
+            ADC_CTL1 &= ~ADC_CTL1_ETERC;
+        }
+        /* external trigger disable for inserted channel */
+        if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
+            ADC_CTL1 &= ~ADC_CTL1_ETEIC;
+        }
+    }
+}
+
+/*!
+    \brief      configure ADC external trigger source 
+    \param[in]  channel_group: select the channel group
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[in]  external_trigger_source: regular or inserted group trigger source
+                only one parameter can be selected which is shown as below:
+                for regular channel:
+      \arg        ADC_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select 
+      \arg        ADC_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select 
+      \arg        ADC_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select  
+      \arg        ADC_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select 
+      \arg        ADC_EXTTRIG_REGULAR_T14_CH0:  TIMER14 CH0 event select 
+      \arg        ADC_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11
+      \arg        ADC_EXTTRIG_REGULAR_NONE: software trigger
+                for inserted channel:
+      \arg        ADC_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select
+      \arg        ADC_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select 
+      \arg        ADC_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select 
+      \arg        ADC_EXTTRIG_INSERTED_T14_TRGO: TIMER14 TRGO event select 
+      \arg        ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 
+      \arg        ADC_EXTTRIG_INSERTED_NONE: software trigger
+    \param[out] none
+    \retval     none
+*/
+void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source)
+{   
+    switch(channel_group){
+    case ADC_REGULAR_CHANNEL:
+        /* external trigger select for regular channel */
+        ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC);
+        ADC_CTL1 |= (uint32_t)external_trigger_source;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        /* external trigger select for inserted channel */
+        ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC);
+        ADC_CTL1 |= (uint32_t)external_trigger_source;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      enable ADC software trigger 
+    \param[in]  channel_group: select the channel group
+                one or more parameters can be selected which is shown as below:
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+    \param[out] none
+    \retval     none
+*/
+void adc_software_trigger_enable(uint8_t channel_group)
+{
+    /* enable regular group channel software trigger */
+    if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
+        ADC_CTL1 |= ADC_CTL1_SWRCST;
+    }
+    /* enable inserted channel group software trigger */
+    if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
+        ADC_CTL1 |= ADC_CTL1_SWICST;
+    }
+}
+
+/*!
+    \brief      read ADC regular group data register 
+    \param[in]  none
+    \param[out] none
+    \retval     the conversion value
+*/
+uint16_t adc_regular_data_read(void)
+{
+    return ((uint16_t)ADC_RDATA);
+}
+
+/*!
+    \brief      read ADC inserted group data register 
+    \param[in]  inserted_channel: inserted channel select
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_INSERTED_CHANNEL_0: ADC inserted channel 0
+      \arg        ADC_INSERTED_CHANNEL_1: ADC inserted channel 1
+      \arg        ADC_INSERTED_CHANNEL_2: ADC inserted channel 2
+      \arg        ADC_INSERTED_CHANNEL_3: ADC inserted channel 3
+    \param[out] none
+    \retval     the conversion value
+*/
+uint16_t adc_inserted_data_read(uint8_t inserted_channel)
+{
+    uint32_t idata;
+    /* read the data of the selected channel */
+    switch(inserted_channel){
+    case ADC_INSERTED_CHANNEL_0:
+        idata = ADC_IDATA0;
+        break;
+    case ADC_INSERTED_CHANNEL_1:
+        idata = ADC_IDATA1;
+        break;
+    case ADC_INSERTED_CHANNEL_2:
+        idata = ADC_IDATA2;
+        break;
+    case ADC_INSERTED_CHANNEL_3:
+        idata = ADC_IDATA3;
+        break;
+    default:
+        idata = 0U;
+        break;
+    }
+    return (uint16_t)idata;
+}
+
+/*!
+    \brief      get the ADC flag bits
+    \param[in]  flag: the adc flag bits
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_FLAG_WDE: analog watchdog event flag
+      \arg        ADC_FLAG_EOC: end of group conversion flag
+      \arg        ADC_FLAG_EOIC: end of inserted group conversion flag
+      \arg        ADC_FLAG_STIC: start flag of inserted channel group
+      \arg        ADC_FLAG_STRC: start flag of regular channel group
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus adc_flag_get(uint32_t flag)
+{
+    FlagStatus reval = RESET;
+    
+    if(ADC_STAT & flag){
+        reval = SET;
+    }
+    return reval;
+}
+
+/*!
+    \brief      clear the ADC flag 
+    \param[in]  flag: the adc flag 
+                one or more parameters can be selected which is shown as below:
+      \arg        ADC_FLAG_WDE: analog watchdog event flag
+      \arg        ADC_FLAG_EOC: end of group conversion flag
+      \arg        ADC_FLAG_EOIC: end of inserted group conversion flag
+      \arg        ADC_FLAG_STIC: start flag of inserted channel group
+      \arg        ADC_FLAG_STRC: start flag of regular channel group
+    \param[out] none
+    \retval     none
+*/
+void adc_flag_clear(uint32_t flag)
+{
+    ADC_STAT &= ~((uint32_t)flag);
+}
+
+/*!
+    \brief      get the ADC interrupt flag
+    \param[in]  flag: the adc interrupt flag
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_INT_FLAG_WDE: analog watchdog interrupt flag
+      \arg        ADC_INT_FLAG_EOC: end of group conversion interrupt flag
+      \arg        ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus adc_interrupt_flag_get(uint32_t flag)
+{
+    FlagStatus interrupt_flag = RESET;
+    uint32_t state;
+
+    /* check the interrupt bits */
+    switch(flag){
+    case ADC_INT_FLAG_WDE:
+        state = ADC_STAT & ADC_STAT_WDE;
+        if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){
+          interrupt_flag = SET;
+        }
+        break;
+    case ADC_INT_FLAG_EOC:
+        state = ADC_STAT & ADC_STAT_EOC;
+        if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){
+            interrupt_flag = SET;
+          }
+        break;
+    case ADC_INT_FLAG_EOIC:
+        state = ADC_STAT & ADC_STAT_EOIC;
+        if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){
+            interrupt_flag = SET;
+        }
+        break;
+    default:
+        break;
+    }
+    return interrupt_flag;
+}
+
+/*!
+    \brief      clear ADC interrupt flag
+    \param[in]  flag: the adc interrupt flag
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_INT_FLAG_WDE: analog watchdog interrupt flag
+      \arg        ADC_INT_FLAG_EOC: end of group conversion interrupt flag
+      \arg        ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag
+    \param[out] none
+    \retval     none
+*/
+void adc_interrupt_flag_clear(uint32_t flag)
+{
+    ADC_STAT &= ~((uint32_t)flag);
+}
+
+/*!
+    \brief      enable ADC interrupt 
+    \param[in]  interrupt: the adc interrupt
+                one or more parameters can be selected which is shown as below:
+      \arg        ADC_INT_WDE: analog watchdog interrupt 
+      \arg        ADC_INT_EOC: end of group conversion interrupt 
+      \arg        ADC_INT_EOIC: end of inserted group conversion interrupt 
+    \param[out] none
+    \retval     none
+*/
+void adc_interrupt_enable(uint32_t interrupt)
+{
+    /* enable analog watchdog interrupt */
+    if(RESET != (interrupt & ADC_INT_WDE)){
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_WDEIE;
+    }  
+
+    /* enable end of group conversion interrupt */
+    if(RESET != (interrupt & ADC_INT_EOC)){
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_EOCIE;
+    }  
+
+    /* enable end of inserted group conversion interrupt */
+    if(RESET != (interrupt & ADC_INT_EOIC)){
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_EOICIE;
+    }
+}
+
+/*!
+    \brief      disable ADC interrupt 
+    \param[in]  interrupt: the adc interrupt flag
+                one or more parameters can be selected which is shown as below:
+      \arg        ADC_INT_WDE: analog watchdog interrupt 
+      \arg        ADC_INT_EOC: end of group conversion interrupt 
+      \arg        ADC_INT_EOIC: end of inserted group conversion interrupt 
+    \param[out] none
+    \retval     none
+*/
+void adc_interrupt_disable(uint32_t interrupt)
+{  
+    /* disable analog watchdog interrupt */
+    if(RESET != (interrupt & ADC_INT_WDE)){
+        ADC_CTL0 &= ~(uint32_t)ADC_CTL0_WDEIE;
+    }
+    
+    /* disable end of group conversion interrupt */
+    if(RESET != (interrupt & ADC_INT_EOC)){
+        ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOCIE;
+    }
+    
+    /* disable end of inserted group conversion interrupt */
+    if(RESET != (interrupt & ADC_INT_EOIC)){
+        ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOICIE;
+    }
+}
+
+/*!
+    \brief      configure ADC analog watchdog single channel 
+    \param[in]  channel: the selected ADC channel
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_single_channel_enable(uint8_t channel)
+{
+    ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
+
+    ADC_CTL0 |= (uint32_t)channel;
+    ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
+}
+
+/*!
+    \brief      configure ADC analog watchdog group channel 
+    \param[in]  channel_group: the channel group use analog watchdog
+                only one parameter can be selected which is shown as below: 
+      \arg        ADC_REGULAR_CHANNEL: regular channel group
+      \arg        ADC_INSERTED_CHANNEL: inserted channel group
+      \arg        ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_group_channel_enable(uint8_t channel_group)
+{
+    ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
+
+    /* select the group */
+    switch(channel_group){
+    case ADC_REGULAR_CHANNEL:
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_RWDEN;
+        break;
+    case ADC_INSERTED_CHANNEL:
+        ADC_CTL0 |= (uint32_t)ADC_CTL0_IWDEN;
+        break;
+    case ADC_REGULAR_INSERTED_CHANNEL:
+        ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      disable ADC analog watchdog 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_disable(void)
+{
+    ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
+}
+
+/*!
+    \brief      configure ADC analog watchdog threshold 
+    \param[in]  low_threshold: analog watchdog low threshold,0..4095
+    \param[in]  high_threshold: analog watchdog high threshold,0..4095
+    \param[out] none
+    \retval     none
+*/
+void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold)
+{
+    ADC_WDLT = (uint32_t)WDLT_WDLT(low_threshold);
+    ADC_WDHT = (uint32_t)WDHT_WDHT(high_threshold);
+}
+
+
+/*!
+    \brief      configure ADC resolution 
+    \param[in]  resolution: ADC resolution
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_RESOLUTION_12B: 12-bit ADC resolution
+      \arg        ADC_RESOLUTION_10B: 10-bit ADC resolution
+      \arg        ADC_RESOLUTION_8B: 8-bit ADC resolution
+      \arg        ADC_RESOLUTION_6B: 6-bit ADC resolution
+    \param[out] none
+    \retval     none
+*/
+void adc_resolution_config(uint32_t resolution)
+{
+    ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES);
+    ADC_CTL0 |= (uint32_t)resolution;
+}
+
+/*!
+    \brief      configure ADC oversample mode 
+    \param[in]  mode: ADC oversampling mode
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger
+      \arg        ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger
+    \param[in]  shift: ADC oversampling shift
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
+      \arg        ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
+    \param[in]  ratio: ADC oversampling ratio
+                only one parameter can be selected which is shown as below:
+      \arg        ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2
+      \arg        ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4
+      \arg        ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8
+      \arg        ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16
+      \arg        ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32
+      \arg        ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64
+      \arg        ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128
+      \arg        ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256
+    \param[out] none
+    \retval     none
+*/
+void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio)
+{
+    /* configure ADC oversampling mode */
+    if(ADC_OVERSAMPLING_ONE_CONVERT == mode){
+        ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS;
+    }else{
+        ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS);
+    }
+    
+    /* configure the shift and ratio */
+    ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS));
+    ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio);
+}
+
+/*!
+    \brief      enable ADC oversample mode 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_oversample_mode_enable(void)
+{
+    ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN;
+}
+
+/*!
+    \brief      disable ADC oversample mode 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void adc_oversample_mode_disable(void)
+{
+    ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
+}

+ 180 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c

@@ -0,0 +1,180 @@
+/*!
+    \file    gd32e230_cmp.c
+    \brief   CMP driver
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_cmp.h"
+
+/*!
+    \brief      deinitialize comparator 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void cmp_deinit(void)
+{
+    CMP_CS = ((uint32_t)0x00000000U);
+}
+
+/*!
+    \brief      initialize comparator mode 
+    \param[in]  operating_mode
+      \arg        CMP_HIGHSPEED: high speed mode
+      \arg        CMP_MIDDLESPEED: medium speed mode
+      \arg        CMP_LOWSPEED: low speed mode
+      \arg        CMP_VERYLOWSPEED: very-low speed mode
+    \param[in]  inverting_input 
+      \arg        CMP_1_4VREFINT: VREFINT *1/4 input
+      \arg        CMP_1_2VREFINT: VREFINT *1/2 input
+      \arg        CMP_3_4VREFINT: VREFINT *3/4 input
+      \arg        CMP_VREFINT: VREFINT input
+      \arg        CMP_PA4: PA4 input
+      \arg        CMP_PA5: PA5 input
+      \arg        CMP_PA0: PA0 input
+      \arg        CMP_PA2: PA2 input
+    \param[in]  hysteresis
+      \arg        CMP_HYSTERESIS_NO: output no hysteresis
+      \arg        CMP_HYSTERESIS_LOW: output low hysteresis
+      \arg        CMP_HYSTERESIS_MIDDLE: output middle hysteresis
+      \arg        CMP_HYSTERESIS_HIGH: output high hysteresis
+    \param[out] none
+    \retval     none
+*/
+void cmp_mode_init(operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis)
+{
+    /* initialize comparator mode */
+    CMP_CS |= CS_CMPM(operating_mode) | CS_CMPMSEL(inverting_input) | CS_CMPHST(output_hysteresis);
+  
+}
+
+/*!
+    \brief      initialize comparator output
+    \param[in]  output_slection 
+      \arg        CMP_OUTPUT_NONE: output no selection
+      \arg        CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input
+      \arg        CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture 
+      \arg        CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input
+      \arg        CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture
+      \arg        CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input
+    \param[in]  output_polarity 
+      \arg        CMP_OUTPUT_POLARITY_INVERTED: output is inverted
+      \arg        CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted
+    \param[out] none
+    \retval     none
+*/
+void cmp_output_init(cmp_output_enum output_slection, uint32_t output_polarity)
+{
+    /* initialize comparator output */
+
+    CMP_CS |= CS_CMPOSEL(output_slection);
+    /* output polarity */
+    if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
+         CMP_CS |= CMP_CS_CMPPL;
+    }else{ 
+         CMP_CS &= ~CMP_CS_CMPPL;
+    }
+
+}
+
+/*!
+    \brief      enable comparator 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void cmp_enable(void)
+{
+    CMP_CS |= CMP_CS_CMPEN;
+}
+
+/*!
+    \brief      disable comparator 
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void cmp_disable(void)
+{
+    CMP_CS &= ~CMP_CS_CMPEN;
+}
+
+/*!
+    \brief      enable comparator switch
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void cmp_switch_enable(void)
+{
+    CMP_CS |= CMP_CS_CMPSW;
+}
+
+/*!
+    \brief      disable comparator switch
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void cmp_switch_disable(void)
+{
+    CMP_CS &= ~CMP_CS_CMPSW;
+}
+
+/*!
+    \brief      get output level
+    \param[in]  none
+    \param[out] none
+    \retval     the output level
+*/
+uint32_t cmp_output_level_get(void)
+{
+    if(CMP_CS & CMP_CS_CMPO){
+        return CMP_OUTPUTLEVEL_HIGH;
+    }else{
+        return CMP_OUTPUTLEVEL_LOW;
+    }
+    
+}
+
+/*!
+    \brief      lock the comparator
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void cmp_lock_enable(void)
+{
+    CMP_CS |= CMP_CS_CMPLK;
+}
+

+ 206 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c

@@ -0,0 +1,206 @@
+/*!
+    \file    gd32e230_crc.c
+    \brief   CRC driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_crc.h"
+
+/*!
+    \brief      deinit CRC calculation unit
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void crc_deinit(void)
+{
+    CRC_IDATA = (uint32_t)0xFFFFFFFFU;
+    CRC_DATA  = (uint32_t)0xFFFFFFFFU;
+    CRC_FDATA = (uint32_t)0x00000000U;
+    CRC_POLY  = (uint32_t)0x04C11DB7U;
+    CRC_CTL   = CRC_CTL_RST;   
+}
+
+/*!
+    \brief      enable the reverse operation of output data
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void crc_reverse_output_data_enable(void)
+{
+    CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O);
+    CRC_CTL |= (uint32_t)CRC_CTL_REV_O;
+}
+
+/*!
+    \brief      disable the reverse operation of output data
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void crc_reverse_output_data_disable(void)
+{
+    CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O);
+}
+
+/*!
+    \brief      reset data register to the value of initializaiton data register
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void crc_data_register_reset(void)
+{
+    CRC_CTL |= (uint32_t)CRC_CTL_RST;
+}
+
+/*!
+    \brief      read the data register 
+    \param[in]  none
+    \param[out] none
+    \retval     32-bit value of the data register
+*/
+uint32_t crc_data_register_read(void)
+{
+    uint32_t data;
+    data = CRC_DATA;
+    return (data);
+}
+
+/*!
+    \brief      read the free data register
+    \param[in]  none
+    \param[out] none
+    \retval     8-bit value of the free data register
+*/
+uint8_t crc_free_data_register_read(void)
+{
+    uint8_t fdata;
+    fdata = (uint8_t)CRC_FDATA;
+    return (fdata);
+}
+
+/*!
+    \brief      write the free data register
+    \param[in]  free_data: specify 8-bit data
+    \param[out] none
+    \retval     none
+*/
+void crc_free_data_register_write(uint8_t free_data)
+{
+    CRC_FDATA = (uint32_t)free_data;
+}
+
+/*!
+    \brief      write the initializaiton data register
+    \param[in]  init_data:specify 32-bit data
+    \param[out] none
+    \retval     none
+*/
+void crc_init_data_register_write(uint32_t init_data)
+{
+    CRC_IDATA = (uint32_t)init_data;
+}
+
+/*!
+    \brief      configure the CRC input data function
+    \param[in]  data_reverse: specify input data reverse function
+      \arg        CRC_INPUT_DATA_NOT: input data is not reversed
+      \arg        CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits
+      \arg        CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits
+      \arg        CRC_INPUT_DATA_WORD: input data is reversed on 32 bits
+    \param[out] none
+    \retval     none
+*/
+void crc_input_data_reverse_config(uint32_t data_reverse)
+{
+    CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I);
+    CRC_CTL |= (uint32_t)data_reverse;
+}
+
+/*!
+    \brief      configure the CRC size of polynomial function
+    \param[in]  poly_size: size of polynomial
+      \arg        CRC_CTL_PS_32: 32-bit polynomial for CRC calculation
+      \arg        CRC_CTL_PS_16: 16-bit polynomial for CRC calculation
+      \arg        CRC_CTL_PS_8: 8-bit polynomial for CRC calculation
+      \arg        CRC_CTL_PS_7: 7-bit polynomial for CRC calculation
+    \param[out] none
+    \retval     none
+*/
+void crc_polynomial_size_set(uint32_t poly_size)
+{
+    CRC_CTL &= (uint32_t)(~(CRC_CTL_PS));
+    CRC_CTL |= (uint32_t)poly_size;
+}
+
+/*!
+    \brief      configure the CRC polynomial value function
+    \param[in]  poly: configurable polynomial value
+    \param[out] none
+    \retval     none
+*/
+void crc_polynomial_set(uint32_t poly)
+{
+    CRC_POLY &= (uint32_t)(~CRC_POLY_POLY);
+    CRC_POLY = poly;
+}
+
+/*!
+    \brief      CRC calculate a 32-bit data
+    \param[in]  sdata: specify 32-bit data
+    \param[out] none
+    \retval     32-bit CRC calculate value
+*/
+uint32_t crc_single_data_calculate(uint32_t sdata)
+{
+    CRC_DATA = sdata;
+    return(CRC_DATA);
+}
+
+/*!
+    \brief      CRC calculate a 32-bit data array
+    \param[in]  array: pointer to an array of 32 bit data words
+    \param[in]  size: size of the array
+    \param[out] none
+    \retval     32-bit CRC calculate value
+*/
+uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size)
+{  
+    uint32_t index;
+    for(index = 0U; index < size; index++){
+        CRC_DATA = array[index];
+    }
+    return (CRC_DATA);    
+}

+ 140 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c

@@ -0,0 +1,140 @@
+/*!
+    \file    gd32e230_dbg.c
+    \brief   DBG driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_dbg.h"
+
+#define DBG_RESET_VAL       0x00000000U
+
+/*!
+    \brief      deinitialize the DBG
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void dbg_deinit(void)
+{
+    DBG_CTL0 = DBG_RESET_VAL;
+    DBG_CTL1 = DBG_RESET_VAL;
+}
+
+/*!
+    \brief      read DBG_ID code register
+    \param[in]  none
+    \param[out] none
+    \retval     DBG_ID code
+*/
+uint32_t dbg_id_get(void)
+{
+    return DBG_ID;
+}
+
+/*!
+    \brief      enable low power behavior when the mcu is in debug mode
+    \param[in]  dbg_low_power:
+                this parameter can be any combination of the following values:
+      \arg        DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode
+      \arg        DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode
+      \arg        DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode
+    \param[out] none
+    \retval     none
+*/
+void dbg_low_power_enable(uint32_t dbg_low_power)
+{
+    DBG_CTL0 |= dbg_low_power;
+}
+
+/*!
+    \brief      disable low power behavior when the mcu is in debug mode
+    \param[in]  dbg_low_power:
+                this parameter can be any combination of the following values:
+      \arg        DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode
+      \arg        DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode
+      \arg        DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode
+    \param[out] none
+    \retval     none
+*/
+void dbg_low_power_disable(uint32_t dbg_low_power)
+{
+    DBG_CTL0 &= ~dbg_low_power;
+}
+
+/*!
+    \brief      enable peripheral behavior when the mcu is in debug mode
+    \param[in]  dbg_periph: DBG peripheral 
+                only one parameter can be selected which is shown as below:
+      \arg        DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
+      \arg        DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
+      \arg        DBG_TIMER0_HOLD: TIMER0 counter kept when core is halted
+      \arg        DBG_TIMER2_HOLD: TIMER2 counter kept when core is halted
+      \arg        DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted
+      \arg        DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted
+      \arg        DBG_TIMER14_HOLD: hold TIMER14 counter when core is halted
+      \arg        DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted
+      \arg        DBG_TIMER16_HOLD: hold TIMER16 counter when core is halted
+      \arg        DBG_I2C0_HOLD: hold I2C0 SMBUS when core is halted
+      \arg        DBG_I2C1_HOLD: hold I2C1 SMBUS when core is halted
+      \arg        DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
+    \param[out] none
+    \retval     none
+*/
+void dbg_periph_enable(dbg_periph_enum dbg_periph)
+{
+    DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph));
+}
+
+/*!
+    \brief      disable peripheral behavior when the mcu is in debug mode
+    \param[in]  dbg_periph: DBG peripheral 
+                only one parameter can be selected which is shown as below:
+      \arg        DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
+      \arg        DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
+      \arg        DBG_TIMER0_HOLD: TIMER0 counter kept when core is halted
+      \arg        DBG_TIMER2_HOLD: TIMER2 counter kept when core is halted
+      \arg        DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted
+      \arg        DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted
+      \arg        DBG_TIMER14_HOLD: hold TIMER14 counter when core is halted
+      \arg        DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted
+      \arg        DBG_TIMER16_HOLD: hold TIMER16 counter when core is halted
+      \arg        DBG_I2C0_HOLD: hold I2C0 SMBUS when core is halted
+      \arg        DBG_I2C1_HOLD: hold I2C1 SMBUS when core is halted
+      \arg        DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
+    \param[out] none
+    \retval     none
+*/
+void dbg_periph_disable(dbg_periph_enum dbg_periph)
+{
+    DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph));
+}

+ 562 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c

@@ -0,0 +1,562 @@
+/*!
+    \file    gd32e230_dma.c
+    \brief   DMA driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_dma.h"
+
+/*!
+    \brief      deinitialize DMA a channel registers 
+    \param[in]  channelx: specify which DMA channel is deinitialized
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_deinit(dma_channel_enum channelx)
+{
+    /* disable DMA a channel */
+    DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN;
+    /* reset DMA channel registers */
+    DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE;
+    DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE;
+    DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE;
+    DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE;
+    DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
+}
+
+/*!
+    \brief      initialize the parameters of DMA struct with the default values
+    \param[in]  init_struct: the initialization data needed to initialize DMA channel
+    \param[out] none
+    \retval     none
+*/
+void dma_struct_para_init(dma_parameter_struct* init_struct)
+{
+    /* set the DMA struct with the default values */
+    init_struct->periph_addr  = 0U;
+    init_struct->periph_width = 0U; 
+    init_struct->periph_inc   = (uint8_t)DMA_PERIPH_INCREASE_DISABLE;
+    init_struct->memory_addr  = 0U;
+    init_struct->memory_width = 0U;
+    init_struct->memory_inc   = (uint8_t)DMA_MEMORY_INCREASE_DISABLE;
+    init_struct->number       = 0U;
+    init_struct->direction    = (uint8_t)DMA_PERIPHERAL_TO_MEMORY;
+    init_struct->priority     = (uint32_t)DMA_PRIORITY_LOW;
+}
+
+/*!
+    \brief      initialize DMA channel 
+    \param[in]  channelx: specify which DMA channel is initialized
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  init_struct: the data needed to initialize DMA channel
+                  periph_addr: peripheral base address
+                  periph_width: DMA_PERIPHERAL_WIDTH_8BIT,DMA_PERIPHERAL_WIDTH_16BIT,DMA_PERIPHERAL_WIDTH_32BIT
+                  periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE 
+                  memory_addr: memory base address
+                  memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT
+                  memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE
+                  direction: DMA_PERIPHERAL_TO_MEMORY,DMA_MEMORY_TO_PERIPHERAL
+                  number: the number of remaining data to be transferred by the DMA
+                  priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH
+    \param[out] none
+    \retval     none
+*/
+void dma_init(dma_channel_enum channelx, dma_parameter_struct* init_struct)
+{
+    uint32_t ctl;
+    
+    dma_channel_disable(channelx);
+    
+    /* configure peripheral base address */
+    DMA_CHPADDR(channelx) = init_struct->periph_addr;
+    
+    /* configure memory base address */
+    DMA_CHMADDR(channelx) = init_struct->memory_addr;
+    
+    /* configure the number of remaining data to be transferred */
+    DMA_CHCNT(channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK);
+    
+    /* configure peripheral transfer width,memory transfer width,channel priotity */
+    ctl = DMA_CHCTL(channelx);
+    ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO);
+    ctl |= (init_struct->periph_width | init_struct->memory_width | init_struct->priority);
+    DMA_CHCTL(channelx) = ctl;
+
+    /* configure peripheral increasing mode */
+    if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){
+        DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA;
+    }else{
+        DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA;
+    }
+
+    /* configure memory increasing mode */
+    if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){
+        DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA;
+    }else{
+        DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA;
+    }
+    
+    /* configure the direction of  data transfer */
+    if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction){
+        DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR;
+    }else{
+        DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR;
+    } 
+}
+
+/*!
+    \brief      enable DMA circulation mode  
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none 
+*/
+void dma_circulation_enable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN;
+}
+
+/*!
+    \brief      disable DMA circulation mode  
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none 
+*/
+void dma_circulation_disable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN;
+}
+
+/*!
+    \brief      enable memory to memory mode
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_to_memory_enable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M;
+}
+
+/*!
+    \brief      disable memory to memory mode
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_to_memory_disable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M;
+}
+
+/*!
+    \brief      enable DMA channel 
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none 
+*/
+void dma_channel_enable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN;
+}
+
+/*!
+    \brief      disable DMA channel 
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none 
+*/
+void dma_channel_disable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN;
+}
+
+/*!
+    \brief      set DMA peripheral base address  
+    \param[in]  channelx: specify which DMA channel to set peripheral base address 
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  address: peripheral base address
+    \param[out] none
+    \retval     none 
+*/
+void dma_periph_address_config(dma_channel_enum channelx, uint32_t address)
+{
+    DMA_CHPADDR(channelx) = address;
+}
+
+/*!
+    \brief      set DMA memory base address  
+    \param[in]  channelx: specify which DMA channel to set memory base address 
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  address: memory base address
+    \param[out] none
+    \retval     none 
+*/
+void dma_memory_address_config(dma_channel_enum channelx, uint32_t address)
+{
+    DMA_CHMADDR(channelx) = address;
+}
+
+/*!
+    \brief      set the number of remaining data to be transferred by the DMA  
+    \param[in]  channelx: specify which DMA channel to set number 
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  number: the number of remaining data to be transferred by the DMA
+    \param[out] none
+    \retval     none 
+*/
+void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number)
+{
+    DMA_CHCNT(channelx) = (number & DMA_CHANNEL_CNT_MASK);
+}
+
+/*!
+    \brief      get the number of remaining data to be transferred by the DMA  
+    \param[in]  channelx: specify which DMA channel to set number 
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     the number of remaining data to be transferred by the DMA 
+*/
+uint32_t dma_transfer_number_get(dma_channel_enum channelx)
+{
+    return (uint32_t)DMA_CHCNT(channelx);
+}
+
+/*!
+    \brief      configure priority level of DMA channel
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  priority: priority level of this channel
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_PRIORITY_LOW: low priority
+      \arg        DMA_PRIORITY_MEDIUM: medium priority
+      \arg        DMA_PRIORITY_HIGH: high priority
+      \arg        DMA_PRIORITY_ULTRA_HIGH: ultra high priority
+    \param[out] none
+    \retval     none 
+*/
+void dma_priority_config(dma_channel_enum channelx, uint32_t priority)
+{
+    uint32_t ctl;
+    
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_PRIO;
+    ctl |= priority;
+    DMA_CHCTL(channelx) = ctl;
+}
+
+/*!
+    \brief      configure transfer data width of memory 
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  mwidth: transfer data width of memory
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit
+      \arg        DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit
+      \arg        DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_width_config(dma_channel_enum channelx, uint32_t mwidth)
+{
+    uint32_t ctl;
+    
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_MWIDTH;
+    ctl |= mwidth;
+    DMA_CHCTL(channelx) = ctl;
+}
+
+/*!
+    \brief      configure transfer data width of peripheral 
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  pwidth: transfer data width of peripheral
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit
+      \arg        DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit
+      \arg        DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit
+    \param[out] none
+    \retval     none
+*/
+void dma_periph_width_config(dma_channel_enum channelx, uint32_t pwidth)
+{
+    uint32_t ctl;
+    
+    /* acquire DMA_CHxCTL register */
+    ctl = DMA_CHCTL(channelx);
+    /* assign regiser */
+    ctl &= ~DMA_CHXCTL_PWIDTH;
+    ctl |= pwidth;
+    DMA_CHCTL(channelx) = ctl;
+}
+
+/*!
+    \brief      enable next address increasement algorithm of memory  
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_increase_enable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA;
+}
+
+/*!
+    \brief      disable next address increasement algorithm of memory  
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_memory_increase_disable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA;
+}
+
+/*!
+    \brief      enable next address increasement algorithm of peripheral
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_periph_increase_enable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA;
+}
+
+/*!
+    \brief      disable next address increasement algorithm of peripheral  
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[out] none
+    \retval     none
+*/
+void dma_periph_increase_disable(dma_channel_enum channelx)
+{
+    DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA;
+}
+
+/*!
+    \brief      configure the direction of data transfer on the channel  
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  direction: specify the direction of  data transfer
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory
+      \arg        DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral
+    \param[out] none
+    \retval     none
+*/
+void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction)
+{
+    if(DMA_PERIPHERAL_TO_MEMORY == direction){
+        DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR;
+    } else {
+        DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR;
+    }
+}
+
+/*!
+    \brief      check DMA flag is set or not 
+    \param[in]  channelx: specify which DMA channel to get flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  flag: specify get which flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_FLAG_G: global interrupt flag of channel
+      \arg        DMA_FLAG_FTF: full transfer finish flag of channel
+      \arg        DMA_FLAG_HTF: half transfer finish flag of channel
+      \arg        DMA_FLAG_ERR: error flag of channel
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag)
+{
+    FlagStatus reval;
+
+    if(RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))){
+        reval = SET;
+    }else{
+        reval = RESET;
+    }
+    
+    return reval;
+}
+
+/*!
+    \brief      clear DMA a channel flag
+    \param[in]  channelx: specify which DMA channel to clear flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  flag: specify get which flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_FLAG_G: global interrupt flag of channel
+      \arg        DMA_FLAG_FTF: full transfer finish flag of channel
+      \arg        DMA_FLAG_HTF: half transfer finish flag of channel
+      \arg        DMA_FLAG_ERR: error flag of channel
+    \param[out] none
+    \retval     none
+*/
+void dma_flag_clear(dma_channel_enum channelx, uint32_t flag)
+{
+    DMA_INTC |= DMA_FLAG_ADD(flag, channelx);
+}
+
+/*!
+    \brief      check DMA flag and interrupt enable bit is set or not  
+    \param[in]  channelx: specify which DMA channel to get flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  flag: specify get which flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_INT_FLAG_FTF: transfer finish flag of channel
+      \arg        DMA_INT_FLAG_HTF: half transfer finish flag of channel
+      \arg        DMA_INT_FLAG_ERR: error flag of channel
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag)
+{
+    uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
+    
+    switch(flag){
+        case DMA_INT_FLAG_FTF:
+            interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx);
+            interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE;
+            break;
+        case DMA_INT_FLAG_HTF:
+            interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx);
+            interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE;
+            break;
+        case DMA_INT_FLAG_ERR:
+            interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx);
+            interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_ERRIE;
+            break;
+        default:
+            break;
+        }
+    
+    if(interrupt_flag && interrupt_enable){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear DMA a channel interrupt flag
+    \param[in]  channelx: specify which DMA channel to clear flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  flag: specify get which flag
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_INT_FLAG_G: global interrupt flag of channel
+      \arg        DMA_INT_FLAG_FTF: transfer finish flag of channel
+      \arg        DMA_INT_FLAG_HTF: half transfer finish flag of channel
+      \arg        DMA_INT_FLAG_ERR: error flag of channel
+    \param[out] none
+    \retval     none
+*/
+void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag)
+{
+    DMA_INTC |= DMA_FLAG_ADD(flag,channelx);
+}
+
+/*!
+    \brief      enable DMA interrupt
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  source: specify which interrupt to enable
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_INT_ERR: channel error interrupt
+      \arg        DMA_INT_HTF: channel half transfer finish interrupt
+      \arg        DMA_INT_FTF: channel full transfer finish interrupt
+    \param[out] none
+    \retval     none
+*/
+void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source)
+{
+    DMA_CHCTL(channelx) |= source;
+}
+
+/*!
+    \brief      disable DMA interrupt
+    \param[in]  channelx: specify which DMA channel to set
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_CHx(x=0..4)
+    \param[in]  source: specify which interrupt to disable
+                only one parameter can be selected which is shown as below:
+      \arg        DMA_INT_ERR: channel error interrupt
+      \arg        DMA_INT_HTF: channel half transfer finish interrupt
+      \arg        DMA_INT_FTF: channel full transfer finish interrupt
+    \param[out] none
+    \retval     none
+*/
+void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source)
+{
+    DMA_CHCTL(channelx) &= ~source;
+}

+ 254 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c

@@ -0,0 +1,254 @@
+/*!
+    \file    gd32e230_exti.c
+    \brief   EXTI driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_exti.h"
+
+/*!
+    \brief      deinitialize the EXTI
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void exti_deinit(void)
+{
+    /* reset the value of all the EXTI registers */
+    EXTI_INTEN = (uint32_t)0x0F940000U;
+    EXTI_EVEN  = (uint32_t)0x00000000U;
+    EXTI_RTEN  = (uint32_t)0x00000000U;
+    EXTI_FTEN  = (uint32_t)0x00000000U;
+    EXTI_SWIEV = (uint32_t)0x00000000U;
+}
+
+/*!
+    \brief      initialize the EXTI
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[in]  mode: interrupt or event mode, refer to exti_mode_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_INTERRUPT: interrupt mode
+      \arg        EXTI_EVENT: event mode
+    \param[in]  trig_type: interrupt trigger type, refer to exti_trig_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_TRIG_RISING: rising edge trigger
+      \arg        EXTI_TRIG_FALLING: falling trigger
+      \arg        EXTI_TRIG_BOTH: rising and falling trigger
+    \param[out] none
+    \retval     none
+*/
+void exti_init(exti_line_enum linex, \
+                exti_mode_enum mode, \
+                exti_trig_type_enum trig_type)
+{
+    /* reset the EXTI line x */
+    EXTI_INTEN &= ~(uint32_t)linex;
+    EXTI_EVEN &= ~(uint32_t)linex;
+    EXTI_RTEN &= ~(uint32_t)linex;
+    EXTI_FTEN &= ~(uint32_t)linex;
+    
+    /* set the EXTI mode and enable the interrupts or events from EXTI line x */
+    switch(mode){
+    case EXTI_INTERRUPT:
+        EXTI_INTEN |= (uint32_t)linex;
+        break;
+    case EXTI_EVENT:
+        EXTI_EVEN |= (uint32_t)linex;
+        break;
+    default:
+        break;
+    }
+    
+    /* set the EXTI trigger type */
+    switch(trig_type){
+    case EXTI_TRIG_RISING:
+        EXTI_RTEN |= (uint32_t)linex;
+        EXTI_FTEN &= ~(uint32_t)linex;
+        break;
+    case EXTI_TRIG_FALLING:
+        EXTI_RTEN &= ~(uint32_t)linex;
+        EXTI_FTEN |= (uint32_t)linex;
+        break;
+    case EXTI_TRIG_BOTH:
+        EXTI_RTEN |= (uint32_t)linex;
+        EXTI_FTEN |= (uint32_t)linex;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      enable the interrupts from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..27): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_interrupt_enable(exti_line_enum linex)
+{
+    EXTI_INTEN |= (uint32_t)linex;
+}
+
+/*!
+    \brief      enable the events from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..27): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_event_enable(exti_line_enum linex)
+{
+    EXTI_EVEN |= (uint32_t)linex;
+}
+
+/*!
+    \brief      disable the interrupt from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..27): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_interrupt_disable(exti_line_enum linex)
+{
+    EXTI_INTEN &= ~(uint32_t)linex;
+}
+
+/*!
+    \brief      disable the events from EXTI line x
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..27): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_event_disable(exti_line_enum linex)
+{
+    EXTI_EVEN &= ~(uint32_t)linex;
+}
+
+/*!
+    \brief      get EXTI lines flag
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[out] none
+    \retval     FlagStatus: status of flag (RESET or SET)
+*/
+FlagStatus exti_flag_get(exti_line_enum linex)
+{
+    if(RESET != (EXTI_PD & (uint32_t)linex)){
+        return SET;
+    }else{
+        return RESET;
+    } 
+}
+
+/*!
+    \brief      clear EXTI lines pending flag
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_flag_clear(exti_line_enum linex)
+{
+    EXTI_PD = (uint32_t)linex;
+}
+
+/*!
+    \brief      get EXTI lines flag when the interrupt flag is set
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[out] none
+    \retval     FlagStatus: status of flag (RESET or SET)
+*/
+FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
+{
+    uint32_t flag_left, flag_right;
+    
+    flag_left = EXTI_PD & (uint32_t)linex;
+    flag_right = EXTI_INTEN & (uint32_t)linex;
+    
+    if((RESET != flag_left) && (RESET != flag_right)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear EXTI lines pending flag
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_interrupt_flag_clear(exti_line_enum linex)
+{
+    EXTI_PD = (uint32_t)linex;
+}
+
+/*!
+    \brief      enable EXTI software interrupt event
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_software_interrupt_enable(exti_line_enum linex)
+{
+    EXTI_SWIEV |= (uint32_t)linex;
+}
+
+/*!
+    \brief      disable EXTI software interrupt event
+    \param[in]  linex: EXTI line number, refer to exti_line_enum
+                only one parameter can be selected which is shown as below:
+      \arg        EXTI_x (x=0..17,19,21): EXTI line x
+    \param[out] none
+    \retval     none
+*/
+void exti_software_interrupt_disable(exti_line_enum linex)
+{
+    EXTI_SWIEV &= ~(uint32_t)linex;
+}

+ 814 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c

@@ -0,0 +1,814 @@
+/*!
+    \file    gd32e230_fmc.c
+    \brief   FMC driver
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_fmc.h"
+
+/* FMC register bit offset */
+#define OB_HIGH_WP_OFFSET                 ((uint32_t)8U)
+#define FMC_OBSTAT_USER_OFFSET            ((uint32_t)8U)
+#define FMC_OBSTAT_DATA_OFFSET            ((uint32_t)16U)
+
+/*!
+    \brief      unlock the main FMC operation
+                it is better to used in pairs with fmc_lock
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fmc_unlock(void)
+{
+    if((RESET != (FMC_CTL & FMC_CTL_LK))){
+        /* write the FMC key */
+        FMC_KEY = UNLOCK_KEY0;
+        FMC_KEY = UNLOCK_KEY1;
+    }
+}
+
+/*!
+    \brief      lock the main FMC operation
+                it is better to used in pairs with fmc_unlock after an operation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fmc_lock(void)
+{
+    /* set the LK bit*/
+    FMC_CTL |= FMC_CTL_LK;
+}
+
+/*!
+    \brief      set the wait state counter value
+    \param[in]  wscnt: wait state counter value
+      \arg        WS_WSCNT_0: 0 wait state added
+      \arg        WS_WSCNT_1: 1 wait state added
+      \arg        WS_WSCNT_2: 2 wait state added
+    \param[out] none
+    \retval     none
+*/
+void fmc_wscnt_set(uint8_t wscnt)
+{
+    uint32_t reg;
+    
+    reg = FMC_WS;
+    /* set the wait state counter value */
+    reg &= ~FMC_WS_WSCNT;
+    FMC_WS = (reg | wscnt);
+}
+
+/*!
+    \brief      pre-fetch enable
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fmc_prefetch_enable(void)
+{
+    FMC_WS |= FMC_WS_PFEN;
+}
+
+/*!
+    \brief      pre-fetch disable
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fmc_prefetch_disable(void)
+{
+    FMC_WS &= ~FMC_WS_PFEN;
+}
+
+/*!
+    \brief      erase page
+    \param[in]  page_address: target page start address
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum fmc_page_erase(uint32_t page_address)
+{
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){ 
+        /* start page erase */
+        FMC_CTL |= FMC_CTL_PER;
+        FMC_ADDR = page_address;
+        FMC_CTL |= FMC_CTL_START;
+
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the PER bit */
+        FMC_CTL &= ~FMC_CTL_PER;
+    }
+    
+    /* return the FMC state  */
+    return fmc_state;
+}
+
+/*!
+    \brief      erase whole chip
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum fmc_mass_erase(void)
+{
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+  
+    if(FMC_READY == fmc_state){ 
+        /* start chip erase */
+        FMC_CTL |= FMC_CTL_MER; 
+        FMC_CTL |= FMC_CTL_START;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+        /* reset the MER bit */
+        FMC_CTL &= ~FMC_CTL_MER;
+    }
+    
+    /* return the fmc state  */
+    return fmc_state;
+}
+
+/*!
+    \brief      program a double word at the corresponding address in main flash, this 
+                function also applies to OTP(address 0x1FFF_7000~0x1FFF_73FF) programming
+    \param[in]  address: address to program
+    \param[in]  data: double word to program
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data)
+{
+    uint32_t data0, data1;
+    
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    data0 = (uint32_t)(data & 0xFFFFFFFFU);
+    data1 = (uint32_t)((data>>32U) & 0xFFFFFFFFU);
+    
+    /* configure program width */
+    FMC_WS |= FMC_WS_PGW;
+    if(FMC_READY == fmc_state){ 
+        /* set the PG bit to start program */
+        FMC_CTL |= FMC_CTL_PG; 
+        REG32(address) = data0;
+        REG32(address+4U) = data1;
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the PG bit */
+        FMC_CTL &= ~FMC_CTL_PG; 
+    }
+    FMC_WS &= ~(FMC_WS_PGW);
+  
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      program a word at the corresponding address in main flash, this function 
+                also applies to OTP(address 0x1FFF_7000~0x1FFF_73FF) programming
+    \param[in]  address: address to program
+    \param[in]  data: word to program
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum fmc_word_program(uint32_t address, uint32_t data)
+{
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+    if(FMC_READY == fmc_state){ 
+        /* set the PG bit to start program */
+        FMC_CTL |= FMC_CTL_PG; 
+  
+        REG32(address) = data;
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        /* reset the PG bit */
+        FMC_CTL &= ~FMC_CTL_PG; 
+    } 
+  
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      unlock the option byte operation
+                it is better to used in pairs with ob_lock
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ob_unlock(void)
+{
+    if(RESET == (FMC_CTL & FMC_CTL_OBWEN)){
+        /* write the FMC key */
+        FMC_OBKEY = UNLOCK_KEY0;
+        FMC_OBKEY = UNLOCK_KEY1;
+    }
+    /* wait until OBWEN bit is set by hardware */
+    while(RESET == (FMC_CTL & FMC_CTL_OBWEN)){
+    }
+}
+
+/*!
+    \brief      lock the option byte operation
+                it is better to used in pairs with ob_unlock after an operation
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ob_lock(void)
+{
+    /* reset the OBWE bit */
+    FMC_CTL &= ~FMC_CTL_OBWEN;
+}
+
+/*!
+    \brief      reload the option byte and generate a system reset
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ob_reset(void)
+{
+    /* set the OBRLD bit */
+    FMC_CTL |= FMC_CTL_OBRLD;
+}
+
+/*!
+    \brief      get option byte value
+    \param[in]  addr: address of option byte
+      \arg        OB_SPC_USER_ADDRESS: address of option byte security protection and user
+      \arg        OB_DATA_ADDRESS: address of option byte data
+      \arg        OB_WP_ADDRESS: address of option byte write protection
+    \param[out] option byte value
+*/
+uint32_t option_byte_value_get(uint32_t addr)
+{
+    return *(volatile uint32_t *)(addr);
+}
+
+/*!
+    \brief      erase the option byte
+                programmer must ensure FMC & option byte are both unlocked before calling this function
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum ob_erase(void)
+{
+    uint16_t fmc_spc;
+    uint32_t val;
+    uint32_t fmc_plevel = ob_obstat_plevel_get();
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+    /* get the original option byte security protection code */
+    if(OB_OBSTAT_PLEVEL_NO == fmc_plevel){
+        fmc_spc = FMC_NSPC;
+    }else if(OB_OBSTAT_PLEVEL_LOW == fmc_plevel){
+        fmc_spc = FMC_LSPC;
+    }else{
+        fmc_spc = FMC_HSPC;
+        fmc_state = FMC_OB_HSPC;
+    }
+    val = HIGH_16BITS_MASK | (uint32_t)fmc_spc;
+    
+    if(FMC_READY == fmc_state){
+        /* start erase the option byte */
+        FMC_CTL |= FMC_CTL_OBER;
+        FMC_CTL |= FMC_CTL_START;
+
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        if(FMC_READY == fmc_state){
+            /* reset the OBER bit */
+            FMC_CTL &= ~FMC_CTL_OBER;
+       
+            /* set the OBPG bit */
+            FMC_CTL |= FMC_CTL_OBPG;
+            
+            /* restore the last get option byte security protection code */
+            OB_SPC_USER = val;
+
+            /* wait for the FMC ready */
+            fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+ 
+            if(FMC_TOERR != fmc_state){
+                /* reset the OBPG bit */
+                FMC_CTL &= ~FMC_CTL_OBPG;
+            }
+        }else{
+            if(FMC_TOERR != fmc_state){
+                /* reset the OBPG bit */
+                FMC_CTL &= ~FMC_CTL_OBPG;
+            }
+        }  
+    }
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      enable option byte write protection (OB_WP)
+    \param[in]  ob_wp: write protection configuration data. Notice that set the
+                bit to 1 if you want to protect the corresponding pages.
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum ob_write_protection_enable(uint16_t ob_wp)
+{
+    uint32_t ob_wrp_val = 0U;
+
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+    ob_wp = (uint16_t)(~ob_wp);
+    ob_wrp_val |= (uint32_t)ob_wp&0x00FFU;
+    ob_wrp_val |= (((uint32_t)ob_wp&0xFF00U)>>8U) << 16U;
+    
+    if(FMC_READY == fmc_state){
+        /* set the OBPG bit*/
+        FMC_CTL |= FMC_CTL_OBPG;
+
+        if(0xFFFFFFFFU != ob_wrp_val){
+            OB_WP = ob_wrp_val;
+    
+            /* wait for the FMC ready */
+            fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+        }
+        if(FMC_TOERR != fmc_state){
+            /* reset the OBPG bit */
+            FMC_CTL &= ~FMC_CTL_OBPG;
+        }
+    } 
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      configure security protection
+    \param[in]  ob_spc: specify security protection code
+      \arg        FMC_NSPC: no security protection
+      \arg        FMC_LSPC: low security protection
+      \arg        FMC_HSPC: high security protection
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum ob_security_protection_config(uint16_t ob_spc)
+{
+    uint32_t val;
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+
+    val = option_byte_value_get(OB_SPC_USER_ADDRESS);
+    /* the OB_SPC byte cannot be reprogrammed if protection level is high */
+    if(OB_OBSTAT_PLEVEL_HIGH == ob_obstat_plevel_get()){
+        fmc_state = FMC_OB_HSPC;
+    }
+    
+    val &= ~LOW_16BITS_MASK;
+    val |= (uint32_t)ob_spc;
+
+    if(FMC_READY == fmc_state){
+        /* start erase the option byte */
+        FMC_CTL |= FMC_CTL_OBER;
+        FMC_CTL |= FMC_CTL_START;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        if(FMC_READY == fmc_state){
+        
+            /* reset the OBER bit */
+            FMC_CTL &= ~FMC_CTL_OBER;
+      
+            /* enable the option bytes programming */
+            FMC_CTL |= FMC_CTL_OBPG;
+       
+            OB_SPC_USER = val;
+
+            /* wait for the FMC ready */
+            fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); 
+    
+            if(FMC_TOERR != fmc_state){
+                /* reset the OBPG bit */
+                FMC_CTL &= ~FMC_CTL_OBPG;
+            }
+        }else{
+            if(FMC_TOERR != fmc_state){
+                /* reset the OBER bit */
+                FMC_CTL &= ~FMC_CTL_OBER;
+            }
+        }
+    }
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      program the FMC user option byte
+                this function can only clear the corresponding bits to be 0 rather than 1.
+                the function ob_erase is used to set all the bits to be 1.
+    \param[in]  ob_user: user option byte
+                one or more parameters (bitwise AND) can be selected which are shown as below:
+      \arg        OB_FWDGT_HW: hardware free watchdog timer
+      \arg        OB_DEEPSLEEP_RST: no reset when entering deepsleep mode
+      \arg        OB_STDBY_RST: no reset when entering standby mode
+      \arg        OB_BOOT1_SET_1: BOOT1 bit is 1
+      \arg        OB_VDDA_DISABLE: disable VDDA monitor
+      \arg        OB_SRAM_PARITY_ENABLE: enable sram parity check
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum ob_user_write(uint8_t ob_user)
+{
+    uint32_t val_spc_user;
+    /* check whether FMC is ready or not */
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+    val_spc_user = option_byte_value_get(OB_SPC_USER_ADDRESS);
+    
+    val_spc_user &= ~HIGH_16BITS_MASK;
+    
+    val_spc_user |= ((uint32_t)ob_user<<16U);
+    
+    if(FMC_READY == fmc_state){
+        /* start erase the option byte */
+        FMC_CTL |= FMC_CTL_OBER;
+        FMC_CTL |= FMC_CTL_START;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        if(FMC_READY == fmc_state){
+        
+            /* reset the OBER bit */
+            FMC_CTL &= ~FMC_CTL_OBER;
+      
+            /* enable the option bytes programming */
+            FMC_CTL |= FMC_CTL_OBPG;
+       
+            OB_SPC_USER = val_spc_user;
+            
+            /* wait for the FMC ready */
+            fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); 
+    
+            if(FMC_TOERR != fmc_state){
+                /* reset the OBPG bit */
+                FMC_CTL &= ~FMC_CTL_OBPG;
+            }
+        }else{
+            if(FMC_TOERR != fmc_state){
+                /* reset the OBER bit */
+                FMC_CTL &= ~FMC_CTL_OBER;
+            }
+        }
+    }
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      program the FMC data option byte
+    \param[in]  data: the data to be programmed, OB_DATA[0:15]
+    \param[out] none
+    \retval     fmc_state: state of FMC
+      \arg        FMC_READY: the operation has been completed
+      \arg        FMC_BUSY: the operation is in progress
+      \arg        FMC_PGERR: program error
+      \arg        FMC_PGAERR: program alignment error
+      \arg        FMC_WPERR: erase/program protection error
+      \arg        FMC_TOERR: timeout error
+      \arg        FMC_OB_HSPC: option byte security protection code high
+*/
+fmc_state_enum ob_data_program(uint16_t data)
+{
+    fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    uint32_t val = 0U;
+
+    val |= (uint32_t)data&0x00FFU;
+    val |= (((uint32_t)data&0xFF00U)>>8U) << 16U;
+    
+    if(FMC_READY == fmc_state){
+        /* set the OBPG bit */
+        FMC_CTL |= FMC_CTL_OBPG; 
+        OB_DATA = val;
+    
+        /* wait for the FMC ready */
+        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
+    
+        if(FMC_TOERR != fmc_state){
+            /* reset the OBPG bit */
+            FMC_CTL &= ~FMC_CTL_OBPG;
+        }
+    }
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      get OB_USER in register FMC_OBSTAT
+    \param[in]  none
+    \param[out] none
+    \retval     ob_user
+*/
+uint8_t ob_user_get(void)
+{
+    return (uint8_t)(FMC_OBSTAT >> FMC_OBSTAT_USER_OFFSET);
+}
+
+/*!
+    \brief      get OB_DATA in register FMC_OBSTAT
+    \param[in]  none
+    \param[out] none
+    \retval     ob_data
+*/
+uint16_t ob_data_get(void)
+{
+    return (uint16_t)(FMC_OBSTAT >> FMC_OBSTAT_DATA_OFFSET);
+}
+
+/*!
+    \brief      get the FMC option byte write protection (OB_WP) in register FMC_WP
+    \param[in]  none
+    \param[out] none
+    \retval     OB_WP
+*/
+uint16_t ob_write_protection_get(void)
+{
+    return (uint16_t)(FMC_WP);
+}
+
+/*!
+    \brief      get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register
+    \param[in]  none
+    \param[out] none
+    \retval     the value of PLEVEL
+*/
+uint32_t ob_obstat_plevel_get(void)
+{
+    return (FMC_OBSTAT & (FMC_OBSTAT_PLEVEL_BIT0 | FMC_OBSTAT_PLEVEL_BIT1));
+}
+
+/* FMC interrupts and flags management functions */
+/*!
+    \brief      enable FMC interrupt
+    \param[in]  interrupt: the FMC interrupt source
+      \arg        FMC_INTEN_END: FMC end of operation interrupt
+      \arg        FMC_INTEN_ERR: FMC error interrupt
+    \param[out] none
+    \retval     none
+*/
+void fmc_interrupt_enable(uint32_t interrupt)
+{
+    FMC_CTL |= interrupt;
+}
+
+/*!
+    \brief      disable FMC interrupt
+    \param[in]  interrupt: the FMC interrupt source
+      \arg        FMC_INTEN_END: FMC end of operation interrupt
+      \arg        FMC_INTEN_ERR: FMC error interrupt
+    \param[out] none
+    \retval     none
+*/
+void fmc_interrupt_disable(uint32_t interrupt)
+{
+    FMC_CTL &= ~(uint32_t)interrupt;
+}
+
+/*!
+    \brief      get flag set or reset
+    \param[in]  flag: check FMC flag
+                only one parameter can be selected which is shown as below:
+      \arg        FMC_FLAG_BUSY: FMC busy flag
+      \arg        FMC_FLAG_PGERR: FMC programming error flag
+      \arg        FMC_FLAG_PGAERR: FMC program alignment error flag
+      \arg        FMC_FLAG_WPERR: FMC write protection error flag
+      \arg        FMC_FLAG_END: FMC end of programming flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus fmc_flag_get(uint32_t flag)
+{
+    FlagStatus status = RESET;
+
+    if(FMC_STAT & flag){
+        status = SET;
+    }
+    /* return the state of corresponding FMC flag */
+    return status; 
+}
+
+/*!
+    \brief      clear the FMC pending flag by writing 1
+    \param[in]  flag: clear FMC flag
+                one or more parameters can be selected which is shown as below:
+      \arg        FMC_FLAG_PGERR: FMC programming error flag
+      \arg        FMC_FLAG_PGAERR: FMC program alignment error flag
+      \arg        FMC_FLAG_WPERR: FMC write protection error flag
+      \arg        FMC_FLAG_END: FMC end of programming flag
+    \param[out] none
+    \retval     none
+*/
+void fmc_flag_clear(uint32_t flag)
+{
+    /* clear the flags */
+    FMC_STAT = flag;
+}
+
+/*!
+    \brief      get intrrupt flag set or reset
+    \param[in]  flag: check FMC flag
+                only one parameter can be selected which is shown as below:
+      \arg        FMC_INT_FLAG_PGERR: FMC programming error flag
+      \arg        FMC_INT_FLAG_PGAERR: FMC program alignment error flag
+      \arg        FMC_INT_FLAG_WPERR: FMC write protection error flag
+      \arg        FMC_INT_FLAG_END: FMC end of programming flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus fmc_interrupt_flag_get(uint32_t int_flag)
+{
+    uint32_t intenable = 0U, flagstatus = 0U;
+    
+    if(FMC_INT_FLAG_END == int_flag){
+        /* get the interrupt enable bit status */
+        intenable = FMC_CTL & FMC_INTEN_END;
+        /* get the corresponding flag bit status */
+        flagstatus = FMC_STAT & int_flag;
+        if(intenable && flagstatus){
+            return SET;
+        }else{
+            return RESET;
+        }
+    }else{
+        /* get the interrupt enable bit status */
+        intenable = FMC_CTL & FMC_INTEN_ERR;
+        /* get the corresponding flag bit status */
+        flagstatus = FMC_STAT & int_flag;
+        if(intenable && flagstatus){
+            return SET;
+        }else{
+            return RESET;
+        }
+    }
+}
+
+/*!
+    \brief      clear the FMC interrupt pending flag by writing 1
+    \param[in]  flag: clear FMC flag
+                one or more parameters can be selected which is shown as below:
+      \arg        FMC_INT_FLAG_PGERR: FMC programming error flag
+      \arg        FMC_INT_FLAG_PGAERR: FMC program alignment error flag
+      \arg        FMC_INT_FLAG_WPERR: FMC write protection error flag
+      \arg        FMC_INT_FLAG_END: FMC end of programming flag
+    \param[out] none
+    \retval     none
+*/
+void fmc_interrupt_flag_clear(uint32_t int_flag)
+{
+    /* clear the flags */
+    FMC_STAT = int_flag;
+}
+
+/*!
+    \brief      get the FMC state
+    \param[in]  none
+    \param[out] none
+    \retval     fmc_state
+*/
+fmc_state_enum fmc_state_get(void)
+{
+    fmc_state_enum fmc_state = FMC_READY;
+  
+    if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)){
+        fmc_state = FMC_BUSY;
+    }else{
+        if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)){
+            fmc_state = FMC_WPERR;
+        }else{
+            if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)){
+                fmc_state = FMC_PGERR; 
+            }
+        }
+    }
+    /* return the FMC state */
+    return fmc_state;
+}
+
+/*!
+    \brief      check whether FMC is ready or not
+    \param[in]  timeout: timeout count
+    \param[out] none
+    \retval     fmc_state
+*/
+fmc_state_enum fmc_ready_wait(uint32_t timeout)
+{
+    fmc_state_enum fmc_state = FMC_BUSY;
+  
+    /* wait for FMC ready */
+    do{
+        /* get FMC state */
+        fmc_state = fmc_state_get();
+        timeout--;
+    }while((FMC_BUSY == fmc_state) && (0U != timeout));
+  
+    if(FMC_BUSY == fmc_state){
+        fmc_state = FMC_TOERR;
+    }
+    /* return the FMC state */
+    return fmc_state;
+}

+ 252 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c

@@ -0,0 +1,252 @@
+/*!
+    \file    gd32e230_fwdgt.c
+    \brief   FWDGT driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_fwdgt.h"
+
+/* write value to FWDGT_CTL_CMD bit field */
+#define CTL_CMD(regval)             (BITS(0,15) & ((uint32_t)(regval) << 0U))  /*!< write value to FWDGT_CTL_CMD bit field */
+/* write value to FWDGT_RLD_RLD bit field */
+#define RLD_RLD(regval)             (BITS(0,11) & ((uint32_t)(regval) << 0U))  /*!< write value to FWDGT_RLD_RLD bit field */
+/* write value to FWDGT_WND_WND bit field */
+#define WND_WND(regval)             (BITS(0,11) & ((uint32_t)(regval) << 0U))  /*!< write value to FWDGT_WND_WND bit field */
+
+/*!
+    \brief      enable write access to FWDGT_PSC and FWDGT_RLD
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_write_enable(void)
+{
+    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+}
+
+/*!
+    \brief      disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_write_disable(void)
+{
+    FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE;
+}
+
+/*!
+    \brief      start the free watchdog timer counter
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_enable(void)
+{
+    FWDGT_CTL = FWDGT_KEY_ENABLE;
+}
+
+/*!
+    \brief      configure the free watchdog timer counter prescaler value
+    \param[in]  prescaler_value: specify prescaler value
+                only one parameter can be selected which is shown as below:
+      \arg        FWDGT_PSC_DIV4: FWDGT prescaler set to 4
+      \arg        FWDGT_PSC_DIV8: FWDGT prescaler set to 8
+      \arg        FWDGT_PSC_DIV16: FWDGT prescaler set to 16
+      \arg        FWDGT_PSC_DIV32: FWDGT prescaler set to 32
+      \arg        FWDGT_PSC_DIV64: FWDGT prescaler set to 64
+      \arg        FWDGT_PSC_DIV128: FWDGT prescaler set to 128
+      \arg        FWDGT_PSC_DIV256: FWDGT prescaler set to 256
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value)
+{
+    uint32_t timeout = FWDGT_PSC_TIMEOUT;
+    uint32_t flag_status = RESET;
+  
+    /* enable write access to FWDGT_PSC */
+    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+  
+    /* wait until the PUD flag to be reset */
+    do{
+        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
+    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
+    
+    if ((uint32_t)RESET != flag_status){
+        return ERROR;
+    }
+    
+    /* configure FWDGT */
+    FWDGT_PSC = (uint32_t)prescaler_value; 
+
+    return SUCCESS;
+}
+
+/*!
+    \brief      configure the free watchdog timer counter reload value
+    \param[in]  reload_value: specify reload value(0x0000 - 0x0FFF)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus fwdgt_reload_value_config(uint16_t reload_value)
+{
+    uint32_t timeout = FWDGT_RLD_TIMEOUT;
+    uint32_t flag_status = RESET;
+  
+    /* enable write access to FWDGT_RLD */
+    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+  
+    /* wait until the RUD flag to be reset */
+    do{
+        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
+    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
+   
+    if ((uint32_t)RESET != flag_status){
+        return ERROR;
+    }
+    
+    FWDGT_RLD = RLD_RLD(reload_value);
+
+    return SUCCESS;
+}
+
+/*!
+    \brief      configure the free watchdog timer counter window value
+    \param[in]  window_value: specify window value(0x0000 - 0x0FFF)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus fwdgt_window_value_config(uint16_t window_value)
+{
+    uint32_t time_index = FWDGT_WND_TIMEOUT;
+    uint32_t flag_status = RESET;
+
+    /* enable write access to FWDGT_WND */
+    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+
+    /* wait until the WUD flag to be reset */
+    do{
+        flag_status = FWDGT_STAT & FWDGT_STAT_WUD;
+    }while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
+
+    if ((uint32_t)RESET != flag_status){
+        return ERROR; 
+    }
+    
+    FWDGT_WND = WND_WND(window_value);
+
+    return SUCCESS;
+}
+
+/*!
+    \brief      reload the counter of FWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void fwdgt_counter_reload(void)
+{
+    FWDGT_CTL = FWDGT_KEY_RELOAD;
+}
+
+/*!
+    \brief      configure counter reload value, and prescaler divider value
+    \param[in]  reload_value: specify reload value(0x0000 - 0x0FFF)
+    \param[in]  prescaler_div: FWDGT prescaler value
+                only one parameter can be selected which is shown as below:
+      \arg        FWDGT_PSC_DIV4: FWDGT prescaler set to 4
+      \arg        FWDGT_PSC_DIV8: FWDGT prescaler set to 8
+      \arg        FWDGT_PSC_DIV16: FWDGT prescaler set to 16
+      \arg        FWDGT_PSC_DIV32: FWDGT prescaler set to 32
+      \arg        FWDGT_PSC_DIV64: FWDGT prescaler set to 64
+      \arg        FWDGT_PSC_DIV128: FWDGT prescaler set to 128
+      \arg        FWDGT_PSC_DIV256: FWDGT prescaler set to 256
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div)
+{
+    uint32_t timeout = FWDGT_PSC_TIMEOUT;
+    uint32_t flag_status = RESET;
+  
+    /* enable write access to FWDGT_PSC,and FWDGT_RLD */
+    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
+  
+    /* wait until the PUD flag to be reset */
+    do{
+        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
+    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
+    
+    if ((uint32_t)RESET != flag_status){
+        return ERROR;
+    }
+    
+    /* configure FWDGT */
+    FWDGT_PSC = (uint32_t)prescaler_div;       
+
+    timeout = FWDGT_RLD_TIMEOUT;    
+    /* wait until the RUD flag to be reset */
+    do{
+        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
+    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
+   
+    if ((uint32_t)RESET != flag_status){
+        return ERROR;
+    }
+    
+    FWDGT_RLD = RLD_RLD(reload_value);
+    
+    /* reload the counter */
+    FWDGT_CTL = FWDGT_KEY_RELOAD;
+    
+    return SUCCESS;
+}
+
+/*!
+    \brief      get flag state of FWDGT
+    \param[in]  flag: flag to get 
+                only one parameter can be selected which is shown as below:
+      \arg        FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going
+      \arg        FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going
+      \arg        FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus fwdgt_flag_get(uint16_t flag)
+{
+    if(RESET != (FWDGT_STAT & flag)){
+        return SET;
+    }
+    return RESET;
+}

+ 399 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c

@@ -0,0 +1,399 @@
+/*!
+    \file    gd32e230_gpio.c
+    \brief   GPIO driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_gpio.h"
+
+/*!
+    \brief      reset GPIO port
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F)
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[out] none
+    \retval     none
+*/
+void gpio_deinit(uint32_t gpio_periph)
+{
+    switch(gpio_periph){
+    case GPIOA:
+        /* reset GPIOA */
+        rcu_periph_reset_enable(RCU_GPIOARST);
+        rcu_periph_reset_disable(RCU_GPIOARST);
+        break;
+    case GPIOB:
+        /* reset GPIOB */
+        rcu_periph_reset_enable(RCU_GPIOBRST);
+        rcu_periph_reset_disable(RCU_GPIOBRST);
+        break;
+    case GPIOC:
+        /* reset GPIOC */
+        rcu_periph_reset_enable(RCU_GPIOCRST);
+        rcu_periph_reset_disable(RCU_GPIOCRST);
+        break;
+    case GPIOF:
+        /* reset GPIOF */
+        rcu_periph_reset_enable(RCU_GPIOFRST);
+        rcu_periph_reset_disable(RCU_GPIOFRST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      set GPIO mode
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  mode: gpio pin mode
+      \arg        GPIO_MODE_INPUT: input mode
+      \arg        GPIO_MODE_OUTPUT: output mode
+      \arg        GPIO_MODE_AF: alternate function mode
+      \arg        GPIO_MODE_ANALOG: analog mode
+    \param[in]  pull_up_down: gpio pin with pull-up or pull-down resistor
+      \arg        GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors
+      \arg        GPIO_PUPD_PULLUP: with pull-up resistor
+      \arg        GPIO_PUPD_PULLDOWN:with pull-down resistor
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
+{
+    uint16_t i;
+    uint32_t ctl, pupd;
+
+    ctl = GPIO_CTL(gpio_periph);
+    pupd = GPIO_PUD(gpio_periph);
+
+    for(i = 0U;i < 16U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin mode bits */
+            ctl &= ~GPIO_MODE_MASK(i);
+            /* set the specified pin mode bits */
+            ctl |= GPIO_MODE_SET(i, mode);
+
+            /* clear the specified pin pupd bits */
+            pupd &= ~GPIO_PUPD_MASK(i);
+            /* set the specified pin pupd bits */
+            pupd |= GPIO_PUPD_SET(i, pull_up_down);
+        }
+    }
+
+    GPIO_CTL(gpio_periph) = ctl;
+    GPIO_PUD(gpio_periph) = pupd;
+}
+
+/*!
+    \brief      set GPIO output type and speed
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  otype: gpio pin output mode
+      \arg        GPIO_OTYPE_PP: push pull mode
+      \arg        GPIO_OTYPE_OD: open drain mode
+    \param[in]  speed: gpio pin output max speed
+      \arg        GPIO_OSPEED_2MHZ: output max speed 2MHz 
+      \arg        GPIO_OSPEED_10MHZ: output max speed 10MHz 
+      \arg        GPIO_OSPEED_50MHZ: output max speed 50MHz
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)
+{
+    uint16_t i;
+    uint32_t ospeed;
+
+    if(GPIO_OTYPE_OD == otype){
+        GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
+    }else{
+        GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
+    }
+
+    /* get the specified pin output speed bits value */
+    ospeed = GPIO_OSPD(gpio_periph);
+
+    for(i = 0U;i < 16U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin output speed bits */
+            ospeed &= ~GPIO_OSPEED_MASK(i);
+            /* set the specified pin output speed bits */
+            ospeed |= GPIO_OSPEED_SET(i,speed);
+        }
+    }
+    GPIO_OSPD(gpio_periph) = ospeed;
+}
+
+/*!
+    \brief      set GPIO pin bit
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
+{
+    GPIO_BOP(gpio_periph) = (uint32_t)pin;
+}
+
+/*!
+    \brief      reset GPIO pin bit
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
+{
+    GPIO_BC(gpio_periph) = (uint32_t)pin;
+}
+
+/*!
+    \brief      write data to the specified GPIO pin
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[in]  bit_value: SET or RESET
+      \arg        RESET: clear the port pin
+      \arg        SET: set the port pin
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
+{
+    if(RESET != bit_value){
+        GPIO_BOP(gpio_periph) = (uint32_t)pin;
+    }else{
+        GPIO_BC(gpio_periph) = (uint32_t)pin;
+    }
+}
+
+/*!
+    \brief      write data to the specified GPIO port
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  data: specify the value to be written to the port output control register
+    \param[out] none
+    \retval     none
+*/
+void gpio_port_write(uint32_t gpio_periph, uint16_t data)
+{
+    GPIO_OCTL(gpio_periph) = (uint32_t)data;
+}
+
+/*!
+    \brief      get GPIO pin input status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     SET or RESET
+*/
+FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin)
+{
+    if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
+        return SET; 
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      get GPIO all pins input status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[out] none
+    \retval     state of GPIO all pins
+*/
+uint16_t gpio_input_port_get(uint32_t gpio_periph)
+{
+    return (uint16_t)GPIO_ISTAT(gpio_periph);
+}
+
+/*!
+    \brief      get GPIO pin output status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     SET or RESET
+*/
+FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
+{
+    if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      get GPIO all pins output status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[out] none
+    \retval     state of GPIO all pins
+*/
+uint16_t gpio_output_port_get(uint32_t gpio_periph)
+{
+    return (uint16_t)GPIO_OCTL(gpio_periph);
+}
+
+/*!
+    \brief      set GPIO alternate function
+    \param[in]  gpio_periph: GPIOx(x = A,B,C) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C) 
+    \param[in]  alt_func_num: GPIO pin af function, please refer to specific device datasheet
+      \arg        GPIO_AF_0: TIMER13, TIMER14, TIMER16, SPI0, SPI1, I2S0, CK_OUT, USART0,
+                              I2C0, I2C1, SWDIO, SWCLK
+      \arg        GPIO_AF_1: USART0, USART1, TIMER2, TIMER14, I2C0, I2C1
+      \arg        GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, I2S0
+      \arg        GPIO_AF_3: I2C0, TIMER14
+      \arg        GPIO_AF_4(port A,B only): USART1, I2C0, I2C1, TIMER13
+      \arg        GPIO_AF_5(port A,B only): TIMER15, TIMER16, I2S0
+      \arg        GPIO_AF_6(port A,B only): SPI1
+      \arg        GPIO_AF_7(port A,B only): CMP
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin)
+{
+    uint16_t i;
+    uint32_t afrl, afrh;
+
+    afrl = GPIO_AFSEL0(gpio_periph);
+    afrh = GPIO_AFSEL1(gpio_periph);
+
+    for(i = 0U;i < 8U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin alternate function bits */
+            afrl &= ~GPIO_AFR_MASK(i);
+            afrl |= GPIO_AFR_SET(i,alt_func_num);
+        }
+    }
+
+    for(i = 8U;i < 16U;i++){
+        if((1U << i) & pin){
+            /* clear the specified pin alternate function bits */
+            afrh &= ~GPIO_AFR_MASK(i - 8U);
+            afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
+        }
+    }
+
+    GPIO_AFSEL0(gpio_periph) = afrl;
+    GPIO_AFSEL1(gpio_periph) = afrh;
+}
+
+/*!
+    \brief      lock GPIO pin bit
+    \param[in]  gpio_periph: GPIOx(x = A,B) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
+{
+    uint32_t lock = 0x00010000U;
+    lock |= pin;
+
+    /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */
+    GPIO_LOCK(gpio_periph) = (uint32_t)lock;
+    GPIO_LOCK(gpio_periph) = (uint32_t)pin;
+    GPIO_LOCK(gpio_periph) = (uint32_t)lock;
+    lock = GPIO_LOCK(gpio_periph);
+    lock = GPIO_LOCK(gpio_periph);
+}
+
+/*!
+    \brief      toggle GPIO pin status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F) 
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[in]  pin: GPIO pin
+                one or more parameters can be selected which are shown as below:
+      \arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
+    \param[out] none
+    \retval     none
+*/
+void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin)
+{
+    GPIO_TG(gpio_periph) = (uint32_t)pin;
+}
+
+/*!
+    \brief      toggle GPIO port status
+    \param[in]  gpio_periph: GPIOx(x = A,B,C,F)
+                only one parameter can be selected which is shown as below:
+      \arg        GPIOx(x = A,B,C,F) 
+    \param[out] none
+    \retval     none
+*/
+void gpio_port_toggle(uint32_t gpio_periph)
+{
+    GPIO_TG(gpio_periph) = 0x0000FFFFU;
+}

+ 797 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c

@@ -0,0 +1,797 @@
+/*!
+    \file    gd32e230_i2c.c
+    \brief   I2C driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_i2c.h"
+
+/* I2C register bit mask */
+#define I2CCLK_MAX                    ((uint32_t)0x0000007FU)             /*!< i2cclk maximum value */
+#define I2CCLK_MIN                    ((uint32_t)0x00000002U)             /*!< i2cclk minimum value */
+#define I2C_FLAG_MASK                 ((uint32_t)0x0000FFFFU)             /*!< i2c flag mask */
+#define I2C_ADDRESS_MASK              ((uint32_t)0x000003FFU)             /*!< i2c address mask */
+#define I2C_ADDRESS2_MASK             ((uint32_t)0x000000FEU)             /*!< the second i2c address mask */
+
+/* I2C register bit offset */
+#define STAT1_PECV_OFFSET             ((uint32_t)8U)     /* bit offset of PECV in I2C_STAT1 */
+
+/*!
+    \brief      reset I2C
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_deinit(uint32_t i2c_periph)
+{
+    switch(i2c_periph){
+    case I2C0:
+        /* reset I2C0 */
+        rcu_periph_reset_enable(RCU_I2C0RST);
+        rcu_periph_reset_disable(RCU_I2C0RST);
+        break;
+    case I2C1:
+        /* reset I2C1 */
+        rcu_periph_reset_enable(RCU_I2C1RST);
+        rcu_periph_reset_disable(RCU_I2C1RST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure I2C clock
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
+                          and fast mode plus (up to 1MHz)
+    \param[in]  dutycyc: duty cycle in fast mode or fast mode plus
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_DTCY_2: T_low/T_high=2 
+      \arg        I2C_DTCY_16_9: T_low/T_high=16/9
+    \param[out] none
+    \retval     none
+*/
+void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc)
+{
+    uint32_t pclk1, clkc, freq, risetime;
+    uint32_t temp;
+    
+    pclk1 = rcu_clock_freq_get(CK_APB1);
+    /* I2C peripheral clock frequency */
+    freq = (uint32_t)(pclk1/1000000U);
+    if(freq >= I2CCLK_MAX){
+        freq = I2CCLK_MAX;
+    }
+    temp = I2C_CTL1(i2c_periph);
+    temp &= ~I2C_CTL1_I2CCLK;
+    temp |= freq;
+    
+    I2C_CTL1(i2c_periph) = temp;
+    
+    if(100000U >= clkspeed){
+        /* the maximum SCL rise time is 1000ns in standard mode */
+        risetime = (uint32_t)((pclk1/1000000U)+1U);
+        if(risetime >= I2CCLK_MAX){
+            I2C_RT(i2c_periph) = I2CCLK_MAX;
+        }else if(risetime <= I2CCLK_MIN){
+            I2C_RT(i2c_periph) = I2CCLK_MIN;
+        }else{
+            I2C_RT(i2c_periph) = risetime;
+        }
+        clkc = (uint32_t)(pclk1/(clkspeed*2U)); 
+        if(clkc < 0x04U){
+            /* the CLKC in standard mode minmum value is 4 */
+            clkc = 0x04U;
+        }
+        I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc);
+
+    }else if(400000U >= clkspeed){
+        /* the maximum SCL rise time is 300ns in fast mode */
+        I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U);
+        if(I2C_DTCY_2 == dutycyc){
+            /* I2C duty cycle is 2 */
+            clkc = (uint32_t)(pclk1/(clkspeed*3U));
+            I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
+        }else{
+            /* I2C duty cycle is 16/9 */
+            clkc = (uint32_t)(pclk1/(clkspeed*25U));
+            I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
+        }
+        if(0U == (clkc & I2C_CKCFG_CLKC)){
+            /* the CLKC in fast mode minmum value is 1 */
+            clkc |= 0x0001U;  
+        }
+        I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
+        I2C_CKCFG(i2c_periph) |= clkc;
+    }else{
+        /* fast mode plus, the maximum SCL rise time is 120ns */
+        I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)120U)/(uint32_t)1000U)+(uint32_t)1U);
+        if(I2C_DTCY_2 == dutycyc){
+            /* I2C duty cycle is 2 */
+            clkc = (uint32_t)(pclk1/(clkspeed*3U));
+            I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
+        }else{
+            /* I2C duty cycle is 16/9 */
+            clkc = (uint32_t)(pclk1/(clkspeed*25U));
+            I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
+        }
+        /* enable fast mode */
+        I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
+        I2C_CKCFG(i2c_periph) |= clkc;
+        /* enable I2C fast mode plus */
+        I2C_FMPCFG(i2c_periph) = I2C_FMPCFG_FMPEN;
+    }
+}
+
+/*!
+    \brief      configure I2C address 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  mode:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_I2CMODE_ENABLE: I2C mode
+      \arg        I2C_SMBUSMODE_ENABLE: SMBus mode
+    \param[in]  addformat: 7bits or 10bits
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_ADDFORMAT_7BITS: 7bits
+      \arg        I2C_ADDFORMAT_10BITS: 10bits
+    \param[in]  addr: I2C address
+    \param[out] none
+    \retval     none
+*/
+void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr)
+{
+    /* SMBus/I2C mode selected */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SMBEN); 
+    ctl |= mode;
+    I2C_CTL0(i2c_periph) = ctl;
+    /* configure address */
+    addr = addr & I2C_ADDRESS_MASK;
+    I2C_SADDR0(i2c_periph) = (addformat | addr);
+}
+
+/*!
+    \brief      SMBus type selection
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  type:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_SMBUS_DEVICE: device
+      \arg        I2C_SMBUS_HOST: host
+    \param[out] none
+    \retval     none
+*/
+void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type)
+{
+    if(I2C_SMBUS_HOST == type){
+        I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL;
+    }else{
+        I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL);
+    }
+}
+
+/*!
+    \brief      whether or not to send an ACK
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  ack:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_ACK_ENABLE: ACK will be sent
+      \arg        I2C_ACK_DISABLE: ACK will not be sent
+    \param[out] none
+    \retval     none
+*/
+void i2c_ack_config(uint32_t i2c_periph, uint32_t ack)
+{
+    if(I2C_ACK_ENABLE == ack){
+        I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN;
+    }else{
+        I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN);
+    }
+}
+
+/*!
+    \brief      configure I2C POAP position
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  pos:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_ACKPOS_CURRENT: whether to send ACK or not for the current
+      \arg        I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte
+    \param[out] none
+    \retval     none
+*/
+void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos)
+{
+    /* configure I2C POAP position */
+    if(I2C_ACKPOS_NEXT == pos){
+        I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP;
+    }else{
+        I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP);
+    }
+}
+
+/*!
+    \brief      master sends slave address
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  addr: slave address  
+    \param[in]  trandirection: transmitter or receiver
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_TRANSMITTER: transmitter  
+      \arg        I2C_RECEIVER:    receiver  
+    \param[out] none
+    \retval     none
+*/
+void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection)
+{
+    /* master is a transmitter or a receiver */
+    if(I2C_TRANSMITTER == trandirection){
+        addr = addr & I2C_TRANSMITTER;
+    }else{
+        addr = addr | I2C_RECEIVER;
+    }
+    /* send slave address */
+    I2C_DATA(i2c_periph) = addr;
+}
+
+/*!
+    \brief      enable dual-address mode
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  addr: the second address in dual-address mode
+    \param[out] none
+    \retval     none
+*/
+void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr)
+{
+    /* configure address */
+    addr = addr & I2C_ADDRESS2_MASK;
+    I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr);
+}
+
+/*!
+    \brief      disable dual-address mode
+    \param[in]  i2c_periph: I2Cx(x=0,1) 
+    \param[out] none
+    \retval     none
+*/
+void i2c_dualaddr_disable(uint32_t i2c_periph)
+{
+    I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN);
+}
+
+/*!
+    \brief      enable I2C
+    \param[in]  i2c_periph: I2Cx(x=0,1) 
+    \param[out] none
+    \retval     none
+*/
+void i2c_enable(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
+}
+
+/*!
+    \brief      disable I2C
+    \param[in]  i2c_periph: I2Cx(x=0,1) 
+    \param[out] none
+    \retval     none
+*/
+void i2c_disable(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN);
+}
+
+/*!
+    \brief      generate a START condition on I2C bus
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_start_on_bus(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) |= I2C_CTL0_START;
+}
+
+/*!
+    \brief      generate a STOP condition on I2C bus
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_stop_on_bus(uint32_t i2c_periph)
+{
+    I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP;
+}
+
+/*!
+    \brief      I2C transmit data function
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  data: data of transmission 
+    \param[out] none
+    \retval     none
+*/
+void i2c_data_transmit(uint32_t i2c_periph, uint8_t data)
+{
+    I2C_DATA(i2c_periph) = DATA_TRANS(data);
+}
+
+/*!
+    \brief      I2C receive data function
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     data of received
+*/
+uint8_t i2c_data_receive(uint32_t i2c_periph)
+{
+    return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph));
+}
+
+/*!
+    \brief      enable I2C DMA mode 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  dmastate:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_DMA_ON: DMA mode enable
+      \arg        I2C_DMA_OFF: DMA mode disable
+    \param[out] none
+    \retval     none
+*/
+void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate)
+{
+    /* configure I2C DMA function */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL1(i2c_periph);
+    ctl &= ~(I2C_CTL1_DMAON); 
+    ctl |= dmastate;
+    I2C_CTL1(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      configure whether next DMA EOT is DMA last transfer or not
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  dmalast:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_DMALST_ON: next DMA EOT is the last transfer
+      \arg        I2C_DMALST_OFF: next DMA EOT is not the last transfer
+    \param[out] none
+    \retval     none
+*/
+void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast)
+{
+    /* configure DMA last transfer */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL1(i2c_periph);
+    ctl &= ~(I2C_CTL1_DMALST); 
+    ctl |= dmalast;
+    I2C_CTL1(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      whether to stretch SCL low when data is not ready in slave mode 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  stretchpara:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled
+      \arg        I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled
+    \param[out] none
+    \retval     none
+*/
+void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara)
+{
+    /* configure I2C SCL strerching enable or disable */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SS); 
+    ctl |= stretchpara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      whether or not to response to a general call 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  gcallpara:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_GCEN_ENABLE: slave will response to a general call
+      \arg        I2C_GCEN_DISABLE: slave will not response to a general call
+    \param[out] none
+    \retval     none
+*/
+void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara)
+{
+    /* configure slave response to a general call enable or disable */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_GCEN); 
+    ctl |= gcallpara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      software reset I2C 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  sreset:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_SRESET_SET: I2C is under reset
+      \arg        I2C_SRESET_RESET: I2C is not under reset
+    \param[out] none
+    \retval     none
+*/
+void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset)
+{
+    /* modify CTL0 and configure software reset I2C state */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SRESET); 
+    ctl |= sreset;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      I2C PEC calculation on or off
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  pecpara:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_PEC_ENABLE: PEC calculation on 
+      \arg        I2C_PEC_DISABLE: PEC calculation off 
+    \param[out] none
+    \retval     none
+*/
+void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate)
+{
+    /* on/off PEC calculation */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_PECEN);
+    ctl |= pecstate;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      I2C whether to transfer PEC value
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  pecpara:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_PECTRANS_ENABLE: transfer PEC 
+      \arg        I2C_PECTRANS_DISABLE: not transfer PEC 
+    \param[out] none
+    \retval     none
+*/
+void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara)
+{
+    /* whether to transfer PEC */
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_PECTRANS);
+    ctl |= pecpara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      get packet error checking value 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     PEC value
+*/
+uint8_t i2c_pec_value_get(uint32_t i2c_periph)
+{
+    return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV)>>STAT1_PECV_OFFSET);
+}
+
+/*!
+    \brief      I2C issue alert through SMBA pin 
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  smbuspara:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_SALTSEND_ENABLE: issue alert through SMBA pin 
+      \arg        I2C_SALTSEND_DISABLE: not issue alert through SMBA pin 
+    \param[out] none
+    \retval     none
+*/
+void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara)
+{
+    /* issue alert through SMBA pin configure*/
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_SALT);
+    ctl |= smbuspara;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      enable or disable I2C ARP protocol in SMBus switch
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  smbuspara:
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_ARP_ENABLE: enable ARP
+      \arg        I2C_ARP_DISABLE: disable ARP
+    \param[out] none
+    \retval     none
+*/
+void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate)
+{
+    /* enable or disable I2C ARP protocol*/
+    uint32_t ctl = 0U;
+    
+    ctl = I2C_CTL0(i2c_periph);
+    ctl &= ~(I2C_CTL0_ARPEN);
+    ctl |= arpstate;
+    I2C_CTL0(i2c_periph) = ctl;
+}
+
+/*!
+    \brief      enable SAM_V interface
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_enable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN;
+}
+
+/*!
+    \brief      disable SAM_V interface
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_disable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN);
+}
+
+/*!
+    \brief      enable SAM_V interface timeout detect
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_timeout_enable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN;
+}
+
+/*!
+    \brief      disable SAM_V interface timeout detect
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void i2c_sam_timeout_disable(uint32_t i2c_periph)
+{
+    I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN);
+}
+
+/*!
+    \brief      check I2C flag is set or not
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  flag: I2C flags, refer to i2c_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_FLAG_SBSEND: start condition send out 
+      \arg        I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
+      \arg        I2C_FLAG_BTC: byte transmission finishes
+      \arg        I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode
+      \arg        I2C_FLAG_STPDET: stop condition detected in slave mode
+      \arg        I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving
+      \arg        I2C_FLAG_TBE: I2C_DATA is empty during transmitting
+      \arg        I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
+      \arg        I2C_FLAG_LOSTARB: arbitration lost in master mode
+      \arg        I2C_FLAG_AERR: acknowledge error
+      \arg        I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode
+      \arg        I2C_FLAG_PECERR: PEC error when receiving data
+      \arg        I2C_FLAG_SMBTO: timeout signal in SMBus mode
+      \arg        I2C_FLAG_SMBALT: SMBus alert status
+      \arg        I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode
+      \arg        I2C_FLAG_I2CBSY: busy flag
+      \arg        I2C_FLAG_TR: whether the I2C is a transmitter or a receiver
+      \arg        I2C_FLAG_RXGC: general call address (00h) received
+      \arg        I2C_FLAG_DEFSMB: default address of SMBus device
+      \arg        I2C_FLAG_HSTSMB: SMBus host header detected in slave mode
+      \arg        I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode
+      \arg        I2C_FLAG_TFF: txframe fall flag
+      \arg        I2C_FLAG_TFR: txframe rise flag
+      \arg        I2C_FLAG_RFF: rxframe fall flag
+      \arg        I2C_FLAG_RFR: rxframe rise flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag)
+{
+    if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear I2C flag
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  flag: I2C flags, refer to i2c_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg       I2C_FLAG_SMBALT: SMBus Alert status
+      \arg       I2C_FLAG_SMBTO: timeout signal in SMBus mode
+      \arg       I2C_FLAG_PECERR: PEC error when receiving data
+      \arg       I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode    
+      \arg       I2C_FLAG_AERR: acknowledge error
+      \arg       I2C_FLAG_LOSTARB: arbitration lost in master mode   
+      \arg       I2C_FLAG_BERR: a bus error   
+      \arg       I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1
+      \arg       I2C_FLAG_TFF: txframe fall flag
+      \arg       I2C_FLAG_TFR: txframe rise flag
+      \arg       I2C_FLAG_RFF: rxframe fall flag
+      \arg       I2C_FLAG_RFR: rxframe rise flag
+    \param[out] none
+    \retval     none
+*/
+void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag)
+{
+    if(I2C_FLAG_ADDSEND == flag){
+        /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
+        I2C_STAT0(i2c_periph);
+        I2C_STAT1(i2c_periph);
+    }else{
+        I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag));
+    }
+}
+
+/*!
+    \brief      enable I2C interrupt
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  interrupt: I2C interrupts, refer to i2c_interrupt_enum
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_INT_ERR: error interrupt enable 
+      \arg        I2C_INT_EV: event interrupt enable 
+      \arg        I2C_INT_BUF: buffer interrupt enable
+      \arg        I2C_INT_TFF: txframe fall interrupt enable
+      \arg        I2C_INT_TFR: txframe rise interrupt enable
+      \arg        I2C_INT_RFF: rxframe fall interrupt enable
+      \arg        I2C_INT_RFR: rxframe rise interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
+{
+    I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt));
+}
+
+/*!
+    \brief      disable I2C interrupt
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  interrupt: I2C interrupts, refer to i2c_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_INT_ERR: error interrupt enable 
+      \arg        I2C_INT_EV: event interrupt enable 
+      \arg        I2C_INT_BUF: buffer interrupt enable
+      \arg        I2C_INT_TFF: txframe fall interrupt enable
+      \arg        I2C_INT_TFR: txframe rise interrupt enable
+      \arg        I2C_INT_RFF: rxframe fall interrupt enable
+      \arg        I2C_INT_RFR: rxframe rise interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
+{
+    I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt));
+}
+
+/*!
+    \brief      check I2C interrupt flag
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag
+      \arg        I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
+      \arg        I2C_INT_FLAG_BTC: byte transmission finishes
+      \arg        I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
+      \arg        I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag
+      \arg        I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
+      \arg        I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
+      \arg        I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
+      \arg        I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
+      \arg        I2C_INT_FLAG_AERR: acknowledge error interrupt flag
+      \arg        I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
+      \arg        I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
+      \arg        I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
+      \arg        I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
+      \arg        I2C_INT_FLAG_TFF: txframe fall interrupt flag
+      \arg        I2C_INT_FLAG_TFR: txframe rise interrupt flag
+      \arg        I2C_INT_FLAG_RFF: rxframe fall interrupt flag
+      \arg        I2C_INT_FLAG_RFR: rxframe rise interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
+{
+    uint32_t intenable = 0U, flagstatus = 0U, bufie;
+    
+    /* check BUFIE */
+    bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
+    
+    /* get the interrupt enable bit status */
+    intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
+    /* get the corresponding flag bit status */
+    flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));
+
+    if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)){
+        if(intenable && bufie){
+            intenable = 1U;
+        }else{
+            intenable = 0U;
+        }
+    }
+    if((0U != flagstatus) && (0U != intenable)){
+        return SET;
+    }else{
+        return RESET; 
+    }
+}
+
+/*!
+    \brief      clear I2C interrupt flag
+    \param[in]  i2c_periph: I2Cx(x=0,1)
+    \param[in]  intflag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
+      \arg        I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
+      \arg        I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
+      \arg        I2C_INT_FLAG_AERR: acknowledge error interrupt flag
+      \arg        I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
+      \arg        I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
+      \arg        I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
+      \arg        I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
+      \arg        I2C_INT_FLAG_TFF: txframe fall interrupt flag
+      \arg        I2C_INT_FLAG_TFR: txframe rise interrupt flag
+      \arg        I2C_INT_FLAG_RFF: rxframe fall interrupt flag
+      \arg        I2C_INT_FLAG_RFR: rxframe rise interrupt flag
+    \param[out] none
+    \retval     none
+*/
+void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
+{
+    if(I2C_INT_FLAG_ADDSEND == int_flag){
+        /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
+        I2C_STAT0(i2c_periph);
+        I2C_STAT1(i2c_periph);
+    }else{
+        I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag));
+    }
+}

+ 142 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c

@@ -0,0 +1,142 @@
+/*!
+    \file    gd32e230_misc.c
+    \brief   MISC driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_misc.h"
+
+/*!
+    \brief      enable NVIC request
+    \param[in]  nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
+    \param[in]  nvic_irq_priority: the priority needed to set (0-3)
+    \param[out] none
+    \retval     none
+*/
+void nvic_irq_enable(uint8_t nvic_irq, 
+                     uint8_t nvic_irq_priority)
+{
+    /* set the priority and enable the selected IRQ */
+    NVIC_SetPriority((IRQn_Type)nvic_irq, (uint32_t)nvic_irq_priority);
+    NVIC_EnableIRQ((IRQn_Type)nvic_irq);
+}
+
+/*!
+    \brief      disable NVIC request
+    \param[in]  nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
+    \param[out] none
+    \retval     none
+*/
+void nvic_irq_disable(uint8_t nvic_irq)
+{
+    /* disable the selected IRQ.*/
+    NVIC_DisableIRQ((IRQn_Type)nvic_irq);
+}
+
+/*  */
+/*!
+    \brief      initiates a system reset request to reset the MCU
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void nvic_system_reset(void)
+{
+    NVIC_SystemReset();
+}
+
+/*!
+    \brief      set the NVIC vector table base address
+    \param[in]  nvic_vict_tab: the RAM or FLASH base address
+      \arg        NVIC_VECTTAB_RAM: RAM base address
+      \arg        NVIC_VECTTAB_FLASH: Flash base address
+    \param[in]  offset: Vector Table offset
+    \param[out] none
+    \retval     none
+*/
+void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset)
+{
+    SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK);
+}
+
+/*!
+    \brief      set the state of the low power mode
+    \param[in]  lowpower_mode: the low power mode state
+      \arg        SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power 
+                    mode by exiting from ISR
+      \arg        SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode
+      \arg        SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up 
+                    by all the enable and disable interrupts
+    \param[out] none
+    \retval     none
+*/
+void system_lowpower_set(uint8_t lowpower_mode)
+{
+    SCB->SCR |= (uint32_t)lowpower_mode;
+}
+
+/*!
+    \brief      reset the state of the low power mode
+    \param[in]  lowpower_mode: the low power mode state
+      \arg        SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power 
+                    mode by exiting from ISR
+      \arg        SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode
+      \arg        SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be 
+                    woke up by the enable interrupts
+    \param[out] none
+    \retval     none
+*/
+void system_lowpower_reset(uint8_t lowpower_mode)
+{
+    SCB->SCR &= (~(uint32_t)lowpower_mode);
+}
+
+/*!
+    \brief      set the systick clock source
+    \param[in]  systick_clksource: the systick clock source needed to choose
+      \arg        SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK
+      \arg        SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8
+    \param[out] none
+    \retval     none
+*/
+
+void systick_clksource_set(uint32_t systick_clksource)
+{
+    if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){
+        /* set the systick clock source from HCLK */
+        SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
+    }else{
+        /* set the systick clock source from HCLK/8 */
+        SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8;
+    }
+}

+ 301 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c

@@ -0,0 +1,301 @@
+/*!
+    \file    gd32e230_pmu.c
+    \brief   PMU driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_pmu.h"
+
+/*!
+    \brief      reset PMU register
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_deinit(void)
+{
+    /* reset PMU */
+    rcu_periph_reset_enable(RCU_PMURST);
+    rcu_periph_reset_disable(RCU_PMURST);
+}
+
+/*!
+    \brief      select low voltage detector threshold
+    \param[in]  lvdt_n:
+                only one parameter can be selected which is shown as below:
+      \arg        PMU_LVDT_0: voltage threshold is 2.1V
+      \arg        PMU_LVDT_1: voltage threshold is 2.3V
+      \arg        PMU_LVDT_2: voltage threshold is 2.4V
+      \arg        PMU_LVDT_3: voltage threshold is 2.6V
+      \arg        PMU_LVDT_4: voltage threshold is 2.7V
+      \arg        PMU_LVDT_5: voltage threshold is 2.9V
+      \arg        PMU_LVDT_6: voltage threshold is 3.0V
+      \arg        PMU_LVDT_7: voltage threshold is 3.1V
+    \param[out] none
+    \retval     none
+*/
+void pmu_lvd_select(uint32_t lvdt_n)
+{
+    /* disable LVD */
+    PMU_CTL &= ~PMU_CTL_LVDEN;
+    /* clear LVDT bits */
+    PMU_CTL &= ~PMU_CTL_LVDT;
+    /* set LVDT bits according to lvdt_n */
+    PMU_CTL |= lvdt_n;
+    /* enable LVD */
+    PMU_CTL |= PMU_CTL_LVDEN;
+}
+
+/*!
+    \brief      select LDO output voltage
+                these bits set by software when the main PLL closed
+    \param[in]  ldo_output:
+                only one parameter can be selected which is shown as below:
+      \arg        PMU_LDOVS_LOW: LDO output voltage low mode
+      \arg        PMU_LDOVS_HIGH: LDO output voltage high mode
+    \param[out] none
+    \retval     none
+*/
+void pmu_ldo_output_select(uint32_t ldo_output)
+{
+    PMU_CTL &= ~PMU_CTL_LDOVS;
+    PMU_CTL |= ldo_output;
+}
+
+/*!
+    \brief      disable PMU lvd
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_lvd_disable(void)
+{
+    /* disable LVD */
+    PMU_CTL &= ~PMU_CTL_LVDEN;
+}
+
+/*!
+    \brief      PMU work at sleep mode
+    \param[in]  sleepmodecmd:
+                only one parameter can be selected which is shown as below:
+      \arg        WFI_CMD: use WFI command
+      \arg        WFE_CMD: use WFE command
+    \param[out] none
+    \retval     none
+*/
+void pmu_to_sleepmode(uint8_t sleepmodecmd)
+{
+    /* clear sleepdeep bit of Cortex-M23 system control register */
+    SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+    
+    /* select WFI or WFE command to enter sleep mode */
+    if(WFI_CMD == sleepmodecmd){
+        __WFI();
+    }else{
+        __WFE();
+    }
+}
+
+/*!
+    \brief      PMU work at deepsleep mode
+    \param[in]  ldo:
+                only one parameter can be selected which is shown as below:
+      \arg        PMU_LDO_NORMAL: LDO operates normally when pmu enter deepsleep mode
+      \arg        PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
+    \param[in]  deepsleepmodecmd:
+                only one parameter can be selected which is shown as below:
+      \arg        WFI_CMD: use WFI command
+      \arg        WFE_CMD: use WFE command
+    \param[out] none
+    \retval     none
+*/
+void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd)
+{
+    static uint32_t reg_snap[ 3 ];  
+    /* clear stbmod and ldolp bits */
+    PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
+    
+    /* set ldolp bit according to pmu_ldo */
+    PMU_CTL |= ldo;
+    
+    /* set sleepdeep bit of Cortex-M23 system control register */
+    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+    reg_snap[ 0 ] = REG32( 0xE000E010U );
+    reg_snap[ 1 ] = REG32( 0xE000E100U );
+    reg_snap[ 2 ] = REG32( 0xE000E104U );
+    
+    REG32( 0xE000E010U ) &= 0x00010004U;
+    REG32( 0xE000E180U )  = 0XF7FFEF19U;
+    REG32( 0xE000E184U )  = 0XFFFFFFFFU;
+  
+    /* select WFI or WFE command to enter deepsleep mode */
+    if(WFI_CMD == deepsleepmodecmd){
+        __WFI();
+    }else{
+        __SEV();
+        __WFE();
+        __WFE();
+    }
+
+    REG32( 0xE000E010U ) = reg_snap[ 0 ] ; 
+    REG32( 0xE000E100U ) = reg_snap[ 1 ] ;
+    REG32( 0xE000E104U ) = reg_snap[ 2 ] ;
+    
+    /* reset sleepdeep bit of Cortex-M23 system control register */
+    SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+}
+
+/*!
+    \brief      pmu work at standby mode
+    \param[in]  standbymodecmd:
+                only one parameter can be selected which is shown as below:
+      \arg        WFI_CMD: use WFI command
+      \arg        WFE_CMD: use WFE command
+    \param[out] none
+    \retval     none
+*/
+void pmu_to_standbymode(uint8_t standbymodecmd)
+{
+    /* set sleepdeep bit of Cortex-M23 system control register */
+    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+    /* set stbmod bit */
+    PMU_CTL |= PMU_CTL_STBMOD;
+        
+    /* reset wakeup flag */
+    PMU_CTL |= PMU_CTL_WURST;
+    
+    /* select WFI or WFE command to enter standby mode */
+    if(WFI_CMD == standbymodecmd){
+        __WFI();
+    }else{
+        __WFE();
+    }
+}
+
+/*!
+    \brief      enable wakeup pin
+    \param[in]  wakeup_pin:
+                one or more parameters can be selected which are shown as below:
+      \arg        PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) 
+      \arg        PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13) 
+      \arg        PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) 
+      \arg        PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15) 
+    \param[out] none
+    \retval     none
+*/
+void pmu_wakeup_pin_enable(uint32_t wakeup_pin)
+{
+    PMU_CS |= wakeup_pin;
+}
+
+/*!
+    \brief      disable wakeup pin
+    \param[in]  wakeup_pin:
+                one or more parameters can be selected which are shown as below:
+      \arg        PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) 
+      \arg        PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13) 
+      \arg        PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) 
+      \arg        PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15)
+    \param[out] none
+    \retval     none
+*/
+void pmu_wakeup_pin_disable(uint32_t wakeup_pin)
+{
+    PMU_CS &= ~(wakeup_pin);
+}
+
+/*!
+    \brief      enable backup domain write
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_backup_write_enable(void)
+{
+    PMU_CTL |= PMU_CTL_BKPWEN;
+}
+
+/*!
+    \brief      disable backup domain write
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void pmu_backup_write_disable(void)
+{
+    PMU_CTL &= ~PMU_CTL_BKPWEN;
+}
+
+/*!
+    \brief      clear flag bit
+    \param[in]  flag_clear:
+                one or more parameters can be selected which are shown as below:
+      \arg        PMU_FLAG_RESET_WAKEUP: reset wakeup flag
+      \arg        PMU_FLAG_RESET_STANDBY: reset standby flag
+    \param[out] none
+    \retval     none
+*/
+void pmu_flag_clear(uint32_t flag_clear)
+{
+    if(RESET != (flag_clear & PMU_FLAG_RESET_WAKEUP)){
+        /* reset wakeup flag */
+        PMU_CTL |= PMU_CTL_WURST;
+    }
+    if(RESET != (flag_clear & PMU_FLAG_RESET_STANDBY)){
+        /* reset standby flag */
+        PMU_CTL |= PMU_CTL_STBRST;
+    }
+}
+
+/*!
+    \brief      get flag state
+    \param[in]  flag:
+                only one parameter can be selected which is shown as below:
+      \arg        PMU_FLAG_WAKEUP: wakeup flag
+      \arg        PMU_FLAG_STANDBY: standby flag
+      \arg        PMU_FLAG_LVD: lvd flag
+    \param[out] none
+    \retval     FlagStatus SET or RESET
+*/
+FlagStatus pmu_flag_get(uint32_t flag)
+{
+    FlagStatus ret_status = RESET;
+    
+    if(PMU_CS & flag){
+        ret_status = SET;
+    }
+    
+    return ret_status;
+}

+ 1034 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c

@@ -0,0 +1,1034 @@
+/*!
+    \file    gd32e230_rcu.c
+    \brief   RCU driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_rcu.h"
+
+/* define clock source */
+#define SEL_IRC8M       0x00U
+#define SEL_HXTAL       0x01U
+#define SEL_PLL         0x02U
+
+/* define startup timeout count */
+#define OSC_STARTUP_TIMEOUT         ((uint32_t)0x000FFFFFU)
+#define LXTAL_STARTUP_TIMEOUT       ((uint32_t)0x03FFFFFFU)
+
+/*!
+    \brief      deinitialize the RCU
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_deinit(void)
+{
+    /* enable IRC8M */
+    RCU_CTL0 |= RCU_CTL0_IRC8MEN;
+    while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){
+    }
+    /* reset RCU */
+    RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\
+                  RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV);
+    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV);
+    RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS);
+    RCU_CFG1 &= ~(RCU_CFG1_PREDV);
+    RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL);
+    RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
+    RCU_CFG2 &= ~RCU_CFG2_ADCPSC2;
+    RCU_CTL1 &= ~RCU_CTL1_IRC28MEN;
+    RCU_INT = 0x00000000U;
+}
+
+/*!
+    \brief      enable the peripherals clock
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOx (x=A,B,C,F): GPIO ports clock
+      \arg        RCU_DMA: DMA clock
+      \arg        RCU_CRC: CRC clock
+      \arg        RCU_CFGCMP: CFGCMP clock
+      \arg        RCU_ADC: ADC clock
+      \arg        RCU_TIMERx (x=0,2,5,13,14,15,16): TIMER clock
+      \arg        RCU_SPIx (x=0,1): SPI clock
+      \arg        RCU_USARTx (x=0,1): USART clock
+      \arg        RCU_WWDGT: WWDGT clock
+      \arg        RCU_I2Cx (x=0,1): I2C clock
+      \arg        RCU_PMU: PMU clock
+      \arg        RCU_RTC: RTC clock
+      \arg        RCU_DBGMCU: DBGMCU clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_enable(rcu_periph_enum periph)
+{
+    RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      disable the peripherals clock
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOx (x=A,B,C,F): GPIO ports clock
+      \arg        RCU_DMA: DMA clock
+      \arg        RCU_CRC: CRC clock
+      \arg        RCU_CFGCMP: CFGCMP clock
+      \arg        RCU_ADC: ADC clock
+      \arg        RCU_TIMERx (x=0,2,5,13,14,15,16): TIMER clock
+      \arg        RCU_SPIx (x=0,1): SPI clock
+      \arg        RCU_USARTx (x=0,1): USART clock
+      \arg        RCU_WWDGT: WWDGT clock
+      \arg        RCU_I2Cx (x=0,1): I2C clock
+      \arg        RCU_PMU: PMU clock
+      \arg        RCU_RTC: RTC clock
+      \arg        RCU_DBGMCU: DBGMCU clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_disable(rcu_periph_enum periph)
+{
+    RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      enable the peripherals clock when sleep mode
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_sleep_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_FMC_SLP: FMC clock
+      \arg        RCU_SRAM_SLP: SRAM clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph)
+{
+    RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph));
+}
+
+/*!
+    \brief      disable the peripherals clock when sleep mode
+    \param[in]  periph: RCU peripherals, refer to rcu_periph_sleep_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_FMC_SLP: FMC clock
+      \arg        RCU_SRAM_SLP: SRAM clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph)
+{
+    RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph));
+}
+/*!
+    \brief      reset the peripherals
+    \param[in]  periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOxRST (x=A,B,C,F): reset GPIO ports
+      \arg        RCU_CFGCMPRST: reset CFGCMP
+      \arg        RCU_ADCRST: reset ADC
+      \arg        RCU_TIMERxRST (x=0,2,5,13,14,15,16): reset TIMER
+      \arg        RCU_SPIxRST (x=0,1): reset SPI
+      \arg        RCU_USARTxRST (x=0,1): reset USART
+      \arg        RCU_WWDGTRST: reset WWDGT
+      \arg        RCU_I2CxRST (x=0,1): reset I2C
+      \arg        RCU_PMURST: reset PMU
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset)
+{
+    RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset));
+}
+
+/*!
+    \brief      disable reset the peripheral
+    \param[in]  periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_GPIOxRST (x=A,B,C,F): reset GPIO ports
+      \arg        RCU_CFGCMPRST: reset CFGCMP
+      \arg        RCU_ADCRST: reset ADC
+      \arg        RCU_TIMERxRST (x=0,2,5,13,14,15,16): reset TIMER
+      \arg        RCU_SPIxRST (x=0,1): reset SPI
+      \arg        RCU_USARTxRST (x=0,1): reset USART
+      \arg        RCU_WWDGTRST: reset WWDGT
+      \arg        RCU_I2CxRST (x=0,1): reset I2C
+      \arg        RCU_PMURST: reset PMU
+    \param[out] none
+    \retval     none
+*/
+void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset)
+{
+    RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset));
+}
+
+/*!
+    \brief      reset the BKP
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_bkp_reset_enable(void)
+{
+    RCU_BDCTL |= RCU_BDCTL_BKPRST;
+}
+
+/*!
+    \brief      disable the BKP reset
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_bkp_reset_disable(void)
+{
+    RCU_BDCTL &= ~RCU_BDCTL_BKPRST;
+}
+
+/*!
+    \brief      configure the system clock source
+    \param[in]  ck_sys: system clock source select
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_CKSYSSRC_IRC8M: select CK_IRC8M as the CK_SYS source
+      \arg        RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source
+      \arg        RCU_CKSYSSRC_PLL: select CK_PLL as the CK_SYS source
+    \param[out] none
+    \retval     none
+*/
+void rcu_system_clock_source_config(uint32_t ck_sys)
+{
+    uint32_t cksys_source = 0U;
+    cksys_source = RCU_CFG0;
+    /* reset the SCS bits and set according to ck_sys */
+    cksys_source &= ~RCU_CFG0_SCS;
+    RCU_CFG0 = (ck_sys | cksys_source);
+}
+
+/*!
+    \brief      get the system clock source
+    \param[in]  none
+    \param[out] none
+    \retval     which clock is selected as CK_SYS source
+      \arg        RCU_SCSS_IRC8M: select CK_IRC8M as the CK_SYS source
+      \arg        RCU_SCSS_HXTAL: select CK_HXTAL as the CK_SYS source
+      \arg        RCU_SCSS_PLL: select CK_PLL as the CK_SYS source
+*/
+uint32_t rcu_system_clock_source_get(void)
+{
+    return (RCU_CFG0 & RCU_CFG0_SCSS);
+}
+
+/*!
+    \brief      configure the AHB clock prescaler selection
+    \param[in]  ck_ahb: AHB clock prescaler selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512
+    \param[out] none
+    \retval     none
+*/
+void rcu_ahb_clock_config(uint32_t ck_ahb)
+{
+    uint32_t ahbpsc = 0U;
+    ahbpsc = RCU_CFG0;
+    /* reset the AHBPSC bits and set according to ck_ahb */
+    ahbpsc &= ~RCU_CFG0_AHBPSC;
+    RCU_CFG0 = (ck_ahb | ahbpsc);
+}
+
+/*!
+    \brief      configure the APB1 clock prescaler selection
+    \param[in]  ck_apb1: APB1 clock prescaler selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1
+      \arg        RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1
+    \param[out] none
+    \retval     none
+*/
+void rcu_apb1_clock_config(uint32_t ck_apb1)
+{
+    uint32_t apb1psc = 0U;
+    apb1psc = RCU_CFG0;
+    /* reset the APB1PSC and set according to ck_apb1 */
+    apb1psc &= ~RCU_CFG0_APB1PSC;
+    RCU_CFG0 = (ck_apb1 | apb1psc);
+}
+
+/*!
+    \brief      configure the APB2 clock prescaler selection
+    \param[in]  ck_apb2: APB2 clock prescaler selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2
+      \arg        RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2
+    \param[out] none
+    \retval     none
+*/
+void rcu_apb2_clock_config(uint32_t ck_apb2)
+{
+    uint32_t apb2psc = 0U;
+    apb2psc = RCU_CFG0;
+    /* reset the APB2PSC and set according to ck_apb2 */
+    apb2psc &= ~RCU_CFG0_APB2PSC;
+    RCU_CFG0 = (ck_apb2 | apb2psc);
+}
+
+/*!
+    \brief      configure the ADC clock prescaler selection
+    \param[in]  ck_adc: ADC clock prescaler selection, refer to rcu_adc_clock_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_ADCCK_IRC28M_DIV2: select CK_IRC28M/2 as CK_ADC
+      \arg        RCU_ADCCK_IRC28M: select CK_IRC28M as CK_ADC
+      \arg        RCU_ADCCK_APB2_DIV2: select CK_APB2/2 as CK_ADC
+      \arg        RCU_ADCCK_AHB_DIV3: select CK_AHB/3 as CK_ADC
+      \arg        RCU_ADCCK_APB2_DIV4: select CK_APB2/4 as CK_ADC
+      \arg        RCU_ADCCK_AHB_DIV5: select CK_AHB/5 as CK_ADC
+      \arg        RCU_ADCCK_APB2_DIV6: select CK_APB2/6 as CK_ADC
+      \arg        RCU_ADCCK_AHB_DIV7: select CK_AHB/7 as CK_ADC
+      \arg        RCU_ADCCK_APB2_DIV8: select CK_APB2/8 as CK_ADC
+      \arg        RCU_ADCCK_AHB_DIV9: select CK_AHB/9 as CK_ADC
+    \param[out] none
+    \retval     none
+*/
+void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc)
+{
+    /* reset the ADCPSC, ADCSEL, IRC28MDIV bits */
+    RCU_CFG0 &= ~RCU_CFG0_ADCPSC;
+    RCU_CFG2 &= ~(RCU_CFG2_ADCSEL | RCU_CFG2_IRC28MDIV | RCU_CFG2_ADCPSC2);
+
+    /* set the ADC clock according to ck_adc */
+    switch(ck_adc){
+    case RCU_ADCCK_IRC28M_DIV2:
+        RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
+        RCU_CFG2 &= ~RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_IRC28M:
+        RCU_CFG2 |= RCU_CFG2_IRC28MDIV;
+        RCU_CFG2 &= ~RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_APB2_DIV2:
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_AHB_DIV3:
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2;
+        RCU_CFG2 |= RCU_CFG2_ADCPSC2;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_APB2_DIV4:
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_AHB_DIV5: 
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4;
+        RCU_CFG2 |= RCU_CFG2_ADCPSC2;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_APB2_DIV6: 
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_AHB_DIV7: 
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6;
+        RCU_CFG2 |= RCU_CFG2_ADCPSC2;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_APB2_DIV8: 
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    case RCU_ADCCK_AHB_DIV9: 
+        RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8;
+        RCU_CFG2 |= RCU_CFG2_ADCPSC2;
+        RCU_CFG2 |= RCU_CFG2_ADCSEL;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure the CK_OUT clock source and divider
+    \param[in]  ckout_src: CK_OUT clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_CKOUTSRC_NONE: no clock selected
+      \arg        RCU_CKOUTSRC_IRC28M: IRC28M selected
+      \arg        RCU_CKOUTSRC_IRC40K: IRC40K selected
+      \arg        RCU_CKOUTSRC_LXTAL: LXTAL selected
+      \arg        RCU_CKOUTSRC_CKSYS: CKSYS selected
+      \arg        RCU_CKOUTSRC_IRC8M: IRC8M selected
+      \arg        RCU_CKOUTSRC_HXTAL: HXTAL selected
+      \arg        RCU_CKOUTSRC_CKPLL_DIV1: CK_PLL selected
+      \arg        RCU_CKOUTSRC_CKPLL_DIV2: CK_PLL/2 selected
+    \param[in]  ckout_div: CK_OUT divider 
+      \arg        RCU_CKOUT_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT is divided by x
+    \param[out] none
+    \retval     none
+*/
+void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div)
+{
+    uint32_t ckout = 0U;
+    ckout = RCU_CFG0;
+    /* reset the CKOUTSEL, CKOUTDIV and PLLDV bits and set according to ckout_src and ckout_div */
+    ckout &= ~(RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV);
+    RCU_CFG0 = (ckout | ckout_src | ckout_div);
+}
+
+/*!
+    \brief      configure the PLL clock source selection and PLL multiply factor
+    \param[in]  pll_src: PLL clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_PLLSRC_IRC8M_DIV2: select CK_IRC8M/2 as PLL source clock
+      \arg        RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock
+    \param[in]  pll_mul: PLL multiply factor
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_PLL_MULx(x=2..32): PLL source clock * x
+    \param[out] none
+    \retval     none
+*/
+void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul)
+{
+    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
+    RCU_CFG0 |= (pll_src | pll_mul);
+}
+
+/*!
+    \brief      configure the USART clock source selection
+    \param[in]  ck_usart: USART clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_USART0SRC_CKAPB2: CK_USART0 select CK_APB2
+      \arg        RCU_USART0SRC_CKSYS: CK_USART0 select CK_SYS
+      \arg        RCU_USART0SRC_LXTAL: CK_USART0 select CK_LXTAL
+      \arg        RCU_USART0SRC_IRC8M: CK_USART0 select CK_IRC8M
+    \param[out] none
+    \retval     none
+*/
+void rcu_usart_clock_config(uint32_t ck_usart)
+{
+    /* reset the USART0SEL bits and set according to ck_usart */
+    RCU_CFG2 &= ~RCU_CFG2_USART0SEL;
+    RCU_CFG2 |= ck_usart;
+}
+
+/*!
+    \brief      configure the RTC clock source selection
+    \param[in]  rtc_clock_source: RTC clock source selection
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_RTCSRC_NONE: no clock selected
+      \arg        RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock
+      \arg        RCU_RTCSRC_IRC40K: CK_IRC40K selected as RTC source clock
+      \arg        RCU_RTCSRC_HXTAL_DIV32: CK_HXTAL/32 selected as RTC source clock
+    \param[out] none
+    \retval     none
+*/
+void rcu_rtc_clock_config(uint32_t rtc_clock_source)
+{
+    /* reset the RTCSRC bits and set according to rtc_clock_source */
+    RCU_BDCTL &= ~RCU_BDCTL_RTCSRC;
+    RCU_BDCTL |= rtc_clock_source;
+}
+
+/*!
+    \brief      configure the HXTAL divider used as input of PLL
+    \param[in]  hxtal_prediv: HXTAL divider used as input of PLL
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_PLL_PREDVx(x=1..16): HXTAL divided x used as input of PLL
+    \param[out] none
+    \retval     none
+*/
+void rcu_hxtal_prediv_config(uint32_t hxtal_prediv)
+{
+    uint32_t prediv = 0U;
+    prediv = RCU_CFG1;
+    /* reset the PREDV bits and set according to hxtal_prediv */
+    prediv &= ~RCU_CFG1_PREDV;
+    RCU_CFG1 = (prediv | hxtal_prediv);
+}
+
+/*!
+    \brief      configure the LXTAL drive capability
+    \param[in]  lxtal_dricap: drive capability of LXTAL
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_LXTAL_LOWDRI: lower driving capability
+      \arg        RCU_LXTAL_MED_LOWDRI: medium low driving capability
+      \arg        RCU_LXTAL_MED_HIGHDRI: medium high driving capability
+      \arg        RCU_LXTAL_HIGHDRI: higher driving capability
+    \param[out] none
+    \retval     none
+*/
+void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap)
+{
+    /* reset the LXTALDRI bits and set according to lxtal_dricap */
+    RCU_BDCTL &= ~RCU_BDCTL_LXTALDRI;
+    RCU_BDCTL |= lxtal_dricap;
+}
+
+/*!
+    \brief      get the clock stabilization and periphral reset flags
+    \param[in]  flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_FLAG_IRC40KSTB: IRC40K stabilization flag
+      \arg        RCU_FLAG_LXTALSTB: LXTAL stabilization flag
+      \arg        RCU_FLAG_IRC8MSTB: IRC8M stabilization flag
+      \arg        RCU_FLAG_HXTALSTB: HXTAL stabilization flag
+      \arg        RCU_FLAG_PLLSTB: PLL stabilization flag
+      \arg        RCU_FLAG_IRC28MSTB: IRC28M stabilization flag
+      \arg        RCU_FLAG_V12RST: V12 domain power reset flag
+      \arg        RCU_FLAG_OBLRST: option byte loader reset flag
+      \arg        RCU_FLAG_EPRST: external pin reset flag
+      \arg        RCU_FLAG_PORRST: power reset flag
+      \arg        RCU_FLAG_SWRST: software reset flag
+      \arg        RCU_FLAG_FWDGTRST: free watchdog timer reset flag
+      \arg        RCU_FLAG_WWDGTRST: window watchdog timer reset flag
+      \arg        RCU_FLAG_LPRST: low-power reset flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus rcu_flag_get(rcu_flag_enum flag)
+{
+    if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the reset flag
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_all_reset_flag_clear(void)
+{
+    RCU_RSTSCK |= RCU_RSTSCK_RSTFC;
+}
+
+/*!
+    \brief      get the clock stabilization interrupt and ckm flags
+    \param[in]  int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_FLAG_IRC40KSTB: IRC40K stabilization interrupt flag
+      \arg        RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag
+      \arg        RCU_INT_FLAG_IRC8MSTB: IRC8M stabilization interrupt flag
+      \arg        RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag
+      \arg        RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag
+      \arg        RCU_INT_FLAG_IRC28MSTB: IRC28M stabilization interrupt flag
+      \arg        RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag)
+{
+    if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the interrupt flags
+    \param[in]  int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_FLAG_IRC40KSTB_CLR: IRC40K stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_IRC8MSTB_CLR: IRC8M stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_IRC28MSTB_CLR: IRC28M stabilization interrupt flag clear
+      \arg        RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear
+    \param[out] none
+    \retval     none
+*/
+void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear)
+{
+    RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear));
+}
+
+/*!
+    \brief      enable the stabilization interrupt
+    \param[in]  stab_int: clock stabilization interrupt, refer to rcu_int_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable
+      \arg        RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable
+      \arg        RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable
+      \arg        RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable
+      \arg        RCU_INT_PLLSTB: PLL stabilization interrupt enable
+      \arg        RCU_INT_IRC28MSTB: IRC28M stabilization interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void rcu_interrupt_enable(rcu_int_enum stab_int)
+{
+    RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int));
+}
+
+
+/*!
+    \brief      disable the stabilization interrupt
+    \param[in]  stab_int: clock stabilization interrupt, refer to rcu_int_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_INT_IRC40KSTB: IRC40K stabilization interrupt disable
+      \arg        RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable
+      \arg        RCU_INT_IRC8MSTB: IRC8M stabilization interrupt disable
+      \arg        RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable
+      \arg        RCU_INT_PLLSTB: PLL stabilization interrupt disable
+      \arg        RCU_INT_IRC28MSTB: IRC28M stabilization interrupt disable
+    \param[out] none
+    \retval     none
+*/
+void rcu_interrupt_disable(rcu_int_enum stab_int)
+{
+    RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int));
+}
+
+/*!
+    \brief      wait until oscillator stabilization flags is SET
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+      \arg        RCU_IRC8M: IRC8M
+      \arg        RCU_IRC28M: IRC28M
+      \arg        RCU_IRC40K: IRC40K
+      \arg        RCU_PLL_CK: PLL
+    \param[out] none
+    \retval     ErrStatus: SUCCESS or ERROR
+*/
+ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci)
+{
+    uint32_t stb_cnt = 0U;
+    ErrStatus reval = ERROR;
+    FlagStatus osci_stat = RESET;
+    switch(osci){
+    case RCU_HXTAL:
+         /* wait until HXTAL is stabilization and osci_stat is not more than timeout */
+        while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB);
+            stb_cnt++;
+        }
+        /* check whether flag is set or not */
+        if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){
+            reval = SUCCESS;
+        }
+        break;
+        
+    /* wait LXTAL stable */
+    case RCU_LXTAL:
+        while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB);
+            stb_cnt++;
+        }
+        /* check whether flag is set or not */
+        if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){
+            reval = SUCCESS;
+        }
+        break;
+
+    /* wait IRC8M stable */
+    case RCU_IRC8M:
+        while((RESET == osci_stat) && (IRC8M_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_IRC8MSTB);
+            stb_cnt++;
+        }
+        /* check whether flag is set or not */
+        if(RESET != rcu_flag_get(RCU_FLAG_IRC8MSTB)){
+            reval = SUCCESS;
+        }
+        break;
+
+    /* wait IRC28M stable */
+    case RCU_IRC28M:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_IRC28MSTB);
+            stb_cnt++;
+        }
+        /* check whether flag is set or not */
+        if(RESET != rcu_flag_get(RCU_FLAG_IRC28MSTB)){
+            reval = SUCCESS;
+        }
+        break;
+        
+    /* wait IRC40K stable */
+    case RCU_IRC40K:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_IRC40KSTB);
+            stb_cnt++;
+        }
+        /* check whether flag is set or not */
+        if(RESET != rcu_flag_get(RCU_FLAG_IRC40KSTB)){
+            reval = SUCCESS;
+        }
+        break;
+
+    /* wait PLL stable */
+    case RCU_PLL_CK:
+        while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){
+            osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB);
+            stb_cnt++;
+        }
+        /* check whether flag is set or not */
+        if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){
+            reval = SUCCESS;
+        }
+        break;
+   
+    default:
+        break;
+    }
+    /* return value */
+    return reval;
+}
+
+/*!
+    \brief      turn on the oscillator
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+      \arg        RCU_IRC8M: IRC8M
+      \arg        RCU_IRC28M: IRC28M
+      \arg        RCU_IRC40K: IRC40K
+      \arg        RCU_PLL_CK: PLL
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_on(rcu_osci_type_enum osci)
+{
+    RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci));
+}
+
+/*!
+    \brief      turn off the oscillator
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+      \arg        RCU_IRC8M: IRC8M
+      \arg        RCU_IRC28M: IRC28M
+      \arg        RCU_IRC40K: IRC40K
+      \arg        RCU_PLL_CK: PLL
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_off(rcu_osci_type_enum osci)
+{
+    RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci));
+}
+
+/*!
+    \brief      enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci)
+{
+    uint32_t reg;
+    switch(osci){
+    case RCU_HXTAL:
+        /* HXTALEN must be reset before enable the oscillator bypass mode */
+        reg = RCU_CTL0;
+        RCU_CTL0 &= ~RCU_CTL0_HXTALEN;
+        RCU_CTL0 = (reg | RCU_CTL0_HXTALBPS);
+        break;
+    case RCU_LXTAL:
+        /* LXTALEN must be reset before enable the oscillator bypass mode */
+        reg = RCU_BDCTL;
+        RCU_BDCTL &= ~RCU_BDCTL_LXTALEN;
+        RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS);
+        break;
+    case RCU_IRC8M:
+    case RCU_IRC28M:
+    case RCU_IRC40K:
+    case RCU_PLL_CK:
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it
+    \param[in]  osci: oscillator types, refer to rcu_osci_type_enum
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_HXTAL: HXTAL
+      \arg        RCU_LXTAL: LXTAL
+    \param[out] none
+    \retval     none
+*/
+void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci)
+{
+    uint32_t reg;
+    switch(osci){
+    case RCU_HXTAL:
+        /* HXTALEN must be reset before disable the oscillator bypass mode */
+        reg = RCU_CTL0;
+        RCU_CTL0 &= ~RCU_CTL0_HXTALEN;
+        RCU_CTL0 = (reg & (~RCU_CTL0_HXTALBPS));
+        break;
+    case RCU_LXTAL:
+        /* LXTALEN must be reset before disable the oscillator bypass mode */
+        reg = RCU_BDCTL;
+        RCU_BDCTL &= ~RCU_BDCTL_LXTALEN;
+        RCU_BDCTL = (reg & (~RCU_BDCTL_LXTALBPS));
+        break;
+    case RCU_IRC8M:
+    case RCU_IRC28M:
+    case RCU_IRC40K:
+    case RCU_PLL_CK:
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      enable the HXTAL clock monitor
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_hxtal_clock_monitor_enable(void)
+{
+    RCU_CTL0 |= RCU_CTL0_CKMEN;
+}
+
+/*!
+    \brief      disable the HXTAL clock monitor
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_hxtal_clock_monitor_disable(void)
+{
+    RCU_CTL0 &= ~RCU_CTL0_CKMEN;
+}
+
+/*!
+    \brief      set the IRC8M adjust value
+    \param[in]  irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F
+    \param[out] none
+    \retval     none
+*/
+void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval)
+{
+    uint32_t adjust = 0U;
+    adjust = RCU_CTL0;
+    /* reset the IRC8MADJ bits and set according to irc8m_adjval */
+    adjust &= ~RCU_CTL0_IRC8MADJ;
+    RCU_CTL0 = (adjust | (((uint32_t)irc8m_adjval)<<3));
+}
+
+/*!
+    \brief      set the IRC28M adjust value
+    \param[in]  irc28m_adjval: IRC28M adjust value, must be between 0 and 0x1F
+    \param[out] none
+    \retval     none
+*/
+void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval)
+{
+    uint32_t adjust = 0U;
+    adjust = RCU_CTL1;
+    /* reset the IRC28MADJ bits and set according to irc28m_adjval */
+    adjust &= ~RCU_CTL1_IRC28MADJ;
+    RCU_CTL1 = (adjust | (((uint32_t)irc28m_adjval)<<3));
+}
+
+/*!
+    \brief      unlock the voltage key
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rcu_voltage_key_unlock(void)
+{
+    /* reset the KEY bits and set 0x1A2B3C4D */
+    RCU_VKEY &= ~RCU_VKEY_KEY;
+    RCU_VKEY |= RCU_VKEY_UNLOCK;
+}
+
+/*!
+    \brief      set voltage in deep sleep mode
+    \param[in]  dsvol: deep sleep mode voltage
+                only one parameter can be selected which is shown as below:
+      \arg        RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V
+      \arg        RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V
+      \arg        RCU_DEEPSLEEP_V_0_8: the core voltage is 0.8V
+      \arg        RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V
+    \param[out] none
+    \retval     none
+*/
+void rcu_deepsleep_voltage_set(uint32_t dsvol)
+{
+    /* reset the DSLPVS bits and set according to dsvol */
+    RCU_DSV &= ~RCU_DSV_DSLPVS;
+    RCU_DSV |= dsvol;
+}
+
+/*!
+    \brief      get the system clock, bus and peripheral clock frequency
+    \param[in]  clock: the clock frequency which to get
+                only one parameter can be selected which is shown as below:
+      \arg        CK_SYS: system clock frequency
+      \arg        CK_AHB: AHB clock frequency
+      \arg        CK_APB1: APB1 clock frequency
+      \arg        CK_APB2: APB2 clock frequency
+      \arg        CK_ADC: ADC clock frequency
+      \arg        CK_USART: USART0 clock frequency
+    \param[out] none
+    \retval     clock frequency of system, AHB, APB1, APB2, ADC or USRAT0
+*/
+uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock)
+{
+    uint32_t sws = 0U, adcps = 0U, adcps2 = 0U, ck_freq = 0U;
+    uint32_t cksys_freq = 0U, ahb_freq = 0U, apb1_freq = 0U, apb2_freq = 0U;
+    uint32_t adc_freq = 0U, usart_freq = 0U;
+    uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U;
+    /* exponent of AHB, APB1 and APB2 clock divider */
+    const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+    const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+    const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+    sws = GET_BITS(RCU_CFG0, 2, 3);
+    switch(sws){
+    /* IRC8M is selected as CK_SYS */
+    case SEL_IRC8M:
+        cksys_freq = IRC8M_VALUE;
+        break;
+    /* HXTAL is selected as CK_SYS */
+    case SEL_HXTAL:
+        cksys_freq = HXTAL_VALUE;
+        break;
+    /* PLL is selected as CK_SYS */
+    case SEL_PLL:
+        /* get the value of PLLMF[3:0] */
+        pllmf = GET_BITS(RCU_CFG0, 18, 21);
+        pllmf4 = GET_BITS(RCU_CFG0, 27, 27);
+        /* high 16 bits */
+        if(1U == pllmf4){
+            pllmf += 17U;
+        }else if(15U == pllmf){
+            pllmf = 16U;
+        }else{
+            pllmf += 2U;
+        }
+            
+        /* PLL clock source selection, HXTAL or IRC8M/2 */
+        pllsel = GET_BITS(RCU_CFG0, 16, 16);
+        if(0U != pllsel){
+            prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U);
+            cksys_freq = (HXTAL_VALUE / prediv) * pllmf;
+        }else{
+            cksys_freq = (IRC8M_VALUE >> 1) * pllmf;
+        }
+        break;
+    /* IRC8M is selected as CK_SYS */
+    default:
+        cksys_freq = IRC8M_VALUE;
+        break;
+    }
+    /* calculate AHB clock frequency */
+    idx = GET_BITS(RCU_CFG0, 4, 7);
+    clk_exp = ahb_exp[idx];
+    ahb_freq = cksys_freq >> clk_exp;
+    
+    /* calculate APB1 clock frequency */
+    idx = GET_BITS(RCU_CFG0, 8, 10);
+    clk_exp = apb1_exp[idx];
+    apb1_freq = ahb_freq >> clk_exp;
+    
+    /* calculate APB2 clock frequency */
+    idx = GET_BITS(RCU_CFG0, 11, 13);
+    clk_exp = apb2_exp[idx];
+    apb2_freq = ahb_freq >> clk_exp;
+    
+    /* return the clocks frequency */
+    switch(clock){
+    case CK_SYS:
+        ck_freq = cksys_freq;
+        break;
+    case CK_AHB:
+        ck_freq = ahb_freq;
+        break;
+    case CK_APB1:
+        ck_freq = apb1_freq;
+        break;
+    case CK_APB2:
+        ck_freq = apb2_freq;
+        break;
+    case CK_ADC:
+        /* calculate ADC clock frequency */
+        if(RCU_ADCSRC_AHB_APB2DIV != (RCU_CFG2 & RCU_CFG2_ADCSEL)){
+            if(RCU_ADC_IRC28M_DIV1 != (RCU_CFG2 & RCU_CFG2_IRC28MDIV)){
+                adc_freq = IRC28M_VALUE >> 1;
+            }else{
+                adc_freq = IRC28M_VALUE;
+            }
+        }else{
+            /* ADC clock select CK_APB2 divided by 2/4/6/8 or CK_AHB divided by 3/5/7/9 */
+            adcps = GET_BITS(RCU_CFG0, 14, 15);
+            adcps2 = GET_BITS(RCU_CFG2, 31, 31);
+            if(0U != adcps2){
+                /* ADC clock select CK_AHB divided by 3/5/7/9 */
+                adc_freq = ahb_freq / (adcps + 1U);
+            }else{
+                /* ADC clock select CK_APB2 divided by 2/4/6/8 */
+                adc_freq = apb2_freq / adcps;
+            }
+        }
+        ck_freq = adc_freq;
+        break;
+    case CK_USART:
+        /* calculate USART0 clock frequency */
+        if(RCU_USART0SRC_CKAPB2 == (RCU_CFG2 & RCU_CFG2_USART0SEL)){
+            usart_freq = apb2_freq;
+        }else if(RCU_USART0SRC_CKSYS == (RCU_CFG2 & RCU_CFG2_USART0SEL)){
+            usart_freq = cksys_freq;
+        }else if(RCU_USART0SRC_LXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)){
+            usart_freq = LXTAL_VALUE;
+        }else if(RCU_USART0SRC_IRC8M == (RCU_CFG2 & RCU_CFG2_USART0SEL)){
+            usart_freq = IRC8M_VALUE;
+        }else{
+        }
+        ck_freq = usart_freq;
+        break;
+    default:
+        break;
+    }
+    return ck_freq;
+}

+ 965 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c

@@ -0,0 +1,965 @@
+/*!
+    \file    gd32e230_rtc.c
+    \brief   RTC driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_rtc.h"
+
+/*!
+    \brief      reset most of the RTC registers
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_deinit(void)
+{
+    ErrStatus error_status = ERROR;
+
+    /* RTC_TAMP register is not under write protection */
+    RTC_TAMP = RTC_REGISTER_RESET;
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* reset RTC_CTL register, this can be done without the init mode */
+    RTC_CTL &= RTC_REGISTER_RESET;
+
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){
+        /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition.
+           in order to read calendar from shadow register, not the real registers being reset */
+        RTC_TIME = RTC_REGISTER_RESET;
+        RTC_DATE = RTC_DATE_RESET;
+
+        RTC_PSC = RTC_PSC_RESET;
+
+        /* reset RTC_STAT register, also exit init mode.
+           at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */
+        RTC_STAT = RTC_STAT_RESET;
+      
+        /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */
+        RTC_ALRM0TD = RTC_REGISTER_RESET;
+        RTC_ALRM0SS = RTC_REGISTER_RESET;
+
+        /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */
+        RTC_SHIFTCTL = RTC_REGISTER_RESET;
+        RTC_HRFC = RTC_REGISTER_RESET;
+
+        error_status = rtc_register_sync_wait();  
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      initialize RTC registers
+    \param[in]  rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains 
+                parameters for initialization of the rtc peripheral
+                members of the structure and the member values are shown as below:
+                  rtc_year: 0x0 - 0x99(BCD format)
+                  rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
+                             RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
+                  rtc_date: 0x1 - 0x31(BCD format)
+                  rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
+                                   RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
+                  rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
+                  rtc_minute: 0x0 - 0x59(BCD format)
+                  rtc_second: 0x0 - 0x59(BCD format)
+                  rtc_factor_asyn: 0x0 - 0x7F
+                  rtc_factor_syn: 0x0 - 0x7FFF
+                  rtc_am_pm: RTC_AM, RTC_PM
+                  rtc_display_format: RTC_24HOUR, RTC_12HOUR
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)
+{
+    ErrStatus error_status = ERROR;
+    uint32_t reg_time = 0x00U, reg_date = 0x00U;
+
+    reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \
+                DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \
+                DATE_MON(rtc_initpara_struct->rtc_month) | \
+                DATE_DAY(rtc_initpara_struct->rtc_date)); 
+    
+    reg_time = (rtc_initpara_struct->rtc_am_pm| \
+                TIME_HR(rtc_initpara_struct->rtc_hour) | \
+                TIME_MN(rtc_initpara_struct->rtc_minute) | \
+                TIME_SC(rtc_initpara_struct->rtc_second)); 
+              
+    /* 1st: disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* 2nd: enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){
+        RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \
+                                  PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn));
+
+        RTC_TIME = (uint32_t)reg_time;
+        RTC_DATE = (uint32_t)reg_date;
+
+        RTC_CTL &= (uint32_t)(~RTC_CTL_CS);
+        RTC_CTL |=  rtc_initpara_struct->rtc_display_format;
+        
+        /* 3rd: exit init mode */
+        rtc_init_mode_exit();
+        
+        /* 4th: wait the RSYNF flag to set */
+        error_status = rtc_register_sync_wait();
+    }
+
+    /* 5th: enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enter RTC init mode
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_init_mode_enter(void)
+{
+    uint32_t time_index = RTC_INITM_TIMEOUT;
+    uint32_t flag_status = RESET;
+    ErrStatus error_status = ERROR;
+
+    /* check whether it has been in init mode */
+    if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){
+        RTC_STAT |= RTC_STAT_INITM;
+        
+        /* wait until the INITF flag to be set */
+        do{
+           flag_status = RTC_STAT & RTC_STAT_INITF;
+        }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status));
+
+        if((uint32_t)RESET != flag_status){
+            error_status = SUCCESS;
+        }
+    }else{
+        error_status = SUCCESS;
+    }
+    return error_status;
+}
+
+/*!
+    \brief      exit RTC init mode
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_init_mode_exit(void)
+{
+    RTC_STAT &= (uint32_t)(~RTC_STAT_INITM);
+}
+
+/*!
+    \brief      wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow 
+                registers are updated
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_register_sync_wait(void)
+{
+    volatile uint32_t time_index = RTC_RSYNF_TIMEOUT;
+    uint32_t flag_status = RESET;
+    ErrStatus error_status = ERROR;
+
+    if((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){
+        /* disable the write protection */
+        RTC_WPK = RTC_UNLOCK_KEY1;
+        RTC_WPK = RTC_UNLOCK_KEY2;
+
+        /* firstly clear RSYNF flag */
+        RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF);
+
+        /* wait until RSYNF flag to be set */
+        do{
+            flag_status = RTC_STAT & RTC_STAT_RSYNF;
+        }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status));
+
+        if((uint32_t)RESET != flag_status){
+            error_status = SUCCESS;
+        }
+        
+        /* enable the write protection */
+        RTC_WPK = RTC_LOCK_KEY;
+    }else{ 
+        error_status = SUCCESS;
+    }
+
+    return error_status;
+}
+
+/*!
+    \brief      get current time and date
+    \param[in]  none
+    \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains 
+                parameters for initialization of the rtc peripheral
+                members of the structure and the member values are shown as below:
+                  rtc_year: 0x0 - 0x99(BCD format)
+                  rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
+                             RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
+                  rtc_date: 0x1 - 0x31(BCD format)
+                  rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
+                                   RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
+                  rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
+                  rtc_minute: 0x0 - 0x59(BCD format)
+                  rtc_second: 0x0 - 0x59(BCD format)
+                  rtc_factor_asyn: 0x0 - 0x7F
+                  rtc_factor_syn: 0x0 - 0x7FFF
+                  rtc_am_pm: RTC_AM, RTC_PM
+                  rtc_display_format: RTC_24HOUR, RTC_12HOUR
+    \retval     none
+*/
+void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct)
+{
+    uint32_t temp_tr = 0x00U, temp_dr = 0x00U, temp_pscr = 0x00U, temp_ctlr = 0x00U;
+
+    temp_tr = (uint32_t)RTC_TIME;   
+    temp_dr = (uint32_t)RTC_DATE;
+    temp_pscr = (uint32_t)RTC_PSC;
+    temp_ctlr = (uint32_t)RTC_CTL;
+  
+    /* get current time and construct rtc_parameter_struct structure */
+    rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr);
+    rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr);
+    rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr);
+    rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr);  
+    rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr);
+    rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr);
+    rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr);
+    rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr);
+    rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr);
+    rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); 
+    rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS);
+}
+
+/*!
+    \brief      get current subsecond value
+    \param[in]  none
+    \param[out] none
+    \retval     current subsecond value
+*/
+uint32_t rtc_subsecond_get(void)
+{
+    uint32_t reg = 0x00U;
+    /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */
+    reg = (uint32_t)RTC_SS;
+    /* read RTC_DATE to unlock the 3 shadow registers */
+    (void) (RTC_DATE);
+
+    return reg;
+}
+
+/*!
+    \brief      configure RTC alarm
+    \param[in]  rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains 
+                parameters for RTC alarm configuration
+                members of the structure and the member values are shown as below:
+                  rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
+                                  RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
+                  rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
+                  rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
+                                 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
+                                    RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
+                  rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
+                  rtc_alarm_minute: 0x0 - 0x59(BCD format)
+                  rtc_alarm_second: 0x0 - 0x59(BCD format)
+                  rtc_am_pm: RTC_AM, RTC_PM
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time)
+{
+    uint32_t reg_alrm0td = 0x00U;
+
+    reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \
+                 rtc_alarm_time->rtc_weekday_or_date | \
+                 rtc_alarm_time->rtc_am_pm | \
+                 ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \
+                 ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \
+                 ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \
+                 ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second));
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_ALRM0TD = (uint32_t)reg_alrm0td;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      configure subsecond of RTC alarm
+    \param[in]  mask_subsecond: alarm subsecond mask
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_MASKSSC_0_14: mask alarm subsecond configuration
+      \arg        RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared
+      \arg        RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared
+      \arg        RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared
+      \arg        RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared
+      \arg        RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared
+      \arg        RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared
+      \arg        RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared
+      \arg        RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared
+      \arg        RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared
+      \arg        RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared
+      \arg        RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared
+      \arg        RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared
+      \arg        RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared
+      \arg        RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared
+      \arg        RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared
+    \param[in]  subsecond: alarm subsecond value(0x000 - 0x7FFF)
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;  
+
+    RTC_ALRM0SS = mask_subsecond | subsecond;  
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      enable RTC alarm
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_alarm_enable(void)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL |= RTC_CTL_ALRM0EN;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC alarm
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_alarm_disable(void)
+{
+    volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT;
+    ErrStatus error_status = ERROR;
+    uint32_t flag_status = RESET;
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* clear the state of alarm */
+    RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN);  
+    
+    /* wait until ALRM0WF flag to be set after the alarm is disabled */
+    do{
+        flag_status = RTC_STAT & RTC_STAT_ALRM0WF;
+    }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status));
+    
+    if((uint32_t)RESET != flag_status){     
+        error_status = SUCCESS;
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      get RTC alarm
+    \param[in]  none
+    \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains 
+                parameters for RTC alarm configuration
+                members of the structure and the member values are shown as below:
+                  rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
+                                  RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
+                  rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
+                  rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
+                                 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
+                                    RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
+                  rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
+                  rtc_alarm_minute: 0x0 - 0x59(BCD format)
+                  rtc_alarm_second: 0x0 - 0x59(BCD format)
+                  rtc_am_pm: RTC_AM, RTC_PM
+    \retval     none
+*/
+void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time)
+{
+    uint32_t reg_alrm0td = 0x00U;
+
+    /* get the value of RTC_ALRM0TD register */
+    reg_alrm0td = RTC_ALRM0TD;
+
+    /* get alarm parameters and construct the rtc_alarm_struct structure */
+    rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK; 
+    rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM);
+    rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS);
+    rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td);
+    rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td);
+    rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td);
+    rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td);  
+}
+
+/*!
+    \brief      get RTC alarm subsecond
+    \param[in]  none
+    \param[out] none
+    \retval     RTC alarm subsecond value
+*/
+uint32_t rtc_alarm_subsecond_get(void)
+{
+    return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC));
+}
+
+/*!
+    \brief      enable RTC time-stamp
+    \param[in]  edge: specify which edge to detect of time-stamp
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event
+      \arg        RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event
+    \param[out] none
+    \retval     none
+*/
+void rtc_timestamp_enable(uint32_t edge)
+{
+    uint32_t reg_ctl = 0x00U;
+
+    /* clear the bits to be configured in RTC_CTL */
+    reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN)));
+
+    /* new configuration */
+    reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN);
+   
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL = (uint32_t)reg_ctl;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC time-stamp
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_timestamp_disable(void)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* clear the TSEN bit */
+    RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      get RTC timestamp time and date
+    \param[in]  none
+    \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains 
+                parameters for RTC time-stamp configuration
+                members of the structure and the member values are shown as below:
+                  rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
+                                       RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
+                  rtc_timestamp_date: 0x1 - 0x31(BCD format)
+                  rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
+                                     RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
+                  rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
+                  rtc_timestamp_minute: 0x0 - 0x59(BCD format)
+                  rtc_timestamp_second: 0x0 - 0x59(BCD format)
+                  rtc_am_pm: RTC_AM, RTC_PM
+    \retval     none
+*/
+void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp)
+{
+    uint32_t temp_tts = 0x00U, temp_dts = 0x00U;
+
+    /* get the value of time_stamp registers */
+    temp_tts = (uint32_t)RTC_TTS;
+    temp_dts = (uint32_t)RTC_DTS;
+  
+    /* get timestamp time and construct the rtc_timestamp_struct structure */
+    rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM);
+    rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts);
+    rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts);
+    rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts);
+    rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts);
+    rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts);
+    rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts);
+}
+
+/*!
+    \brief      get RTC time-stamp subsecond
+    \param[in]  none
+    \param[out] none
+    \retval     RTC time-stamp subsecond value
+*/
+uint32_t rtc_timestamp_subsecond_get(void)
+{
+    return ((uint32_t)RTC_SSTS);
+}
+
+/*!
+    \brief      enable RTC tamper
+    \param[in]  rtc_tamper: pointer to a rtc_tamper_struct structure which contains 
+                parameters for RTC tamper configuration
+                members of the structure and the member values are shown as below:
+                  rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1
+                  rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING
+                                      RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH
+                  rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S
+                  rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192,
+                                               RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024,
+                                               RTC_FREQ_DIV512, RTC_FREQ_DIV256
+                  rtc_tamper_precharge_enable: DISABLE, ENABLE
+                  rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C
+                  rtc_tamper_with_timestamp: DISABLE, ENABLE
+    \param[out] none
+    \retval     none
+*/
+void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper)
+{
+    /* disable tamper */
+    RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source); 
+
+    /* tamper filter must be used when the tamper source is voltage level detection */
+    RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT;
+    
+    /* the tamper source is voltage level detection */
+    if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){ 
+        RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT);
+
+        /* check if the tamper pin need precharge, if need, then configure the precharge time */
+        if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){
+            RTC_TAMP |=  (uint32_t)RTC_TAMP_DISPU;    
+        }else{
+            RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time);
+        }
+
+        RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency);
+        RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter);
+    }
+    
+    RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS;  
+    
+    if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){           
+        /* the tamper event also cause a time-stamp event */
+        RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS;
+    } 
+    
+    /* configure the tamper trigger */
+    RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS));    
+    if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){
+        RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS);  
+    }    
+    /* enable tamper */
+    RTC_TAMP |=  (uint32_t)(rtc_tamper->rtc_tamper_source); 
+}
+
+/*!
+    \brief      disable RTC tamper
+    \param[in]  source: specify which tamper source to be disabled
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_TAMPER0
+      \arg        RTC_TAMPER1
+    \param[out] none
+    \retval     none
+*/
+void rtc_tamper_disable(uint32_t source)
+{
+    /* disable tamper */
+    RTC_TAMP &= (uint32_t)~source; 
+
+}
+
+/*!
+    \brief      enable specified RTC interrupt
+    \param[in]  interrupt: specify which interrupt source to be enabled
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_INT_TIMESTAMP: timestamp interrupt
+      \arg        RTC_INT_ALARM: alarm interrupt
+      \arg        RTC_INT_TAMP: tamp interrupt
+    \param[out] none
+    \retval     none
+*/
+void rtc_interrupt_enable(uint32_t interrupt)
+{  
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+ 
+    /* enable the interrupts in RTC_CTL register */
+    RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE);
+    /* enable the interrupts in RTC_TAMP register */
+    RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE);
+    
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY; 
+}
+
+/*!
+    \brief      disble specified RTC interrupt
+    \param[in]  interrupt: specify which interrupt source to be disabled
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_INT_TIMESTAMP: timestamp interrupt
+      \arg        RTC_INT_ALARM: alarm interrupt
+      \arg        RTC_INT_TAMP: tamp interrupt
+    \param[out] none
+    \retval     none
+*/
+void rtc_interrupt_disable(uint32_t interrupt)
+{  
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+ 
+    /* disable the interrupts in RTC_CTL register */
+    RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE);
+    /* disable the interrupts in RTC_TAMP register */
+    RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      check specified flag
+    \param[in]  flag: specify which flag to check
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_FLAG_RECALIBRATION: recalibration pending flag
+      \arg        RTC_FLAG_TAMP1: tamper 1 event flag
+      \arg        RTC_FLAG_TAMP0: tamper 0 event flag
+      \arg        RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag
+      \arg        RTC_FLAG_TIMESTAMP: time-stamp event flag
+      \arg        RTC_FLAG_ALARM0: alarm event flag
+      \arg        RTC_FLAG_INIT: init mode event flag
+      \arg        RTC_FLAG_RSYN: time and date registers synchronized event flag
+      \arg        RTC_FLAG_YCM: year parameter configured event flag
+      \arg        RTC_FLAG_SHIFT: shift operation pending flag
+      \arg        RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus rtc_flag_get(uint32_t flag)
+{
+    FlagStatus flag_state = RESET;
+    
+    if((uint32_t)RESET != (RTC_STAT & flag)){   
+        flag_state = SET;
+    }
+    return flag_state;
+}
+
+/*!
+    \brief      clear specified flag
+    \param[in]  flag: specify which flag to clear
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_FLAG_TAMP1: tamper 1 event flag
+      \arg        RTC_FLAG_TAMP0: tamper 0 event flag
+      \arg        RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag
+      \arg        RTC_FLAG_TIMESTAMP: time-stamp event flag
+      \arg        RTC_FLAG_ALARM0: alarm event flag
+      \arg        RTC_FLAG_RSYN: time and date registers synchronized event flag
+    \param[out] none
+    \retval     none
+*/
+void rtc_flag_clear(uint32_t flag)
+{
+    RTC_STAT &= (uint32_t)(~flag);  
+}
+
+/*!
+    \brief      configure rtc alternate output source
+    \param[in]  source: specify signal to output
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC 
+                                         is the default value, output 512Hz signal
+      \arg        RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC 
+                                       is the default value, output 512Hz signal
+      \arg        RTC_ALARM_HIGH: when the  alarm flag is set, the output pin is high
+      \arg        RTC_ALARM_LOW: when the  Alarm flag is set, the output pin is low
+    \param[in]  mode: specify the output pin (PC13) mode when output alarm signal
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_ALARM_OUTPUT_OD: open drain mode
+      \arg        RTC_ALARM_OUTPUT_PP: push pull mode
+    \param[out] none
+    \retval     none
+*/
+void rtc_alter_output_config(uint32_t source, uint32_t mode)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS);
+
+    RTC_CTL |= (uint32_t)(source);
+    
+    /* alarm output */
+    if((uint32_t)RESET != (source & RTC_OS_ENABLE)){
+        RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL);
+        RTC_TAMP |= (uint32_t)(mode);  
+    }
+    
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      configure RTC calibration register
+    \param[in]  window: select calibration window
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz
+      \arg        RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz
+      \arg        RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz
+    \param[in]  plus: add RTC clock or not
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock
+      \arg        RTC_CALIBRATION_PLUS_RESET: no effect
+    \param[in]  minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus)
+{
+    uint32_t time_index = RTC_HRFC_TIMEOUT;
+    ErrStatus error_status = ERROR;
+    uint32_t flag_status = RESET;
+    
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;    
+    
+    /* check if a calibration operation is ongoing */        
+    do{
+        flag_status = RTC_STAT & RTC_STAT_SCPF;
+    }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status));
+    
+    if((uint32_t)RESET == flag_status){
+        RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus));
+        error_status = SUCCESS;
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      adjust the daylight saving time by adding or substracting one hour from the current time
+    \param[in]  operation: hour ajustment operation
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_CTL_A1H: add one hour
+      \arg        RTC_CTL_S1H: substract one hour
+    \param[out] none
+    \retval     none
+*/
+void rtc_hour_adjust(uint32_t operation)
+{
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL |= (uint32_t)(operation);
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      adjust RTC second or subsecond value of current time
+    \param[in]  add: add 1s to current time or not
+                only one parameter can be selected which is shown as below:
+      \arg        RTC_SHIFT_ADD1S_RESET: no effect
+      \arg        RTC_SHIFT_ADD1S_SET: add 1s to current time
+    \param[in]  minus: number of subsecond to minus from current time(0x0 - 0x7FFF)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus)
+{
+    uint32_t time_index = RTC_SHIFTCTL_TIMEOUT;
+    ErrStatus error_status = ERROR;
+    uint32_t flag_status = RESET;
+    uint32_t temp=0U;
+
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+    
+    /* check if a shift operation is ongoing */    
+    do{
+        flag_status = RTC_STAT & RTC_STAT_SOPF;
+    }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status));
+  
+    temp = RTC_CTL & RTC_CTL_REFEN;
+    /* check if the function of reference clock detection is disabled */
+    if(((uint32_t)RESET == flag_status) && (RESET == temp)){  
+        RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus));
+        error_status = rtc_register_sync_wait();        
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      enable RTC bypass shadow registers function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_bypass_shadow_enable(void)
+{ 
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      disable RTC bypass shadow registers function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void rtc_bypass_shadow_disable(void)
+{ 
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD;
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+}
+
+/*!
+    \brief      enable RTC reference clock detection function
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_refclock_detection_enable(void)
+{
+    ErrStatus error_status = ERROR;
+    
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){
+        RTC_CTL |= (uint32_t)RTC_CTL_REFEN;
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}
+
+/*!
+    \brief      disable RTC reference clock detection function
+    \param[in]  none
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus rtc_refclock_detection_disable(void)
+{
+    ErrStatus error_status = ERROR;
+    
+    /* disable the write protection */
+    RTC_WPK = RTC_UNLOCK_KEY1;
+    RTC_WPK = RTC_UNLOCK_KEY2;
+
+    /* enter init mode */
+    error_status = rtc_init_mode_enter();
+
+    if(ERROR != error_status){ 
+        RTC_CTL &= (uint32_t)~RTC_CTL_REFEN;
+        /* exit init mode */
+        rtc_init_mode_exit();
+    }
+
+    /* enable the write protection */
+    RTC_WPK = RTC_LOCK_KEY;
+
+    return error_status;
+}

+ 1003 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c

@@ -0,0 +1,1003 @@
+/*!
+    \file    gd32e230_spi.c
+    \brief   SPI driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_spi.h"
+
+/* SPI/I2S parameter initialization mask */
+#define SPI_INIT_MASK                        ((uint32_t)0x00003040U)  /*!< SPI0 parameter initialization mask */
+#define SPI_FIFO_INIT_MASK1                  ((uint32_t)0x00003840U)  /*!< SPI1 parameter initialization mask1 */
+#define SPI_FIFO_INIT_MASK2                  ((uint32_t)0x0000F0FFU)  /*!< SPI1 parameter initialization mask2*/
+#define I2S_INIT_MASK                        ((uint32_t)0x0000F047U)  /*!< I2S parameter initialization mask */
+
+#define SPI_FRAMESIZE_MASK                   ((uint32_t)0x00000800U)  /*!< SPI0 frame size mask */
+#define SPI_BYTEN_MASK                       ((uint32_t)0x00001000U)  /*!< SPI1 access to FIFO mask */
+#define SPI_TXLVL_EMPTY_MASK                 ((uint32_t)0x00001800U)  /*!< SPI1 TXFIFO empty mask */
+#define SPI_RXLVL_EMPTY_MASK                 ((uint32_t)0x00000600U)  /*!< SPI1 RXFIFO empty mask */
+
+/* I2S clock source selection, multiplication and division mask */
+#define SPI_I2SPSC_RESET                     ((uint32_t)0x00000002U)  /*!< I2S clock prescaler register reset value */
+
+/*!
+    \brief      reset SPI and I2S 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_deinit(uint32_t spi_periph)
+{
+    switch(spi_periph){
+    case SPI0:
+        /* reset SPI0 and I2S0 */
+        rcu_periph_reset_enable(RCU_SPI0RST);
+        rcu_periph_reset_disable(RCU_SPI0RST);
+        break;
+    case SPI1:
+        /* reset SPI1 */
+        rcu_periph_reset_enable(RCU_SPI1RST);
+        rcu_periph_reset_disable(RCU_SPI1RST);
+        break;
+    default :
+        break;
+    }
+}
+
+/*!
+    \brief      initialize the parameters of SPI struct with the default values
+    \param[in]  spi_struct: SPI parameter stuct
+    \param[out] none
+    \retval     none
+*/
+void spi_struct_para_init(spi_parameter_struct* spi_struct)
+{
+    /* set the SPI struct with the default values */
+    spi_struct->device_mode = SPI_SLAVE;
+    spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX;
+    spi_struct->frame_size = SPI_FRAMESIZE_8BIT;
+    spi_struct->nss = SPI_NSS_HARD;
+    spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
+    spi_struct->prescale = SPI_PSC_2;
+}
+
+/*!
+    \brief      initialize SPI parameter
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  spi_struct: SPI parameter initialization stuct members of the structure 
+                            and the member values are shown as below:
+                  device_mode: SPI_MASTER, SPI_SLAVE
+                  trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY,
+                              SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT
+                  frame_size: SPI_FRAMESIZE_4BIT, SPI_FRAMESIZE_5BIT
+                              SPI_FRAMESIZE_6BIT, SPI_FRAMESIZE_7BIT
+                              SPI_FRAMESIZE_8BIT, SPI_FRAMESIZE_9BIT
+                              SPI_FRAMESIZE_10BIT, SPI_FRAMESIZE_11BIT
+                              SPI_FRAMESIZE_12BIT, SPI_FRAMESIZE_13BIT
+                              SPI_FRAMESIZE_14BIT, SPI_FRAMESIZE_15BIT
+                              SPI_FRAMESIZE_16BIT
+                  nss: SPI_NSS_SOFT, SPI_NSS_HARD
+                  endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB
+                  clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE
+                                        SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE
+                  prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256)
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct)
+{   
+    uint32_t reg1, reg2, reg3 = 0U;
+    
+    reg1 = SPI_CTL0(spi_periph);
+    reg1 &= SPI_INIT_MASK;
+    
+    reg2 = SPI_CTL0(spi_periph);
+    reg2 &= SPI_FIFO_INIT_MASK1;
+
+    reg3 = SPI_CTL1(spi_periph);
+    reg3 &= SPI_FIFO_INIT_MASK2;
+
+    if( SPI0 == spi_periph){
+        /* select SPI as master or slave */
+        reg1 |= spi_struct->device_mode;
+        /* select SPI transfer mode */
+        reg1 |= spi_struct->trans_mode;
+        /* select SPI NSS use hardware or software */
+        reg1 |= spi_struct->nss;
+        /* select SPI LSB or MSB */
+        reg1 |= spi_struct->endian;
+        /* select SPI polarity and phase */
+        reg1 |= spi_struct->clock_polarity_phase;
+        /* select SPI prescale to adjust transmit speed */
+        reg1 |= spi_struct->prescale;
+        /* select SPI frame size */
+        /* check SPI0 frame size is 8bits/16bits or not*/
+        if((SPI_FRAMESIZE_8BIT != spi_struct->frame_size) && (SPI_FRAMESIZE_16BIT != spi_struct->frame_size))
+        {
+            return ERROR;
+        }else{
+            reg1 |= (spi_struct->frame_size & SPI_FRAMESIZE_MASK);
+        }
+        
+        /* write to SPI_CTL0 register */
+        SPI_CTL0(spi_periph) = (uint32_t)reg1;
+    
+    }else{
+        /* select SPI as master or slave */
+        reg2 |= spi_struct->device_mode;
+        /* select SPI transfer mode */
+        reg2 |= spi_struct->trans_mode;
+        /* select SPI NSS use hardware or software */
+        reg2 |= spi_struct->nss;
+        /* select SPI LSB or MSB */
+        reg2 |= spi_struct->endian;
+        /* select SPI polarity and phase */
+        reg2 |= spi_struct->clock_polarity_phase;
+        /* select SPI prescale to adjust transmit speed */
+        reg2 |= spi_struct->prescale;
+        /* write to SPI_CTL0 register */
+        SPI_CTL0(spi_periph) = (uint32_t)reg2;
+
+        /* select SPI data size */
+        reg3 |= spi_struct->frame_size;
+        /* write to SPI_CTL0 register */
+        SPI_CTL1(spi_periph) = (uint32_t)reg3;
+    }
+    
+    /* select SPI mode */
+    SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
+    
+    return SUCCESS;
+}
+
+/*!
+    \brief      enable SPI
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_enable(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN;
+}
+
+/*!
+    \brief      disable SPI 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_disable(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
+}
+
+/*!
+    \brief      initialize I2S parameter 
+    \param[in]  spi_periph: SPIx(x=0)
+    \param[in]  mode: I2S operation mode
+                only one parameter can be selected which is shown as below:
+      \arg        I2S_MODE_SLAVETX: I2S slave transmit mode
+      \arg        I2S_MODE_SLAVERX: I2S slave receive mode
+      \arg        I2S_MODE_MASTERTX: I2S master transmit mode
+      \arg        I2S_MODE_MASTERRX: I2S master receive mode
+    \param[in]  standard: I2S standard
+                only one parameter can be selected which is shown as below:
+      \arg        I2S_STD_PHILLIPS: I2S phillips standard
+      \arg        I2S_STD_MSB: I2S MSB standard
+      \arg        I2S_STD_LSB: I2S LSB standard
+      \arg        I2S_STD_PCMSHORT: I2S PCM short standard
+      \arg        I2S_STD_PCMLONG: I2S PCM long standard
+    \param[in]  ckpl: I2S idle state clock polarity
+                only one parameter can be selected which is shown as below:
+      \arg        I2S_CKPL_LOW: I2S clock polarity low level
+      \arg        I2S_CKPL_HIGH: I2S clock polarity high level
+    \param[out] none
+    \retval     none
+*/
+void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl)
+{
+    uint32_t reg = 0U;
+    reg = SPI_I2SCTL(spi_periph);
+    reg &= I2S_INIT_MASK;
+
+    /* enable I2S mode */
+    reg |= (uint32_t)SPI_I2SCTL_I2SSEL; 
+    /* select I2S mode */
+    reg |= (uint32_t)mode;
+    /* select I2S standard */
+    reg |= (uint32_t)standard;
+    /* select I2S polarity */
+    reg |= (uint32_t)ckpl;
+
+    /* write to SPI_I2SCTL register */
+    SPI_I2SCTL(spi_periph) = (uint32_t)reg;
+}
+
+/*!
+    \brief      configure I2S prescaler 
+    \param[in]  spi_periph: SPIx(x=0)
+    \param[in]  audiosample: I2S audio sample rate
+                only one parameter can be selected which is shown as below:
+      \arg        I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz
+      \arg        I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz
+      \arg        I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz
+      \arg        I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz
+      \arg        I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz
+      \arg        I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz
+      \arg        I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz
+      \arg        I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz
+      \arg        I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz
+    \param[in]  frameformat: I2S data length and channel length
+                only one parameter can be selected which is shown as below:
+      \arg        I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
+      \arg        I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
+      \arg        I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
+      \arg        I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
+    \param[in]  mckout: I2S master clock output
+                only one parameter can be selected which is shown as below:
+      \arg        I2S_MCKOUT_ENABLE: I2S master clock output enable
+      \arg        I2S_MCKOUT_DISABLE: I2S master clock output disable
+    \param[out] none
+    \retval     none
+*/
+void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout)
+{
+    uint32_t i2sdiv = 2U, i2sof = 0U;
+    uint32_t clks = 0U;
+    uint32_t i2sclock = 0U;
+
+    /* deinit SPI_I2SPSC register */
+    SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET;
+
+    /* get system clock */
+    i2sclock = rcu_clock_freq_get(CK_SYS);
+    
+    /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
+    if(I2S_MCKOUT_ENABLE == mckout){
+        clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample);
+    }else{
+        if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){
+            clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample);
+        }else{
+            clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample);
+        }
+    }
+    
+    /* remove the floating point */
+    clks = (clks + 5U) / 10U;
+    i2sof = (clks & 0x00000001U);
+    i2sdiv = ((clks - i2sof) / 2U);
+    i2sof  = (i2sof << 8U);
+
+    /* set the default values */
+    if((i2sdiv < 2U) || (i2sdiv > 255U)){
+        i2sdiv = 2U;
+        i2sof = 0U;
+    }
+
+    /* configure SPI_I2SPSC */
+    SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | mckout);
+
+    /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */
+    SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN));
+    /* configure data frame format */
+    SPI_I2SCTL(spi_periph) |= (uint32_t)frameformat;
+}
+
+
+/*!
+    \brief      enable I2S 
+    \param[in]  spi_periph: SPIx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void i2s_enable(uint32_t spi_periph)
+{
+    SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
+}
+
+/*!
+    \brief      disable I2S 
+    \param[in]  spi_periph: SPIx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void i2s_disable(uint32_t spi_periph)
+{
+    SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
+}
+
+/*!
+    \brief      enable SPI NSS output 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_output_enable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
+}
+
+/*!
+    \brief      disable SPI NSS output 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_output_disable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV);
+}
+
+/*!
+    \brief      SPI NSS pin high level in software mode
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_internal_high(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS;
+}
+
+/*!
+    \brief      SPI NSS pin low level in software mode
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_nss_internal_low(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS);
+}
+
+/*!
+    \brief      enable SPI DMA send or receive 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  dma: SPI DMA mode
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_DMA_TRANSMIT: SPI transmit data using DMA
+      \arg        SPI_DMA_RECEIVE: SPI receive data using DMA
+    \param[out] none
+    \retval     none
+*/
+void spi_dma_enable(uint32_t spi_periph, uint8_t dma)
+{
+    if(SPI_DMA_TRANSMIT == dma){
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
+    }else{
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
+    }
+}
+
+/*!
+    \brief      disable SPI DMA send or receive 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  dma: SPI DMA mode
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_DMA_TRANSMIT: SPI transmit data using DMA
+      \arg        SPI_DMA_RECEIVE: SPI receive data using DMA
+    \param[out] none
+    \retval     none
+*/
+void spi_dma_disable(uint32_t spi_periph, uint8_t dma)
+{
+    if(SPI_DMA_TRANSMIT == dma){
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN);
+    }else{
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN);
+    }
+}
+
+/*!
+    \brief      configure SPI/I2S data frame format
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  frame_format: SPI frame size
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_FRAMESIZE_4BIT: SPI frame size is 4 bits
+      \arg        SPI_FRAMESIZE_5BIT: SPI frame size is 5 bits
+      \arg        SPI_FRAMESIZE_6BIT: SPI frame size is 6 bits
+      \arg        SPI_FRAMESIZE_7BIT: SPI frame size is 7 bits
+      \arg        SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits
+      \arg        SPI_FRAMESIZE_9BIT: SPI frame size is 9 bits
+      \arg        SPI_FRAMESIZE_10BIT: SPI frame size is 10 bits
+      \arg        SPI_FRAMESIZE_11BIT: SPI frame size is 11 bits
+      \arg        SPI_FRAMESIZE_12BIT: SPI frame size is 12 bits
+      \arg        SPI_FRAMESIZE_13BIT: SPI frame size is 13 bits
+      \arg        SPI_FRAMESIZE_14BIT: SPI frame size is 14 bits
+      \arg        SPI_FRAMESIZE_15BIT: SPI frame size is 15 bits
+      \arg        SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits
+    \param[out] none
+    \retval     ErrStatus: ERROR or SUCCESS
+*/
+ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format)
+{
+    if(SPI0 == spi_periph)
+    {
+        /* check SPI0 frame size is 8bits/16bits or not*/
+        if((SPI_FRAMESIZE_8BIT != frame_format) && (SPI_FRAMESIZE_16BIT != frame_format))
+        {
+            return ERROR;
+        }else{
+            /* clear SPI_CTL0_FF16 bit */
+            SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16);
+            /* configure SPI_CTL0_FF16 bit */
+            SPI_CTL0(spi_periph) |= ((uint32_t)frame_format & SPI_FRAMESIZE_MASK);
+        }
+    }
+    else{
+        /* clear SPI_CTL1_DZ bits */
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DZ);
+        /* confige SPI_CTL1_DZ bits */
+        SPI_CTL1(spi_periph) |= (uint32_t)frame_format;
+    }
+    return SUCCESS;
+}
+
+/*!
+    \brief      SPI transmit data
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  data: 16-bit data
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data)
+{
+    uint32_t reg, byten;
+    if(SPI0 == spi_periph)
+    {
+        SPI_DATA(spi_periph) = (uint32_t)data;
+    }
+    else
+    {
+        /* get the access size to FIFO */
+        byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK;
+        if(RESET != byten)
+        {
+            reg = spi_periph + 0x0CU;
+            *( uint8_t *)(reg) = (uint8_t)data;
+        }else
+        {
+            SPI_DATA(spi_periph) = (uint16_t)data;
+        }
+    }
+}
+
+/*!
+    \brief      SPI receive data
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     16-bit data
+*/
+uint16_t spi_i2s_data_receive(uint32_t spi_periph)
+{
+    uint32_t reg, byten;
+    if(SPI0 == spi_periph)
+    {
+        return ((uint16_t)SPI_DATA(spi_periph));
+    }
+    else
+    {
+        /* get the access size to FIFO */
+        byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK;
+        if(RESET != byten)
+        {
+            reg = spi_periph + 0x0CU;
+            return (uint16_t)(*(uint8_t *)(reg));
+        }else
+        {
+            return ((uint16_t)SPI_DATA(spi_periph));
+        }
+    }
+}
+
+/*!
+    \brief      configure SPI bidirectional transfer direction
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  transfer_direction: SPI transfer direction
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode
+      \arg        SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode
+    \param[out] none
+    \retval     none
+*/
+void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction)
+{
+    if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){
+        /* set the transmit-only mode */
+        SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT;
+    }else{
+        /* set the receive-only mode */
+        SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE;
+    }
+}
+
+/*!
+    \brief      set SPI CRC polynomial 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  crc_poly: CRC polynomial value
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly)
+{
+    /* enable SPI CRC */
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
+    /* set SPI CRC polynomial */
+    SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly;
+}
+
+/*!
+    \brief      get SPI CRC polynomial 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     16-bit CRC polynomial
+*/
+uint16_t spi_crc_polynomial_get(uint32_t spi_periph)
+{
+    return ((uint16_t)SPI_CRCPOLY(spi_periph));
+}
+
+/*!
+    \brief      turn on CRC function 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_on(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
+}
+
+/*!
+    \brief      turn off CRC function 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_off(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
+}
+
+/*!
+    \brief      SPI next data is CRC value
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_next(uint32_t spi_periph)
+{
+    SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT;
+}
+
+/*!
+    \brief      get SPI CRC send value or receive value
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  crc: SPI crc value
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_CRC_TX: get transmit crc value
+      \arg        SPI_CRC_RX: get receive crc value
+    \param[out] none
+    \retval     16-bit CRC value
+*/
+uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc)
+{
+    if(SPI_CRC_TX == crc){
+        return ((uint16_t)(SPI_TCRC(spi_periph)));
+    }else{
+        return ((uint16_t)(SPI_RCRC(spi_periph)));
+    }
+}
+
+/*!
+    \brief      enable SPI TI mode
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_ti_mode_enable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD;
+}
+
+/*!
+    \brief      disable SPI TI mode
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_ti_mode_disable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD);
+}
+
+/*!
+    \brief      enable SPI NSS pulse mode
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_nssp_mode_enable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSP;
+}
+
+/*!
+    \brief      disable SPI NSS pulse mode
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_nssp_mode_disable(uint32_t spi_periph)
+{
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSP);
+}
+
+/*!
+    \brief      enable quad wire SPI
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[out] none
+    \retval     none
+*/
+void qspi_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD;
+}
+
+/*!
+    \brief      disable quad wire SPI 
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[out] none
+    \retval     none
+*/
+void qspi_disable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD);
+}
+
+/*!
+    \brief      enable quad wire SPI write 
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[out] none
+    \retval     none
+*/
+void qspi_write_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD);
+}
+
+/*!
+    \brief      enable quad wire SPI read 
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[out] none
+    \retval     none
+*/
+void qspi_read_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD;
+}
+
+/*!
+    \brief      enable SPI_IO2 and SPI_IO3 pin output 
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[out] none
+    \retval     none
+*/
+void qspi_io23_output_enable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV;
+}
+
+ /*!
+    \brief      disable SPI_IO2 and SPI_IO3 pin output 
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[out] none
+    \retval     none
+*/
+ void qspi_io23_output_disable(uint32_t spi_periph)
+{
+    SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
+}
+
+/*!
+    \brief      enable SPI and I2S interrupt 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  interrupt: SPI/I2S interrupt
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_I2S_INT_TBE: transmit buffer empty interrupt
+      \arg        SPI_I2S_INT_RBNE: receive buffer not empty interrupt
+      \arg        SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
+                                   transmission underrun error and format error interrupt
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt)
+{
+    switch(interrupt){
+    /* SPI/I2S transmit buffer empty interrupt */
+    case SPI_I2S_INT_TBE:
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE;
+        break;
+    /* SPI/I2S receive buffer not empty interrupt */
+    case SPI_I2S_INT_RBNE:
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE;
+        break;
+    /* SPI/I2S error */
+    case SPI_I2S_INT_ERR:
+        SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      disable SPI and I2S interrupt 
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  interrupt: SPI/I2S interrupt
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_I2S_INT_TBE: transmit buffer empty interrupt
+      \arg        SPI_I2S_INT_RBNE: receive buffer not empty interrupt
+      \arg        SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
+                                   transmission underrun error and format error interrupt
+    \param[out] none
+    \retval     none
+*/
+void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt)
+{
+    switch(interrupt){
+    /* SPI/I2S transmit buffer empty interrupt */
+    case SPI_I2S_INT_TBE:
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE);
+        break;
+    /* SPI/I2S receive buffer not empty interrupt */
+    case SPI_I2S_INT_RBNE:
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE);
+        break;
+    /* SPI/I2S error */
+    case SPI_I2S_INT_ERR:
+        SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE);
+        break;
+    default :
+        break;
+    }
+}
+
+/*!
+    \brief      get SPI and I2S interrupt flag status
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  interrupt: SPI/I2S interrupt flag status
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag
+      \arg        SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag
+      \arg        SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag
+      \arg        SPI_INT_FLAG_CONFERR: config error interrupt flag
+      \arg        SPI_INT_FLAG_CRCERR: CRC error interrupt flag
+      \arg        I2S_INT_FLAG_TXURERR: underrun error interrupt flag
+      \arg        SPI_I2S_INT_FLAG_FERR: format error interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt)
+{
+    uint32_t reg1 = SPI_STAT(spi_periph);
+    uint32_t reg2 = SPI_CTL1(spi_periph);
+
+    switch(interrupt){
+    /* SPI/I2S transmit buffer empty interrupt */
+    case SPI_I2S_INT_FLAG_TBE:
+        reg1 = reg1 & SPI_STAT_TBE;
+        reg2 = reg2 & SPI_CTL1_TBEIE;
+        break;
+    /* SPI/I2S receive buffer not empty interrupt */
+    case SPI_I2S_INT_FLAG_RBNE:
+        reg1 = reg1 & SPI_STAT_RBNE;
+        reg2 = reg2 & SPI_CTL1_RBNEIE;
+        break;
+    /* SPI/I2S overrun interrupt */
+    case SPI_I2S_INT_FLAG_RXORERR:
+        reg1 = reg1 & SPI_STAT_RXORERR;
+        reg2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    /* SPI config error interrupt */
+    case SPI_INT_FLAG_CONFERR:
+        reg1 = reg1 & SPI_STAT_CONFERR;
+        reg2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    /* SPI CRC error interrupt */
+    case SPI_INT_FLAG_CRCERR:
+        reg1 = reg1 & SPI_STAT_CRCERR;
+        reg2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    /* I2S underrun error interrupt */
+    case I2S_INT_FLAG_TXURERR:
+        reg1 = reg1 & SPI_STAT_TXURERR;
+        reg2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    /* SPI/I2S format error interrupt */
+    case SPI_I2S_INT_FLAG_FERR:
+        reg1 = reg1 & SPI_STAT_FERR;
+        reg2 = reg2 & SPI_CTL1_ERRIE;
+        break;
+    default :
+        break;
+    }
+    /*get SPI/I2S interrupt flag status */
+    if((0U != reg1) && (0U != reg2)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      get SPI and I2S flag status
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[in]  flag: SPI/I2S flag status
+                one or more parameters can be selected which are shown as below:
+      \arg        SPI_FLAG_TBE: transmit buffer empty flag
+      \arg        SPI_FLAG_RBNE: receive buffer not empty flag
+      \arg        SPI_FLAG_TRANS: transmit on-going flag
+      \arg        SPI_FLAG_RXORERR: receive overrun error flag
+      \arg        SPI_FLAG_CONFERR: mode config error flag
+      \arg        SPI_FLAG_CRCERR: CRC error flag
+      \arg        SPI_FLAG_FERR: format error interrupt flag
+      \arg        I2S_FLAG_TBE: transmit buffer empty flag
+      \arg        I2S_FLAG_RBNE: receive buffer not empty flag
+      \arg        I2S_FLAG_TRANS: transmit on-going flag
+      \arg        I2S_FLAG_RXORERR: overrun error flag
+      \arg        I2S_FLAG_TXURERR: underrun error flag
+      \arg        I2S_FLAG_CH: channel side flag
+                only for SPI1:
+      \arg        SPI_TXLVL_EMPTY: SPI TXFIFO is empty
+      \arg        SPI_TXLVL_QUARTER_FULL: SPI TXFIFO is a quarter of full
+      \arg        SPI_TXLVL_HAlF_FULL: SPI TXFIFO is a half of full
+      \arg        SPI_TXLVL_FULL: SPI TXFIFO is full
+      \arg        SPI_RXLVL_EMPTY: SPI RXFIFO is empty
+      \arg        SPI_RXLVL_QUARTER_FULL: SPI RXFIFO is a quarter of full
+      \arg        SPI_RXLVL_HAlF_FULL: SPI RXFIFO is a half of full
+      \arg        SPI_RXLVL_FULL: SPI RXFIFO is full
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag)
+{
+    if(RESET != (SPI_STAT(spi_periph) & flag)){
+        return SET;
+    }else{
+        if(SPI1 == spi_periph){
+            /* check TXFIFO is empty or not */
+            if(SPI_TXLVL_EMPTY == flag){
+                if(RESET != (SPI_STAT(spi_periph) & SPI_TXLVL_EMPTY_MASK)){
+                    return RESET;
+                }else{
+                    return SET;
+                }
+            }
+            /* check RXFIFO is empty or not */
+            if(SPI_RXLVL_EMPTY == flag){
+                if(RESET != (SPI_STAT(spi_periph) & SPI_RXLVL_EMPTY_MASK)){
+                    return RESET;
+                }else{
+                    return SET;
+                }
+            }
+        }
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear SPI CRC error flag status
+    \param[in]  spi_periph: SPIx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_error_clear(uint32_t spi_periph)
+{
+    SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR);
+}
+
+/*!
+    \brief      configure SPI1 access size to FIFO(8bit or 16bit)
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[in]  fifo_access_size: byte access enable
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_HALFWORD_ACCESS: half-word access to FIFO
+      \arg        SPI_BYTE_ACCESS: byte access to FIFO
+    \param[out] none
+    \retval     none
+*/
+void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size)
+{
+    /* clear SPI_CTL1_BYTEN bit */
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_BYTEN);
+    /* confige SPI_CTL1_BYTEN bit */
+    SPI_CTL1(spi_periph) |= (uint32_t)fifo_access_size;
+}
+
+/*!
+    \brief      configure SPI1 total number of data to transmit by DMA is odd or not
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[in]  odd: odd bytes in TX DMA channel
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_TXDMA_EVEN: number of byte in TX DMA channel is even
+      \arg        SPI_TXDMA_ODD: number of byte in TX DMA channel is odd
+    \param[out] none
+    \retval     none
+*/
+void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd)
+{
+    /* clear SPI_CTL1_TXDMA_ODD bit */
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TXDMA_ODD);
+    /* confige SPI_CTL1_TXDMA_ODD bit */
+    SPI_CTL1(spi_periph) |= (uint32_t)odd;
+}
+
+/*!
+    \brief      configure SPI1 total number of data to receive by DMA is odd or not
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[in]  odd: odd bytes in RX DMA channel
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_RXDMA_EVEN: number of bytes in RX DMA channel is even
+      \arg        SPI_RXDMA_ODD: number of bytes in RX DMA channel is odd
+    \param[out] none
+    \retval     none
+*/
+void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd)
+{
+    /* clear SPI_CTL1_RXDMA_ODD bit */
+    SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RXDMA_ODD);
+    /* confige SPI_CTL1_RXDMA_ODD bit */
+    SPI_CTL1(spi_periph) |= (uint32_t)odd;
+}
+
+/*!
+    \brief      set CRC length
+    \param[in]  spi_periph: SPIx(x=1)
+    \param[in]  crc_length: CRC length
+                only one parameter can be selected which is shown as below:
+      \arg        SPI_CRC_8BIT: CRC length is 8 bits
+      \arg        SPI_CRC_16BIT: CRC length is 16 bits
+    \param[out] none
+    \retval     none
+*/
+void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length)
+{
+    /* clear SPI_CTL0_CRCL bit */
+    SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCL);
+    /* confige SPI_CTL0_CRCL bit */
+    SPI_CTL0(spi_periph) |= (uint32_t)crc_length;
+}

+ 207 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c

@@ -0,0 +1,207 @@
+ /*!
+    \file    gd32e230_syscfg.h
+    \brief   SYSCFG driver
+
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_syscfg.h"
+
+/*!
+    \brief      reset the SYSCFG registers
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void syscfg_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_CFGCMPRST);
+    rcu_periph_reset_disable(RCU_CFGCMPRST);
+}
+
+/*!
+    \brief      enable the DMA channels remapping
+    \param[in]  syscfg_dma_remap: specify the DMA channels to remap
+      \arg        SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
+      \arg        SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
+      \arg        SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
+      \arg        SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
+      \arg        SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
+      \arg        SYSCFG_PA11_REMAP_PA12: remap PA11 PA12
+    \param[out] none
+    \retval     none
+*/
+void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap)
+{
+    SYSCFG_CFG0 |= syscfg_dma_remap;
+}
+
+/*!
+    \brief      disable the DMA channels remapping
+    \param[in]  syscfg_dma_remap: specify the DMA channels to remap
+      \arg        SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
+      \arg        SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
+      \arg        SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
+      \arg        SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
+      \arg        SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
+      \arg        SYSCFG_PA11_REMAP_PA12: remap PA11 PA12
+    \param[out] none
+    \retval     none
+*/
+void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap)
+{
+    SYSCFG_CFG0 &= ~syscfg_dma_remap;
+}
+
+/*!
+    \brief      enable PB9 high current capability
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void syscfg_high_current_enable(void)
+{
+    SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE;
+}
+
+/*!
+    \brief      disable PB9 high current capability
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void syscfg_high_current_disable(void)
+{
+    SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE;
+}
+
+/*!
+    \brief      configure the GPIO pin as EXTI Line
+    \param[in]  exti_port: specify the GPIO port used in EXTI
+      \arg        EXTI_SOURCE_GPIOx(x = A,B,C,F): EXTI GPIO port
+    \param[in]  exti_pin: specify the EXTI line
+      \arg        EXTI_SOURCE_PINx(GPIOA x = 0..15,GPIOB x = 0..15,GPIOC x = 13..15,GPIOF x = 0.1.6.7): EXTI GPIO pin
+    \param[out] none
+    \retval     none
+*/
+void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin)
+{
+    uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin)));
+    uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin));
+
+    switch(exti_pin / EXTI_SS_JSTEP){
+    case EXTISS0:
+        /* clear EXTI source line(0..3) */
+        SYSCFG_EXTISS0 &= clear_exti_mask;
+        /* configure EXTI soure line(0..3) */
+        SYSCFG_EXTISS0 |= config_exti_mask;
+        break;
+    case EXTISS1:
+        /* clear EXTI soure line(4..7) */
+        SYSCFG_EXTISS1 &= clear_exti_mask;
+        /* configure EXTI soure line(4..7) */
+        SYSCFG_EXTISS1 |= config_exti_mask;
+        break;
+    case EXTISS2:
+        /* clear EXTI soure line(8..11) */
+        SYSCFG_EXTISS2 &= clear_exti_mask;
+        /* configure EXTI soure line(8..11) */
+        SYSCFG_EXTISS2 |= config_exti_mask;
+        break;
+    case EXTISS3:
+        /* clear EXTI soure line(12..15) */
+        SYSCFG_EXTISS3 &= clear_exti_mask;
+        /* configure EXTI soure line(12..15) */
+        SYSCFG_EXTISS3 |= config_exti_mask;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      connect TIMER0/14/15/16 break input to the selected parameter
+    \param[in]  syscfg_lock: Specify the parameter to be connected
+      \arg        SYSCFG_LOCK_LOCKUP: Cortex-M23 lockup output connected to the break input
+      \arg        SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY check error connected to the break input
+      \arg        SYSCFG_LOCK_LVD: LVD interrupt connected to the break input
+    \param[out] none
+    \retval     none
+*/
+void syscfg_lock_config(uint32_t syscfg_lock)
+{
+    SYSCFG_CFG2 |= syscfg_lock;
+}
+
+/*!
+    \brief      set the wait state counter value
+    \param[in]  irq_latency: IRQ_LATENCY value (0x00 - 0xFF)
+    \param[out] none
+    \retval     none
+*/
+void irq_latency_set(uint8_t irq_latency)
+{
+    uint32_t reg;
+    
+    reg = SYSCFG_CPU_IRQ_LAT &(~(uint32_t)SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY);
+    reg |= (uint32_t)(IRQ_LATENCY(irq_latency));
+    
+    SYSCFG_CPU_IRQ_LAT = (uint32_t)reg;
+}
+/*!
+    \brief      check if the specified flag in SYSCFG_CFG2 is set or not.
+    \param[in]  syscfg_flag: specify the flag in SYSCFG_CFG2 to check.
+      \arg        SYSCFG_SRAM_PCEF: SRAM parity check error flag.
+    \param[out] none
+    \retval     the syscfg_flag state returned (SET or RESET).
+  */
+FlagStatus syscfg_flag_get(uint32_t syscfg_flag)
+{
+    if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear the flag in SYSCFG_CFG2 by writing 1.
+    \param[in]  syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear.
+      \arg        SYSCFG_SRAM_PCEF: SRAM parity check error flag.
+    \param[out] none
+    \retval     none
+*/
+void syscfg_flag_clear(uint32_t syscfg_flag)
+{
+    SYSCFG_CFG2 |= (uint32_t) syscfg_flag;
+}
+

+ 2059 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c

@@ -0,0 +1,2059 @@
+/*!
+    \file    gd32e230_timer.c
+    \brief   TIMER driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_timer.h"
+
+/* TIMER init parameter mask */
+#define ALIGNEDMODE_MASK            ((uint32_t)0x00000060U)   /*!< TIMER init parameter aligne dmode mask */
+#define COUNTERDIRECTION_MASK       ((uint32_t)0x00000010U)   /*!< TIMER init parameter counter direction mask */
+#define CLOCKDIVISION_MASK          ((uint32_t)0x00000300U)   /*!< TIMER init parameter clock division value mask */
+
+/*!
+    \brief      deinit a TIMER
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_deinit(uint32_t timer_periph)
+{
+    switch(timer_periph){
+    case TIMER0:
+        /* reset TIMER0 */
+        rcu_periph_reset_enable(RCU_TIMER0RST);
+        rcu_periph_reset_disable(RCU_TIMER0RST);
+        break;
+    case TIMER2:
+        /* reset TIMER2 */
+        rcu_periph_reset_enable(RCU_TIMER2RST);
+        rcu_periph_reset_disable(RCU_TIMER2RST);
+        break;
+    case TIMER5:
+        /* reset TIMER5 */
+        rcu_periph_reset_enable(RCU_TIMER5RST);
+        rcu_periph_reset_disable(RCU_TIMER5RST);
+        break;
+    case TIMER13:
+        /* reset TIMER13 */
+        rcu_periph_reset_enable(RCU_TIMER13RST);
+        rcu_periph_reset_disable(RCU_TIMER13RST);
+        break;
+    case TIMER14:
+        /* reset TIMER14 */
+        rcu_periph_reset_enable(RCU_TIMER14RST);
+        rcu_periph_reset_disable(RCU_TIMER14RST);
+        break;
+    case TIMER15:
+        /* reset TIMER15 */
+        rcu_periph_reset_enable(RCU_TIMER15RST);
+        rcu_periph_reset_disable(RCU_TIMER15RST);
+        break;
+    case TIMER16:
+        /* reset TIMER16 */
+        rcu_periph_reset_enable(RCU_TIMER16RST);
+        rcu_periph_reset_disable(RCU_TIMER16RST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      initialize TIMER init parameter struct with a default value
+    \param[in]  initpara: init parameter struct
+    \param[out] none
+    \retval     none
+*/
+void timer_struct_para_init(timer_parameter_struct* initpara)
+{
+    /* initialize the init parameter struct member with the default value */
+    initpara->prescaler         = 0U;
+    initpara->alignedmode       = TIMER_COUNTER_EDGE;
+    initpara->counterdirection  = TIMER_COUNTER_UP;
+    initpara->period            = 65535U;
+    initpara->clockdivision     = TIMER_CKDIV_DIV1;
+    initpara->repetitioncounter = 0U;
+}
+
+/*!
+    \brief      initialize TIMER counter
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[in]  initpara: init parameter struct
+                  prescaler: prescaler value of the counter clock, 0~65535
+                  alignedmode: TIMER_COUNTER_EDGE, TIMER_COUNTER_CENTER_DOWN, TIMER_COUNTER_CENTER_UP, TIMER_COUNTER_CENTER_BOTH
+                  counterdirection: TIMER_COUNTER_UP, TIMER_COUNTER_DOWN
+                  period: counter auto reload value, 0~65535
+                  clockdivision: TIMER_CKDIV_DIV1, TIMER_CKDIV_DIV2, TIMER_CKDIV_DIV4
+                  repetitioncounter: counter repetition value, 0~255
+    \param[out] none
+    \retval     none
+*/
+void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara)
+{
+    /* configure the counter prescaler value */
+    TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler;
+
+    /* configure the counter direction and aligned mode */
+    if((TIMER0 == timer_periph) || (TIMER2 == timer_periph)){
+        TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR|TIMER_CTL0_CAM);
+        TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode;
+        TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection;
+    }
+
+    /* configure the autoreload value */
+    TIMER_CAR(timer_periph) = (uint32_t)initpara->period;
+    
+    if((TIMER0 == timer_periph) || (TIMER2 == timer_periph) || (TIMER13 == timer_periph)
+        || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){
+        /* reset the CKDIV bit */
+        TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV;
+        TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision;
+    }
+
+    if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){
+        /* configure the repetition counter value */
+        TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter;
+    }
+
+    /* generate an update event */
+    TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG;
+}
+
+/*!
+    \brief      enable a TIMER
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_enable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN;
+}
+
+/*!
+    \brief      disable a TIMER
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_disable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN;
+}
+
+/*!
+    \brief      enable the auto reload shadow function
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_auto_reload_shadow_enable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE;
+}
+
+/*!
+    \brief      disable the auto reload shadow function
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_auto_reload_shadow_disable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE;
+}
+
+/*!
+    \brief      enable the update event
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_update_event_enable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS;
+}
+
+/*!
+    \brief      disable the update event
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_update_event_disable(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS;
+}
+
+/*!
+    \brief      set TIMER counter alignment mode
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  aligned:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_COUNTER_EDGE: edge-aligned mode
+      \arg        TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode
+      \arg        TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode
+      \arg        TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode
+    \param[out] none
+    \retval     none
+*/
+void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CAM;
+    TIMER_CTL0(timer_periph) |= (uint32_t)aligned;
+}
+
+/*!
+    \brief      set TIMER counter up direction
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[out] none
+    \retval     none
+*/
+void timer_counter_up_direction(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR;
+}
+
+/*!
+    \brief      set TIMER counter down direction
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[out] none
+    \retval     none
+*/
+void timer_counter_down_direction(uint32_t timer_periph)
+{
+    TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR;
+}
+
+/*!
+    \brief      configure TIMER prescaler
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[in]  prescaler: prescaler value,0~65535
+    \param[in]  pscreload: prescaler reload mode
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now
+      \arg        TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event
+    \param[out] none
+    \retval     none
+*/
+void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload)
+{
+    TIMER_PSC(timer_periph) = (uint32_t)prescaler;
+    
+    if(TIMER_PSC_RELOAD_NOW == pscreload){
+        TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG;
+    }
+}
+
+/*!
+    \brief      configure TIMER repetition register value
+    \param[in]  timer_periph: TIMERx(x=0,15,16)
+    \param[in]  repetition: the counter repetition value,0~255
+    \param[out] none
+    \retval     none
+*/
+void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition)
+{
+    TIMER_CREP(timer_periph) = (uint32_t)repetition;
+} 
+ 
+/*!
+    \brief      configure TIMER autoreload register value
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[in]  autoreload: the counter auto-reload value,0~65535
+    \param[out] none
+    \retval     none
+*/         
+void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload)
+{
+    TIMER_CAR(timer_periph) = (uint32_t)autoreload;
+}
+
+/*!
+    \brief      configure TIMER counter register value
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[in]  counter: the counter value,0~65535
+    \param[out] none
+    \retval     none
+*/         
+void timer_counter_value_config(uint32_t timer_periph, uint16_t counter)
+{
+    TIMER_CNT(timer_periph) = (uint32_t)counter;
+}
+
+/*!
+    \brief      read TIMER counter value
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     counter value
+*/         
+uint32_t timer_counter_read(uint32_t timer_periph)
+{
+    uint32_t count_value = 0U;
+    count_value = TIMER_CNT(timer_periph);
+    return (count_value);
+}
+
+/*!
+    \brief      read TIMER prescaler value
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[out] none
+    \retval     prescaler register value
+*/         
+uint16_t timer_prescaler_read(uint32_t timer_periph)
+{
+    uint16_t prescaler_value = 0U;
+    prescaler_value = (uint16_t)(TIMER_PSC(timer_periph));
+    return (prescaler_value);
+}
+
+/*!
+    \brief      configure TIMER single pulse mode
+    \param[in]  timer_periph: TIMERx(x=0,2,5,14..16)
+    \param[in]  spmode:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_SP_MODE_SINGLE: single pulse mode
+      \arg        TIMER_SP_MODE_REPETITIVE: repetitive pulse mode
+    \param[out] none
+    \retval     none
+*/
+void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode)
+{
+    if(TIMER_SP_MODE_SINGLE == spmode){
+        TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM;
+    }else if(TIMER_SP_MODE_REPETITIVE == spmode){
+        TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM);
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure TIMER update source 
+    \param[in]  timer_periph: TIMERx(x=0,2,5,13..16)
+    \param[in]  update:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger
+      \arg        TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow
+    \param[out] none
+    \retval     none
+*/
+void timer_update_source_config(uint32_t timer_periph, uint32_t update)
+{
+    if(TIMER_UPDATE_SRC_REGULAR == update){
+        TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS;
+    }else if(TIMER_UPDATE_SRC_GLOBAL == update){
+        TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure TIMER OCPRE clear source selection
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  ocpreclear:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OCPRE_CLEAR_SOURCE_CLR: OCPRE_CLR_INT is connected to the OCPRE_CLR input
+      \arg        TIMER_OCPRE_CLEAR_SOURCE_ETIF: OCPRE_CLR_INT is connected to ETIF
+    \param[out] none
+    \retval     none
+*/
+void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear)
+{
+    if(TIMER_OCPRE_CLEAR_SOURCE_ETIF == ocpreclear){
+        TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_OCRC;
+    }else if(TIMER_OCPRE_CLEAR_SOURCE_CLR == ocpreclear){
+        TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_OCRC;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      enable the TIMER interrupt
+    \param[in]  timer_periph: please refer to the following parameters 
+    \param[in]  interrupt: timer interrupt enable source
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13..16)
+      \arg        TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,14)
+      \arg        TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2)
+      \arg        TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0,2)
+      \arg        TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,14..16)
+      \arg        TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2,14)
+      \arg        TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt)
+{
+    TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; 
+}
+
+/*!
+    \brief      disable the TIMER interrupt
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  interrupt: timer interrupt source disable
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13..16)
+      \arg        TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,14)
+      \arg        TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2)
+      \arg        TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0,2)
+      \arg        TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,14..16)
+      \arg        TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2,14)
+      \arg        TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt)
+{
+    TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); 
+}
+
+/*!
+    \brief      get timer interrupt flag
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  interrupt: the timer interrupt bits
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0,2,13..16)
+      \arg        TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0,2,14)
+      \arg        TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0,2)
+      \arg        TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0,2)
+      \arg        TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,14..16)
+      \arg        TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,2,14)
+      \arg        TIMER_INT_FLAG_BRK:  break interrupt flag,TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt)
+{
+    uint32_t val;
+    val = (TIMER_DMAINTEN(timer_periph) & interrupt);
+    if((RESET != (TIMER_INTF(timer_periph) & interrupt) ) && (RESET != val)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear TIMER interrupt flag
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  interrupt: the timer interrupt bits
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0,2,13..16)
+      \arg        TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0,2,14)
+      \arg        TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0,2)
+      \arg        TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0,2)
+      \arg        TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,14..16)
+      \arg        TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,2,14)
+      \arg        TIMER_INT_FLAG_BRK:  break interrupt flag, TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt)
+{
+    TIMER_INTF(timer_periph) &= (~(uint32_t)interrupt);
+}
+
+/*!
+    \brief      get TIMER flags
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  flag: the timer interrupt flags
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_FLAG_UP: update flag, TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0,2,13..16)
+      \arg        TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0,2,14)
+      \arg        TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0,2)
+      \arg        TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0,2)
+      \arg        TIMER_FLAG_CMT: channel control update flag, TIMERx(x=0,14..16)
+      \arg        TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,2,14)
+      \arg        TIMER_FLAG_BRK: break flag,TIMERx(x=0,14..16)
+      \arg        TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,2,13..16)
+      \arg        TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,2,14)
+      \arg        TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,2)
+      \arg        TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,2)
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag)
+{
+    if(RESET != (TIMER_INTF(timer_periph) & flag)){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear TIMER flags
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  flag: the timer interrupt flags
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_FLAG_UP: update flag, TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0,2,13..16)
+      \arg        TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0,2,14)
+      \arg        TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0,2)
+      \arg        TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0,2)
+      \arg        TIMER_FLAG_CMT: channel control update flag, TIMERx(x=0,14..16)
+      \arg        TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,2,14)
+      \arg        TIMER_FLAG_BRK: break flag,TIMERx(x=0,14..16)
+      \arg        TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,2,13..16)
+      \arg        TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,2,14)
+      \arg        TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,2)
+      \arg        TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,2)
+    \param[out] none
+    \retval     none
+*/
+void timer_flag_clear(uint32_t timer_periph, uint32_t flag)
+{
+    TIMER_INTF(timer_periph) &= (~(uint32_t)flag);
+}
+
+/*!
+    \brief      enable the TIMER DMA
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  dma: specify which DMA to enable
+                one or more parameters can be selected which is shown as below:
+      \arg        TIMER_DMA_UPD: update DMA, TIMERx(x=0,2,5,14..16)
+      \arg        TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0,2,14..16)
+      \arg        TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,2,14)
+      \arg        TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,2)
+      \arg        TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,2)
+      \arg        TIMER_DMA_CMTD: commutation DMA request, TIMERx(x=0,14)
+      \arg        TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0,2,14)
+    \param[out] none
+    \retval     none
+*/
+void timer_dma_enable(uint32_t timer_periph, uint16_t dma)
+{
+    TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; 
+}
+
+/*!
+    \brief      disable the TIMER DMA
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  dma: specify which DMA to disable
+                one or more parameters can be selected which are shown as below:
+      \arg        TIMER_DMA_UPD: update DMA, TIMERx(x=0,2,5,14..16)
+      \arg        TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0,2,14..16)
+      \arg        TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,2,14)
+      \arg        TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,2)
+      \arg        TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,2)
+      \arg        TIMER_DMA_CMTD: commutation DMA request , TIMERx(x=0,14)
+      \arg        TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0,2,14)
+    \param[out] none
+    \retval     none
+*/
+void timer_dma_disable(uint32_t timer_periph, uint16_t dma)
+{
+    TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); 
+}
+
+/*!
+    \brief      channel DMA request source selection
+    \param[in]  timer_periph: TIMERx(x=0,2,14..16)
+    \param[in]  dma_request: channel DMA request source selection
+                only one parameter can be selected which is shown as below:
+       \arg        TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs
+       \arg        TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request)
+{
+    if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS;
+    }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){
+        TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure the TIMER DMA transfer
+    \param[in]  timer_periph: TIMERx(x=0,2,14..16)
+    \param[in]  dma_baseaddr:
+                only one parameter can be selected which is shown as below:
+       \arg        TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG, TIMERx(x=0,2,14)
+       \arg        TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1, TIMERx(x=0,2)
+       \arg        TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP, TIMERx(x=0,14..16)
+       \arg        TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV, TIMERx(x=0,2,14..16)
+       \arg        TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV, TIMERx(x=0,2,14)
+       \arg        TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV, TIMERx(x=0,2)
+       \arg        TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV, TIMERx(x=0,2)
+       \arg        TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP, TIMERx(x=0,14..16)
+       \arg        TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG, TIMERx(x=0,2,14..16)
+    \param[in]  dma_lenth:
+                only one parameter can be selected which is shown as below:
+       \arg        TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time
+    \param[out] none
+    \retval     none
+*/
+void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth)
+{
+    TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC));
+    TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth);
+}
+
+/*!
+    \brief      software generate events 
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  event: the timer software event generation sources
+                one or more parameters can be selected which are shown as below:
+      \arg        TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0,2,5,13..16)
+      \arg        TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation, TIMERx(x=0,2,13..16) 
+      \arg        TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation, TIMERx(x=0,2,14)
+      \arg        TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation, TIMERx(x=0,2) 
+      \arg        TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation, TIMERx(x=0,2) 
+      \arg        TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0,14..16) 
+      \arg        TIMER_EVENT_SRC_TRGG: trigger event generation, TIMERx(x=0,2,14)
+      \arg        TIMER_EVENT_SRC_BRKG:  break event generation, TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_event_software_generate(uint32_t timer_periph, uint16_t event)
+{
+    TIMER_SWEVG(timer_periph) |= (uint32_t)event;
+}
+
+/*!
+    \brief      initialize TIMER break parameter struct with a default value
+    \param[in]  breakpara: TIMER break parameter struct
+    \param[out] none
+    \retval     none
+*/
+void timer_break_struct_para_init(timer_break_parameter_struct* breakpara)
+{
+    /* initialize the break parameter struct member with the default value */
+    breakpara->runoffstate     = TIMER_ROS_STATE_DISABLE;
+    breakpara->ideloffstate    = TIMER_IOS_STATE_DISABLE;
+    breakpara->deadtime        = 0U;
+    breakpara->breakpolarity   = TIMER_BREAK_POLARITY_LOW;
+    breakpara->outputautostate = TIMER_OUTAUTO_DISABLE;
+    breakpara->protectmode     = TIMER_CCHP_PROT_OFF;
+    breakpara->breakstate      = TIMER_BREAK_DISABLE;
+}
+
+/*!
+    \brief      configure TIMER break function 
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[in]  breakpara: TIMER break parameter struct
+                runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE
+                ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE
+                deadtime: 0~255
+                breakpolarity: TIMER_BREAK_POLARITY_LOW,TIMER_BREAK_POLARITY_HIGH
+                outputautostate: TIMER_OUTAUTO_ENABLE,TIMER_OUTAUTO_DISABLE
+                protectmode: TIMER_CCHP_PROT_OFF,TIMER_CCHP_PROT_0,TIMER_CCHP_PROT_1,TIMER_CCHP_PROT_2
+                breakstate: TIMER_BREAK_ENABLE,TIMER_BREAK_DISABLE
+    \param[out] none
+    \retval     none
+*/
+void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara)
+{
+    TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate))|
+                                          ((uint32_t)(breakpara->ideloffstate))|
+                                          ((uint32_t)(breakpara->deadtime))|
+                                          ((uint32_t)(breakpara->breakpolarity))|
+                                          ((uint32_t)(breakpara->outputautostate)) |
+                                          ((uint32_t)(breakpara->protectmode))|
+                                          ((uint32_t)(breakpara->breakstate))) ;
+}
+
+/*!
+    \brief      enable TIMER break function
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_break_enable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN;
+}
+
+/*!
+    \brief      disable TIMER break function
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_break_disable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN;
+}
+
+/*!
+    \brief      enable TIMER output automatic function
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_automatic_output_enable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN;
+}
+
+/*!
+    \brief      disable TIMER output automatic function
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[out] none
+    \retval     none
+*/
+void timer_automatic_output_disable(uint32_t timer_periph)
+{
+    TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN;
+}
+
+/*!
+    \brief      configure TIMER primary output function
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[in]  newvalue: ENABLE or DISABLE
+    \param[out] none
+    \retval     none
+*/
+void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue)
+{
+    if(ENABLE == newvalue){
+        TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN;
+    }else{
+        TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN);
+    }
+}
+
+/*!
+    \brief      enable or disable channel capture/compare control shadow register
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[in]  newvalue: ENABLE or DISABLE 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue)
+{
+     if(ENABLE == newvalue){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE;
+    }else{
+        TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE);
+    }
+}
+
+/*!
+    \brief      configure TIMER channel control shadow register update control
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[in]  ccuctl: channel control shadow register update control
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set
+      \arg        TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs 
+    \param[out] none
+    \retval     none
+*/              
+void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl)
+{
+    if(TIMER_UPDATECTL_CCU == ccuctl){
+        TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC);
+    }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      initialize TIMER channel output parameter struct with a default value
+    \param[in]  ocpara: TIMER channel n output parameter struct
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara)
+{
+    /* initialize the channel output parameter struct member with the default value */
+    ocpara->outputstate  = (uint16_t)TIMER_CCX_DISABLE;
+    ocpara->outputnstate = TIMER_CCXN_DISABLE;
+    ocpara->ocpolarity   = TIMER_OC_POLARITY_HIGH;
+    ocpara->ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
+    ocpara->ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
+    ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
+}
+
+/*!
+    \brief      configure TIMER channel output function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel 0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel 1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel 2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel 3(TIMERx(x=0,2))
+    \param[in]  ocpara: TIMER channeln output parameter struct
+                outputstate: TIMER_CCX_ENABLE,TIMER_CCX_DISABLE
+                outputnstate: TIMER_CCXN_ENABLE,TIMER_CCXN_DISABLE
+                ocpolarity: TIMER_OC_POLARITY_HIGH,TIMER_OC_POLARITY_LOW
+                ocnpolarity: TIMER_OCN_POLARITY_HIGH,TIMER_OCN_POLARITY_LOW
+                ocidlestate: TIMER_OC_IDLE_STATE_LOW,TIMER_OC_IDLE_STATE_HIGH
+                ocnidlestate: TIMER_OCN_IDLE_STATE_LOW,TIMER_OCN_IDLE_STATE_HIGH
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS;
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputstate;
+        /* reset the CH0P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P);
+        /* set the CH0P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity;
+
+        if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){
+            /* reset the CH0NEN bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN);
+            /* set the CH0NEN bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate;
+            /* reset the CH0NP bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP);
+            /* set the CH0NP bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity;
+            /* reset the ISO0 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0);
+            /* set the ISO0 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate;
+            /* reset the ISO0N bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N);
+            /* set the ISO0N bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate;
+        }
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS;
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 4U);
+        /* reset the CH1P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P);
+        /* set the CH1P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 4U);
+
+        if(TIMER0 == timer_periph){
+            /* reset the CH1NEN bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN);
+            /* set the CH1NEN bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 4U);
+            /* reset the CH1NP bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP);
+            /* set the CH1NP bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 4U);
+            /* reset the ISO1 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1);
+            /* set the ISO1 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U);
+            /* reset the ISO1N bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N);
+            /* set the ISO1N bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 2U);
+        }
+        
+        if(TIMER14 == timer_periph){
+            /* reset the ISO1 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1);
+            /* set the ISO1 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U);
+        }
+        
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        /* reset the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN);
+        TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS;
+        /* set the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 8U);
+        /* reset the CH2P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P);
+        /* set the CH2P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 8U);
+
+        if(TIMER0 == timer_periph){
+            /* reset the CH2NEN bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN);
+            /* set the CH2NEN bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 8U);
+            /* reset the CH2NP bit */
+            TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP);
+            /* set the CH2NP bit */
+            TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 8U);
+            /* reset the ISO2 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2);
+            /* set the ISO2 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 4U);
+            /* reset the ISO2N bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N);
+            /* set the ISO2N bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 4U);
+        }
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        /* reset the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN);
+        TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS;
+        /* set the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 12U);
+        /* reset the CH3P bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P);
+        /* set the CH3P bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 12U);
+
+        if(TIMER0 == timer_periph){
+            /* reset the ISO3 bit */
+            TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3);
+            /* set the ISO3 bit */
+            TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 6U);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output compare mode
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  ocmode: channel output compare mode
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OC_MODE_TIMING: timing mode
+      \arg        TIMER_OC_MODE_ACTIVE: active mode
+      \arg        TIMER_OC_MODE_INACTIVE: inactive mode
+      \arg        TIMER_OC_MODE_TOGGLE: toggle mode
+      \arg        TIMER_OC_MODE_LOW: force low mode
+      \arg        TIMER_OC_MODE_HIGH: force high mode
+      \arg        TIMER_OC_MODE_PWM0: PWM0 mode
+      \arg        TIMER_OC_MODE_PWM1: PWM1 mode
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)ocmode;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output pulse value
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  pulse: channel output pulse value,0~65535
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CH0CV(timer_periph) = (uint32_t)pulse;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CH1CV(timer_periph) = (uint32_t)pulse;
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CH2CV(timer_periph) = (uint32_t)pulse;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+         TIMER_CH3CV(timer_periph) = (uint32_t)pulse;
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output shadow function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  ocshadow: channel output shadow state
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OC_SHADOW_ENABLE: channel output shadow state enable
+      \arg        TIMER_OC_SHADOW_DISABLE: channel output shadow state disable
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)ocshadow;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output fast function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  ocfast: channel output fast function
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OC_FAST_ENABLE: channel output fast function enable
+      \arg        TIMER_OC_FAST_DISABLE: channel output fast function disable
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output clear function
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  occlear: channel output clear function
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OC_CLEAR_ENABLE: channel output clear function enable
+      \arg        TIMER_OC_CLEAR_DISABLE: channel output clear function disable
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)occlear;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel output polarity 
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  ocpolarity: channel output polarity 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OC_POLARITY_HIGH: channel output polarity is high
+      \arg        TIMER_OC_POLARITY_LOW: channel output polarity is low
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 8U);
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 12U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel complementary output polarity 
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  channel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel2(TIMERx(x=0,2))
+    \param[in]  ocnpolarity: channel complementary output polarity 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high
+      \arg        TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8U);
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3NP);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 12U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel enable state
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  state: TIMER channel enable state
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CCX_ENABLE: channel enable 
+      \arg        TIMER_CCX_DISABLE: channel disable 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)state;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 8U);
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 12U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure TIMER channel complementary output enable state
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,14..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0))
+    \param[in]  ocnstate: TIMER channel complementary output enable state
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CCXN_ENABLE: channel complementary enable 
+      \arg        TIMER_CCXN_DISABLE: channel complementary disable 
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN);
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      initialize TIMER channel input parameter struct with a default value
+    \param[in]  icpara: TIMER channel intput parameter struct
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara)
+{
+    /* initialize the channel input parameter struct member with the default value */
+    icpara->icpolarity  = TIMER_IC_POLARITY_RISING;
+    icpara->icselection = TIMER_IC_SELECTION_DIRECTTI;
+    icpara->icprescaler = TIMER_IC_PSC_DIV1;
+    icpara->icfilter    = 0U;
+}
+
+/*!
+    \brief      configure TIMER input capture parameter 
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+     \param[in]  icpara: TIMER channel intput parameter struct
+                 icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_BOTH_EDGE
+                 icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI,TIMER_IC_SELECTION_ITS
+                 icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8
+                 icfilter: 0~15
+    \param[out]  none
+    \retval      none
+*/
+void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic_parameter_struct* icpara)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity);
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection);
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U);
+
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+        break;
+    
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+
+        /* reset the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U);
+
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        /* reset the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN);
+
+        /* reset the CH2P and CH2NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U);
+
+        /* reset the CH2MS bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection));
+
+        /* reset the CH2CAPFLT bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U);
+
+        /* set the CH2EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        /* reset the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN);
+
+        /* reset the CH3P and CH3NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P|TIMER_CHCTL2_CH3NP));
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 12U);
+
+        /* reset the CH3MS bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U);
+
+        /* reset the CH3CAPFLT bit */
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U);
+
+        /* set the CH3EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN;
+        break;
+    default:
+        break;
+    }
+    /* configure TIMER channel input capture prescaler value */
+    timer_channel_input_capture_prescaler_config(timer_periph, channel, (uint16_t)(icpara->icprescaler));
+}
+
+/*!
+    \brief      configure TIMER channel input capture prescaler value
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[in]  prescaler: channel input capture prescaler value
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_IC_PSC_DIV1: no prescaler
+      \arg        TIMER_IC_PSC_DIV2: divided by 2
+      \arg        TIMER_IC_PSC_DIV4: divided by 4
+      \arg        TIMER_IC_PSC_DIV8: divided by 8
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler)
+{
+    switch(channel){
+    /* configure TIMER_CH_0 */
+    case TIMER_CH_0:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC);
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)prescaler;
+        break;
+    /* configure TIMER_CH_1 */
+    case TIMER_CH_1:
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC);
+        TIMER_CHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U);
+        break;
+    /* configure TIMER_CH_2 */
+    case TIMER_CH_2:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC);
+        TIMER_CHCTL1(timer_periph) |= (uint32_t)prescaler;
+        break;
+    /* configure TIMER_CH_3 */
+    case TIMER_CH_3:
+        TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC);
+        TIMER_CHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      read TIMER channel capture compare register value
+    \param[in]  timer_periph: please refer to the following parameters
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16))
+      \arg        TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14))
+      \arg        TIMER_CH_2: TIMER channel2(TIMERx(x=0,2))
+      \arg        TIMER_CH_3: TIMER channel3(TIMERx(x=0,2))
+    \param[out] none
+    \retval     channel capture compare register value
+*/
+uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel)
+{
+    uint32_t count_value = 0U;
+
+    switch(channel){
+    /* read TIMER channel 0 capture compare register value */
+    case TIMER_CH_0:
+        count_value = TIMER_CH0CV(timer_periph);
+        break;
+    /* read TIMER channel 1 capture compare register value */
+    case TIMER_CH_1:
+        count_value = TIMER_CH1CV(timer_periph);
+        break;
+    /* read TIMER channel 2 capture compare register value */
+    case TIMER_CH_2:
+        count_value = TIMER_CH2CV(timer_periph);
+        break;
+    /* read TIMER channel 3 capture compare register value */
+    case TIMER_CH_3:
+        count_value = TIMER_CH3CV(timer_periph);
+        break;
+    default:
+        break;
+    }
+    return (count_value);
+}
+
+/*!
+    \brief      configure TIMER input pwm capture function 
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  channel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CH_0: TIMER channel0
+      \arg        TIMER_CH_1: TIMER channel1
+     \param[in]  icpwm:TIMER channel intput pwm parameter struct
+                 icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING
+                 icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI
+                 icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8
+                 icfilter: 0~15
+    \param[out] none
+    \retval     none
+*/
+void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm)
+{
+    uint16_t icpolarity  = 0x0U;
+    uint16_t icselection = 0x0U;
+
+    /* Set channel input polarity */
+    if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){
+        icpolarity = TIMER_IC_POLARITY_FALLING;
+    }else{
+        icpolarity = TIMER_IC_POLARITY_RISING;
+    }
+
+    /* Set channel input mode selection */
+    if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){
+        icselection = TIMER_IC_SELECTION_INDIRECTTI;
+    }else{
+        icselection = TIMER_IC_SELECTION_DIRECTTI;
+    }
+
+    if(TIMER_CH_0 == channel){
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+        /* set the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity);
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        /* set the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection);
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        /* set the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U);
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(icpwm->icprescaler));
+
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* reset the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+        /* set the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        /* set the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection << 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        /* set the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(icpwm->icprescaler));
+    }else{
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* reset the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+        /* set the CH1P and CH1NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icpolarity) << 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        /* set the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icselection) << 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        /* set the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler));
+
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+        /* set the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity;
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        /* set the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection;
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        /* set the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U);
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+        /* configure TIMER channel input capture prescaler value */
+        timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler));
+    }
+}
+
+/*!
+    \brief      configure TIMER hall sensor mode
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  hallmode: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable
+      \arg        TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable
+    \param[out] none
+    \retval     none
+*/
+void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode)
+{
+    if(TIMER_HALLINTERFACE_ENABLE == hallmode){
+        TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S;
+    }else if(TIMER_HALLINTERFACE_DISABLE == hallmode){
+        TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      select TIMER input trigger source 
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  intrigger:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,2))
+      \arg        TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_ETIFP: external trigger(TIMERx(x=0,2))
+    \param[out] none
+    \retval     none
+*/
+void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS);
+    TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger;
+}
+
+/*!
+    \brief      select TIMER master mode output trigger source 
+    \param[in]  timer_periph: TIMERx(x=0,2,5,14)
+    \param[in]  outrigger:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output(TIMERx(x=0,2,5,14))
+      \arg        TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0,2,5,14))
+      \arg        TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0,2,5,14))
+      \arg        TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO
+      \arg        TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0,2,14))
+      \arg        TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0,2,14))
+      \arg        TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0,2,14))
+      \arg        TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0,2,14))
+    \param[out] none
+    \retval     none
+*/
+void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger)
+{
+    TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC);
+    TIMER_CTL1(timer_periph) |= (uint32_t)outrigger;
+}
+
+/*!
+    \brief      select TIMER slave mode 
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  slavemode:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_SLAVE_MODE_DISABLE: slave mode disable(TIMERx(x=0,2,14))
+      \arg        TIMER_ENCODER_MODE0: encoder mode 0(TIMERx(x=0,2))
+      \arg        TIMER_ENCODER_MODE1: encoder mode 1(TIMERx(x=0,2))
+      \arg        TIMER_ENCODER_MODE2: encoder mode 2(TIMERx(x=0,2))
+      \arg        TIMER_SLAVE_MODE_RESTART: restart mode(TIMERx(x=0,2,14))
+      \arg        TIMER_SLAVE_MODE_PAUSE: pause mode(TIMERx(x=0,2,14))
+      \arg        TIMER_SLAVE_MODE_EVENT: event mode(TIMERx(x=0,2,14))
+      \arg        TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0(TIMERx(x=0,2,14))
+    \param[out] none
+    \retval     none
+*/
+
+void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+
+    TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode;
+}
+
+/*!
+    \brief      configure TIMER master slave mode 
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  masterslave:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable
+      \arg        TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable
+    \param[out] none
+    \retval     none
+*/ 
+void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave)
+{
+    if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave){
+        TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM;
+    }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave){
+        TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure TIMER external trigger input
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  extprescaler:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_EXT_TRI_PSC_OFF: no divided
+      \arg        TIMER_EXT_TRI_PSC_DIV2: divided by 2
+      \arg        TIMER_EXT_TRI_PSC_DIV4: divided by 4
+      \arg        TIMER_EXT_TRI_PSC_DIV8: divided by 8
+    \param[in]  extpolarity:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_ETP_FALLING: active low or falling edge active
+      \arg        TIMER_ETP_RISING: active high or rising edge active
+    \param[in]  extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler,
+                                   uint32_t extpolarity, uint32_t extfilter)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC));
+    TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity);
+    TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U);
+}
+
+/*!
+    \brief      configure TIMER quadrature decoder mode
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  decomode: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level
+      \arg        TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level
+      \arg        TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input
+    \param[in]  ic0polarity: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_IC_POLARITY_RISING: capture rising edge
+      \arg        TIMER_IC_POLARITY_FALLING: capture falling edge
+    \param[in]  ic1polarity:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_IC_POLARITY_RISING: capture rising edge
+      \arg        TIMER_IC_POLARITY_FALLING: capture falling edge
+    \param[out] none
+    \retval     none
+*/
+void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode,
+                                   uint16_t ic0polarity, uint16_t ic1polarity)
+{
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+    TIMER_SMCFG(timer_periph) |= (uint32_t)decomode;
+
+    TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS))&((~(uint32_t)TIMER_CHCTL0_CH1MS)));
+    TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U));
+
+    TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+    TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+    TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity|((uint32_t)ic1polarity << 4U));
+}
+
+/*!
+    \brief      configure TIMER internal clock mode
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[out] none
+    \retval     none
+*/
+void timer_internal_clock_config(uint32_t timer_periph)
+{
+    TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC;
+}
+
+/*!
+    \brief      configure TIMER the internal trigger as external clock input
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  intrigger: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,2,14))
+      \arg        TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,2))
+    \param[out] none
+    \retval     none
+*/
+void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger)
+{
+    timer_input_trigger_source_select(timer_periph, intrigger);
+    TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC;
+    TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0;
+}
+
+/*!
+    \brief      configure TIMER the external trigger as external clock input
+    \param[in]  timer_periph: TIMERx(x=0,2,14)
+    \param[in]  extrigger: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector
+      \arg        TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0
+      \arg        TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1
+    \param[in]  extpolarity: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_IC_POLARITY_RISING: active high or rising edge active
+      \arg        TIMER_IC_POLARITY_FALLING: active low or falling edge active
+      \arg        TIMER_IC_POLARITY_BOTH_EDGE: active both edge
+    \param[in]  extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger,
+                                       uint16_t extpolarity, uint32_t extfilter)
+{
+    if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){
+        /* reset the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN);
+        /* reset the CH1NP bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP));
+        /* set the CH1NP bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U);
+        /* reset the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS);
+        /* set the CH1MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U);
+        /* reset the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT);
+        /* set the CH1CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 8U);
+        /* set the CH1EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN;
+    }else{
+        /* reset the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN);
+        /* reset the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP));
+        /* set the CH0P and CH0NP bits */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity;
+        /* reset the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS);
+        /* set the CH0MS bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI;
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT);
+        /* reset the CH0CAPFLT bit */
+        TIMER_CHCTL0(timer_periph) |= (uint32_t)extfilter;
+        /* set the CH0EN bit */
+        TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN;
+    }
+    /* select TIMER input trigger source */
+    timer_input_trigger_source_select(timer_periph,extrigger);
+    /* reset the SMC bit */
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC);
+    /* set the SMC bit */
+    TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0;
+}
+
+/*!
+    \brief      configure TIMER the external clock mode0
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  extprescaler: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_EXT_TRI_PSC_OFF: no divided
+      \arg        TIMER_EXT_TRI_PSC_DIV2: divided by 2
+      \arg        TIMER_EXT_TRI_PSC_DIV4: divided by 4
+      \arg        TIMER_EXT_TRI_PSC_DIV8: divided by 8
+    \param[in]  extpolarity: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_ETP_FALLING: active low or falling edge active
+      \arg        TIMER_ETP_RISING: active high or rising edge active
+    \param[in]  extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler,
+                                       uint32_t extpolarity, uint32_t extfilter)
+{
+    /* configure TIMER external trigger input */
+    timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter);
+
+    /* reset the SMC bit,TRGS bit */
+    TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS));
+    /* set the SMC bit,TRGS bit */
+    TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP);
+}
+
+/*!
+    \brief      configure TIMER the external clock mode1
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[in]  extprescaler: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_EXT_TRI_PSC_OFF: no divided
+      \arg        TIMER_EXT_TRI_PSC_DIV2: divided by 2
+      \arg        TIMER_EXT_TRI_PSC_DIV4: divided by 4
+      \arg        TIMER_EXT_TRI_PSC_DIV8: divided by 8
+    \param[in]  extpolarity: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_ETP_FALLING: active low or falling edge active
+      \arg        TIMER_ETP_RISING: active high or rising edge active
+    \param[in]  extfilter: a value between 0 and 15
+    \param[out] none
+    \retval     none
+*/
+void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler,
+                                       uint32_t extpolarity, uint32_t extfilter)
+{
+    /* configure TIMER external trigger input */
+    timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter);
+
+    TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1;
+}
+
+/*!
+    \brief      disable TIMER the external clock mode1
+    \param[in]  timer_periph: TIMERx(x=0,2)
+    \param[out] none
+    \retval     none
+*/
+void timer_external_clock_mode1_disable(uint32_t timer_periph)
+{
+    TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1;
+}
+
+/*!
+    \brief      configure TIMER channel remap function
+    \param[in]  timer_periph: TIMERx(x=13)
+    \param[in]  remap: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER13_CI0_RMP_GPIO: timer13 channel 0 input is connected to GPIO(TIMER13_CH0)
+      \arg        TIMER13_CI0_RMP_RTCCLK: timer13 channel 0 input is connected to the RTCCLK
+      \arg        TIMER13_CI0_RMP_HXTAL_DIV32: timer13 channel 0 input is connected to HXTAL/32 clock
+      \arg        TIMER13_CI0_RMP_CKOUTSEL: timer13 channel 0 input is connected to CKOUTSEL
+    \param[out] none
+    \retval     none
+*/
+void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap)
+{
+    TIMER_IRMP(timer_periph) = (uint32_t)remap;
+}
+
+/*!
+    \brief      configure TIMER write CHxVAL register selection
+    \param[in]  timer_periph: TIMERx(x=0,2,13..16)
+    \param[in]  ccsel: 
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_CHVSEL_DISABLE: no effect
+      \arg        TIMER_CHVSEL_ENABLE:  when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored
+    \param[out] none
+    \retval     none
+*/
+void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel)
+{
+    if(TIMER_CHVSEL_ENABLE == ccsel){
+        TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL;
+    }else if(TIMER_CHVSEL_DISABLE == ccsel){
+        TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL;
+    }else{
+        /* illegal parameters */
+    }
+}
+
+/*!
+    \brief      configure TIMER output value selection
+    \param[in]  timer_periph: TIMERx(x=0,14..16)
+    \param[in]  outsel:
+                only one parameter can be selected which is shown as below:
+      \arg        TIMER_OUTSEL_DISABLE: no effect
+      \arg        TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled
+    \param[out] none
+    \retval     none
+*/
+void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel)
+{
+    if(TIMER_OUTSEL_ENABLE == outsel){
+        TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL;
+    }else if(TIMER_OUTSEL_DISABLE == outsel){
+        TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL;
+    }else{
+        /* illegal parameters */
+    }
+}

+ 1318 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c

@@ -0,0 +1,1318 @@
+/*!
+    \file    gd32e230_usart.c
+    \brief   USART driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_usart.h"
+
+/*!
+    \brief      reset USART
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_deinit(uint32_t usart_periph)
+{
+    switch(usart_periph){
+    case USART0:
+        /* reset USART0 */
+        rcu_periph_reset_enable(RCU_USART0RST);
+        rcu_periph_reset_disable(RCU_USART0RST);
+        break;
+    case USART1:
+        /* reset USART1 */
+        rcu_periph_reset_enable(RCU_USART1RST);
+        rcu_periph_reset_disable(RCU_USART1RST);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      configure USART baud rate value
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  baudval: baud rate value
+    \param[out] none
+    \retval     none
+*/ 
+void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval)
+{
+    uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U;
+    switch(usart_periph){
+         /* get clock frequency */
+    case USART0:
+         /* get USART0 clock */
+         uclk = rcu_clock_freq_get(CK_USART);
+         break;
+    case USART1:
+         /* get USART1 clock */
+         uclk = rcu_clock_freq_get(CK_APB1);
+         break;
+    default:
+         break;
+    }
+    if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){
+        /* oversampling by 8, configure the value of USART_BAUD */
+        udiv = ((2U*uclk)+baudval/2U)/baudval;
+        intdiv = udiv & 0x0000fff0U;
+        fradiv = (udiv>>1U) & 0x00000007U;
+        USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
+    }else{
+        /* oversampling by 16, configure the value of USART_BAUD */
+        udiv = (uclk+baudval/2U)/baudval;
+        intdiv = udiv & 0x0000fff0U;
+        fradiv = udiv & 0x0000000fU;
+        USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
+    }
+}
+
+/*!
+    \brief      configure USART parity
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  paritycfg: USART parity configure
+                only one parameter can be selected which is shown as below:
+      \arg        USART_PM_NONE: no parity
+      \arg        USART_PM_ODD: odd parity
+      \arg        USART_PM_EVEN: even parity
+    \param[out] none
+    \retval     none
+*/
+void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* clear USART_CTL0 PM,PCEN bits */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); 
+    /* configure USART parity mode */
+    USART_CTL0(usart_periph) |= paritycfg;
+}
+
+/*!
+    \brief      configure USART word length
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  wlen: USART word length configure
+                only one parameter can be selected which is shown as below:
+      \arg        USART_WL_8BIT: 8 bits
+      \arg        USART_WL_9BIT: 9 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_word_length_set(uint32_t usart_periph, uint32_t wlen)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* clear USART_CTL0 WL bit */
+    USART_CTL0(usart_periph) &= ~USART_CTL0_WL;
+    /* configure USART word length */
+    USART_CTL0(usart_periph) |= wlen;
+}
+
+/*!
+    \brief      configure USART stop bit length
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  stblen: USART stop bit configure
+                only one parameter can be selected which is shown as below:
+      \arg        USART_STB_1BIT: 1 bit
+      \arg        USART_STB_0_5BIT: 0.5bit
+      \arg        USART_STB_2BIT: 2 bits
+      \arg        USART_STB_1_5BIT: 1.5bit
+    \param[out] none
+    \retval     none
+*/
+void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* clear USART_CTL1 STB bits */
+    USART_CTL1(usart_periph) &= ~USART_CTL1_STB;
+    USART_CTL1(usart_periph) |= stblen;
+}
+
+/*!
+    \brief      enable USART
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_enable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) |= USART_CTL0_UEN;
+}
+
+/*!
+    \brief      disable USART
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_disable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+}
+
+/*!
+    \brief      configure USART transmitter
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  txconfig: enable or disable USART transmitter
+                only one parameter can be selected which is shown as below:
+      \arg        USART_TRANSMIT_ENABLE: enable USART transmission
+      \arg        USART_TRANSMIT_DISABLE: enable USART transmission
+    \param[out] none
+    \retval     none
+*/
+void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig)
+{
+    USART_CTL0(usart_periph) &= ~USART_CTL0_TEN;
+    /* configure transfer mode */
+    USART_CTL0(usart_periph) |= txconfig;
+}
+
+/*!
+    \brief      configure USART receiver
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  rxconfig: enable or disable USART receiver
+                only one parameter can be selected which is shown as below:
+      \arg        USART_RECEIVE_ENABLE: enable USART reception
+      \arg        USART_RECEIVE_DISABLE: disable USART reception
+    \param[out] none
+    \retval     none
+*/
+void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig)
+{
+    USART_CTL0(usart_periph) &= ~USART_CTL0_REN;
+    /* configure receiver mode */
+    USART_CTL0(usart_periph) |= rxconfig;
+}
+
+/*!
+    \brief      data is transmitted/received with the LSB/MSB first
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  msbf: LSB/MSB
+                only one parameter can be selected which is shown as below:
+      \arg        USART_MSBF_LSB: LSB first
+      \arg        USART_MSBF_MSB: MSB first
+    \param[out] none
+    \retval     none
+*/
+void usart_data_first_config(uint32_t usart_periph, uint32_t msbf)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* configure LSB or MSB first */
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF);
+    USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf);
+}
+
+/*!
+    \brief      USART inverted configure
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  invertpara: refer to usart_invert_enum
+                only one parameter can be selected which is shown as below:
+      \arg        USART_DINV_ENABLE: data bit level inversion
+      \arg        USART_DINV_DISABLE: data bit level not inversion
+      \arg        USART_TXPIN_ENABLE: TX pin level inversion
+      \arg        USART_TXPIN_DISABLE: TX pin level not inversion
+      \arg        USART_RXPIN_ENABLE: RX pin level inversion
+      \arg        USART_RXPIN_DISABLE: RX pin level not inversion
+      \arg        USART_SWAP_ENABLE: swap TX/RX pins
+      \arg        USART_SWAP_DISABLE: not swap TX/RX pins
+    \param[out] none
+    \retval     none
+*/
+void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* inverted or not the specified signal */
+    switch(invertpara){
+    case USART_DINV_ENABLE:
+        USART_CTL1(usart_periph) |= USART_CTL1_DINV;
+        break;
+    case USART_DINV_DISABLE:
+        USART_CTL1(usart_periph) &= ~(USART_CTL1_DINV);
+        break;
+    case USART_TXPIN_ENABLE:
+        USART_CTL1(usart_periph) |= USART_CTL1_TINV;
+        break;
+    case USART_TXPIN_DISABLE:
+        USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV);
+        break;
+    case USART_RXPIN_ENABLE:
+        USART_CTL1(usart_periph) |= USART_CTL1_RINV;
+        break;
+    case USART_RXPIN_DISABLE:
+        USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV);
+        break;
+    case USART_SWAP_ENABLE:
+        USART_CTL1(usart_periph) |= USART_CTL1_STRP;
+        break;
+    case USART_SWAP_DISABLE:
+        USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP);
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+    \brief      enable the USART overrun function
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_overrun_enable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* enable overrun function */
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD);
+}
+
+/*!
+    \brief      disable the USART overrun function
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_overrun_disable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* disable overrun function */
+    USART_CTL2(usart_periph) |= USART_CTL2_OVRD;
+}
+
+/*!
+    \brief      configure the USART oversample mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  oversamp: oversample value
+                only one parameter can be selected which is shown as below:
+      \arg        USART_OVSMOD_8: oversampling by 8
+      \arg        USART_OVSMOD_16: oversampling by 16
+    \param[out] none
+    \retval     none
+*/
+void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* clear OVSMOD bit */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD);
+    USART_CTL0(usart_periph) |= oversamp;
+}
+
+/*!
+    \brief      configure the sample bit method
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  osb: sample bit
+                only one parameter can be selected which is shown as below:
+      \arg        USART_OSB_1BIT: 1 bit
+      \arg        USART_OSB_3BIT: 3 bits
+    \param[out] none
+    \retval     none
+*/
+void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB);
+    USART_CTL2(usart_periph) |= osb;
+}
+
+/*!
+    \brief      enable receiver timeout
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_receiver_timeout_enable(uint32_t usart_periph)
+{
+    USART_CTL1(usart_periph) |= USART_CTL1_RTEN;
+}
+
+/*!
+    \brief      disable receiver timeout
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_receiver_timeout_disable(uint32_t usart_periph)
+{
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN);
+}
+
+/*!
+    \brief      configure receiver timeout threshold
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  rtimeout: 0x00000000-0x00FFFFFF, receiver timeout value in terms of number of baud clocks
+    \param[out] none
+    \retval     none
+*/
+void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout)
+{
+    USART_RT(usart_periph) &= ~(USART_RT_RT);
+    USART_RT(usart_periph) |= rtimeout;
+}
+
+/*!
+    \brief      USART transmit data function
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  data: data of transmission
+    \param[out] none
+    \retval     none
+*/
+void usart_data_transmit(uint32_t usart_periph, uint32_t data)
+{
+    USART_TDATA(usart_periph) = (USART_TDATA_TDATA & data);
+}
+
+/*!
+    \brief      USART receive data function
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     data of received
+*/
+uint16_t usart_data_receive(uint32_t usart_periph)
+{
+    return (uint16_t)(GET_BITS(USART_RDATA(usart_periph), 0U, 8U));
+}
+
+/*!
+    \brief      enable auto baud rate detection
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_autobaud_detection_enable(uint32_t usart_periph)
+{
+    USART_CTL1(usart_periph) |= USART_CTL1_ABDEN;
+}
+
+/*!
+    \brief      disable auto baud rate detection
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_autobaud_detection_disable(uint32_t usart_periph)
+{
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDEN);
+}
+
+/*!
+    \brief      configure auto baud rate detection mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  abdmod: auto baud rate detection mode
+                only one parameter can be selected which is shown as below:
+      \arg        USART_ABDM_FTOR: falling edge to rising edge measurement
+      \arg        USART_ABDM_FTOF: falling edge to falling edge measurement
+    \param[out] none
+    \retval     none
+*/
+void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod)
+{
+    /* reset ABDM bits */
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDM);
+    USART_CTL1(usart_periph) |= abdmod;
+}
+
+/*!
+    \brief      address of the USART terminal
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  addr: 0x00-0xFF, address of USART terminal
+    \param[out] none
+    \retval     none
+*/
+void usart_address_config(uint32_t usart_periph, uint8_t addr)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR);
+    USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (((uint32_t)addr) << 24));
+}
+
+/*!
+    \brief      configure address detection mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  addmod: address detection mode
+                only one parameter can be selected which is shown as below:
+      \arg        USART_ADDM_4BIT: 4 bits
+      \arg        USART_ADDM_FULLBIT: full bits
+    \param[out] none
+    \retval     none
+*/
+void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDM);
+    USART_CTL1(usart_periph) |= USART_CTL1_ADDM & (addmod);
+}
+
+/*!
+    \brief      enable mute mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_mute_mode_enable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) |= USART_CTL0_MEN;
+}
+
+/*!
+    \brief      disable mute mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_mute_mode_disable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN);
+}
+
+/*!
+    \brief      configure wakeup method in mute mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  wmethod: two methods be used to enter or exit the mute mode
+                only one parameter can be selected which is shown as below:
+      \arg        USART_WM_IDLE: idle line
+      \arg        USART_WM_ADDR: address mark
+    \param[out] none
+    \retval     none
+*/
+void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_WM);
+    USART_CTL0(usart_periph) |= wmethod;
+}
+
+/*!
+    \brief      enable LIN mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_lin_mode_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL1(usart_periph) |= USART_CTL1_LMEN;
+}
+
+/*!
+    \brief      disable LIN mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_lin_mode_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN);
+}
+
+/*!
+    \brief      LIN break detection length
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  lblen: LIN break detection length
+                only one parameter can be selected which is shown as below:
+      \arg        USART_LBLEN_10B: 10 bits break detection
+      \arg        USART_LBLEN_11B: 11 bits break detection
+    \param[out] none
+    \retval     none
+*/
+void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN);
+    USART_CTL1(usart_periph) |= USART_CTL1_LBLEN & (lblen);
+}
+
+/*!
+    \brief      enable half-duplex mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_halfduplex_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) |= USART_CTL2_HDEN;
+}
+
+/*!
+    \brief      disable half-duplex mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_halfduplex_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN);
+}
+
+/*!
+    \brief      enable clock
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_clock_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL1(usart_periph) |= USART_CTL1_CKEN;
+}
+
+/*!
+    \brief      disable clock
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_clock_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN);
+}
+
+/*!
+    \brief      configure USART synchronous mode parameters
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  clen: last bit clock pulse
+                only one parameter can be selected which is shown as below:
+      \arg        USART_CLEN_NONE: clock pulse of the last data bit (MSB) is not output to the CK pin
+      \arg        USART_CLEN_EN: clock pulse of the last data bit (MSB) is output to the CK pin
+    \param[in]  cph: clock phase
+                only one parameter can be selected which is shown as below:
+      \arg        USART_CPH_1CK: first clock transition is the first data capture edge
+      \arg        USART_CPH_2CK: second clock transition is the first data capture edge
+    \param[in]  cpl: clock polarity
+                only one parameter can be selected which is shown as below:
+      \arg        USART_CPL_LOW: steady low value on CK pin
+      \arg        USART_CPL_HIGH: steady high value on CK pin
+    \param[out] none
+    \retval     none
+*/
+void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* reset USART_CTL1 CLEN,CPH,CPL bits */
+    USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL);
+
+    USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen);
+    USART_CTL1(usart_periph) |= (USART_CTL1_CPH & cph);
+    USART_CTL1(usart_periph) |= (USART_CTL1_CPL & cpl);
+}
+
+/*!
+    \brief      configure guard time value in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  guat: 0x00-0xFF
+    \param[out] none
+    \retval     none
+*/
+void usart_guard_time_config(uint32_t usart_periph, uint32_t guat)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_GP(usart_periph) &= ~(USART_GP_GUAT);
+    USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << 8));
+}
+
+/*!
+    \brief      enable smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) |= USART_CTL2_SCEN;
+}
+
+/*!
+    \brief      disable smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN);
+}
+
+/*!
+    \brief      enable NACK in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_nack_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) |= USART_CTL2_NKEN;
+}
+
+/*!
+    \brief      disable NACK in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_nack_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN);
+}
+
+/*!
+    \brief      enable early NACK in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph)
+{
+    USART_RFCS(usart_periph) |= USART_RFCS_ELNACK;
+}
+
+/*!
+    \brief      disable early NACK in smartcard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph)
+{
+    USART_RFCS(usart_periph) &= ~USART_RFCS_ELNACK;
+}
+
+/*!
+    \brief      configure smartcard auto-retry number
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  scrtnum: 0x00000000-0x00000007, smartcard auto-retry number
+    \param[out] none
+    \retval     none
+*/
+void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_SCRTNUM);
+    USART_CTL2(usart_periph) |= (USART_CTL2_SCRTNUM & (scrtnum << 17));
+}
+
+/*!
+    \brief      configure block length
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  bl: 0x00000000-0x000000FF
+    \param[out] none
+    \retval     none
+*/
+void usart_block_length_config(uint32_t usart_periph, uint32_t bl)
+{
+    USART_RT(usart_periph) &= ~(USART_RT_BL);
+    USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << 24));
+}
+
+/*!
+    \brief      enable IrDA mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_irda_mode_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) |= USART_CTL2_IREN;
+}
+
+/*!
+    \brief      disable IrDA mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_irda_mode_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN);
+}
+
+/*!
+    \brief      configure the peripheral clock prescaler in USART IrDA low-power or SmartCard mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  psc: 0x00000000-0x000000FF
+    \param[out] none
+    \retval     none
+*/
+void usart_prescaler_config(uint32_t usart_periph, uint32_t psc)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    USART_GP(usart_periph) &= ~(USART_GP_PSC);
+    USART_GP(usart_periph) |= psc;
+}
+
+/*!
+    \brief      configure IrDA low-power
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  irlp: IrDA low-power or normal
+                only one parameter can be selected which is shown as below:
+      \arg        USART_IRLP_LOW:    low-power
+      \arg        USART_IRLP_NORMAL: normal
+    \param[out] none
+    \retval     none
+*/
+void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP);
+    USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp);
+}
+
+/*!
+    \brief      configure hardware flow control RTS
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  rtsconfig: enable or disable RTS
+                only one parameter can be selected which is shown as below:
+      \arg        USART_RTS_ENABLE:  enable RTS
+      \arg        USART_RTS_DISABLE: disable RTS
+    \param[out] none
+    \retval     none
+*/
+void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN);
+    USART_CTL2(usart_periph) |= rtsconfig;
+}
+
+/*!
+    \brief      configure hardware flow control CTS
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  ctsconfig:  enable or disable CTS
+                only one parameter can be selected which is shown as below:
+      \arg        USART_CTS_ENABLE:  enable CTS
+      \arg        USART_CTS_DISABLE: disable CTS
+    \param[out] none
+    \retval     none
+*/
+void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~USART_CTL2_CTSEN;
+    USART_CTL2(usart_periph) |= ctsconfig;
+}
+
+ /*!
+    \brief      configure hardware flow control coherence mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  hcm:
+                only one parameter can be selected which is shown as below:
+      \arg        USART_HCM_NONE: nRTS signal equals to the rxne status register
+      \arg        USART_HCM_EN:   nRTS signal is set when the last data bit has been sampled
+    \param[out] none
+    \retval     none
+*/
+void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm)
+{
+    USART_CHC(usart_periph) &= ~(USART_CHC_HCM);
+    USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm);
+}
+
+/*!
+    \brief      enable RS485 driver
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_rs485_driver_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) |= USART_CTL2_DEM;
+}
+
+/*!
+    \brief      disable RS485 driver
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_rs485_driver_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_DEM);
+}
+
+/*!
+    \brief      configure driver enable assertion time
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  deatime: 0x00000000-0x0000001F
+    \param[out] none
+    \retval     none
+*/
+void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_DEA);
+    USART_CTL0(usart_periph) |= (USART_CTL0_DEA & ((deatime) << 21));
+}
+
+/*!
+    \brief      configure driver enable de-assertion time
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  dedtime: 0x00000000-0x0000001F
+    \param[out] none
+    \retval     none
+*/
+void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_DED);
+    USART_CTL0(usart_periph) |= (USART_CTL0_DED & ((dedtime) << 16));
+}
+
+/*!
+    \brief      configure driver enable polarity mode
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  dep: DE signal
+                only one parameter can be selected which is shown as below:
+      \arg        USART_DEP_HIGH: DE signal is active high
+      \arg        USART_DEP_LOW: DE signal is active low
+    \param[out] none
+    \retval     none
+*/
+void usart_depolarity_config(uint32_t usart_periph, uint32_t dep)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* reset DEP bit */
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_DEP);
+    USART_CTL2(usart_periph) |= (USART_CTL2_DEP & dep);
+}
+
+/*!
+    \brief      configure USART DMA reception
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  dmacmd: enable or disable DMA for reception
+                only one parameter can be selected which is shown as below:
+      \arg        USART_DENR_ENABLE: DMA enable for reception
+      \arg        USART_DENR_DISABLE: DMA disable for reception
+    \param[out] none
+    \retval     none
+*/
+void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd)
+{
+    USART_CTL2(usart_periph) &= ~USART_CTL2_DENR;
+    /* configure DMA reception */
+    USART_CTL2(usart_periph) |= dmacmd;
+}
+
+/*!
+    \brief      configure USART DMA transmission
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  dmacmd: enable or disable DMA for transmission
+                only one parameter can be selected which is shown as below:
+      \arg        USART_DENT_ENABLE: DMA enable for transmission
+      \arg        USART_DENT_DISABLE: DMA disable for transmission
+    \param[out] none
+    \retval     none
+*/
+void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd)
+{
+    USART_CTL2(usart_periph) &= ~USART_CTL2_DENT;
+    /* configure DMA transmission */
+    USART_CTL2(usart_periph) |= dmacmd;
+}
+
+/*!
+    \brief      disable DMA on reception error
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_reception_error_dma_disable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) |= USART_CTL2_DDRE;
+}
+
+/*!
+    \brief      enable DMA on reception error 
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_reception_error_dma_enable(uint32_t usart_periph)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_DDRE);
+}
+
+/*!
+    \brief      enable USART to wakeup the mcu from deep-sleep mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_wakeup_enable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) |= USART_CTL0_UESM;
+}
+
+/*!
+    \brief      disable USART to wakeup the mcu from deep-sleep mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[out] none
+    \retval     none
+*/
+void usart_wakeup_disable(uint32_t usart_periph)
+{
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM);
+}
+
+/*!
+    \brief      configure the USART wakeup mode from deep-sleep mode
+    \param[in]  usart_periph: USARTx(x=0)
+    \param[in]  wum: wakeup mode
+                only one parameter can be selected which is shown as below:
+      \arg        USART_WUM_ADDR: WUF active on address match
+      \arg        USART_WUM_STARTB: WUF active on start bit
+      \arg        USART_WUM_RBNE: WUF active on RBNE
+    \param[out] none
+    \retval     none
+*/
+void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum)
+{
+    /* disable USART */
+    USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
+    /* reset WUM bit */
+    USART_CTL2(usart_periph) &= ~(USART_CTL2_WUM);
+    USART_CTL2(usart_periph) |= USART_CTL2_WUM & (wum);
+}
+
+/*!
+    \brief      enable receive FIFO
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_receive_fifo_enable(uint32_t usart_periph)
+{
+    USART_RFCS(usart_periph) |= USART_RFCS_RFEN;
+}
+
+/*!
+    \brief      disable receive FIFO
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     none
+*/
+void usart_receive_fifo_disable(uint32_t usart_periph)
+{
+    USART_RFCS(usart_periph) &= ~(USART_RFCS_RFEN);
+}
+
+/*!
+    \brief      read receive FIFO counter number
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[out] none
+    \retval     receive FIFO counter number
+*/
+uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph)
+{
+    return (uint8_t)(GET_BITS(USART_RFCS(usart_periph), 12U, 14U));
+}
+
+/*!
+    \brief      get flag in STAT/CHC/RFCS register
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  flag: flag type
+                only one parameter can be selected which is shown as below:
+      \arg        USART_FLAG_PERR: parity error flag
+      \arg        USART_FLAG_FERR: frame error flag
+      \arg        USART_FLAG_NERR: noise error flag
+      \arg        USART_FLAG_ORERR: overrun error
+      \arg        USART_FLAG_IDLE: idle line detected flag
+      \arg        USART_FLAG_RBNE: read data buffer not empty
+      \arg        USART_FLAG_TC: transmission completed
+      \arg        USART_FLAG_TBE: transmit data register empty
+      \arg        USART_FLAG_LBD: LIN break detected flag
+      \arg        USART_FLAG_CTSF: CTS change flag
+      \arg        USART_FLAG_CTS: CTS level
+      \arg        USART_FLAG_RT: receiver timeout flag
+      \arg        USART_FLAG_EB: end of block flag
+      \arg        USART_FLAG_ABDE: auto baudrate detection error
+      \arg        USART_FLAG_ABD: auto baudrate detection flag
+      \arg        USART_FLAG_BSY: busy flag
+      \arg        USART_FLAG_AM: address match flag
+      \arg        USART_FLAG_SB: send break flag
+      \arg        USART_FLAG_RWU: receiver wakeup from mute mode.
+      \arg        USART_FLAG_WU: wakeup from deep-sleep mode flag
+      \arg        USART_FLAG_TEA: transmit enable acknowledge flag
+      \arg        USART_FLAG_REA: receive enable acknowledge flag 
+      \arg        USART_FLAG_EPERR: early parity error flag
+      \arg        USART_FLAG_RFE: receive FIFO empty flag
+      \arg        USART_FLAG_RFF: receive FIFO full flag
+      \arg        USART_FLAG_RFFINT: receive FIFO full interrupt flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
+{
+    if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){
+        return SET;
+    }else{
+        return RESET;
+    }
+}
+
+/*!
+    \brief      clear USART status
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  flag: flag type
+                only one parameter can be selected which is shown as below:
+      \arg        USART_FLAG_PERR: parity error flag
+      \arg        USART_FLAG_FERR: frame error flag
+      \arg        USART_FLAG_NERR: noise detected flag
+      \arg        USART_FLAG_ORERR: overrun error flag
+      \arg        USART_FLAG_IDLE: idle line detected flag
+      \arg        USART_FLAG_TC: transmission complete flag
+      \arg        USART_FLAG_LBD: LIN break detected flag
+      \arg        USART_FLAG_CTSF: CTS change flag
+      \arg        USART_FLAG_RT: receiver timeout flag
+      \arg        USART_FLAG_EB: end of block flag
+      \arg        USART_FLAG_AM: address match flag
+      \arg        USART_FLAG_WU: wakeup from deep-sleep mode flag
+      \arg        USART_FLAG_EPERR: early parity error flag
+    \param[out] none
+    \retval     none
+*/
+void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag)
+{
+    USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag));
+}
+
+/*!
+    \brief      enable USART interrupt
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  inttype: interrupt type
+                only one parameter can be selected which is shown as below:
+      \arg        USART_INT_IDLE: idle interrupt
+      \arg        USART_INT_RBNE: read data buffer not empty interrupt and
+                                  overrun error interrupt enable interrupt
+      \arg        USART_INT_TC: transmission complete interrupt
+      \arg        USART_INT_TBE: transmit data register empty interrupt
+      \arg        USART_INT_PERR: parity error interrupt
+      \arg        USART_INT_AM: address match interrupt
+      \arg        USART_INT_RT: receiver timeout interrupt
+      \arg        USART_INT_EB: end of block interrupt
+      \arg        USART_INT_LBD: LIN break detection interrupt
+      \arg        USART_INT_ERR: error interrupt enable in multibuffer communication
+      \arg        USART_INT_CTS: CTS interrupt
+      \arg        USART_INT_WU: wakeup from deep-sleep mode interrupt
+      \arg        USART_INT_RFF: receive FIFO full interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum inttype)
+{
+    USART_REG_VAL(usart_periph, inttype) |= BIT(USART_BIT_POS(inttype));
+}
+
+/*!
+    \brief      disable USART interrupt
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  inttype: interrupt type
+                only one parameter can be selected which is shown as below:
+      \arg        USART_INT_IDLE: idle interrupt
+      \arg        USART_INT_RBNE: read data buffer not empty interrupt and
+                                  overrun error interrupt
+      \arg        USART_INT_TC: transmission complete interrupt
+      \arg        USART_INT_TBE: transmit data register empty interrupt
+      \arg        USART_INT_PERR: parity error interrupt
+      \arg        USART_INT_AM: address match interrupt
+      \arg        USART_INT_RT: receiver timeout interrupt
+      \arg        USART_INT_EB: end of block interrupt
+      \arg        USART_INT_LBD: LIN break detection interrupt
+      \arg        USART_INT_ERR: error interrupt enable in multibuffer communication
+      \arg        USART_INT_CTS: CTS interrupt
+      \arg        USART_INT_WU: wakeup from deep-sleep mode interrupt
+      \arg        USART_INT_RFF: receive FIFO full interrupt enable
+    \param[out] none
+    \retval     none
+*/
+void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum inttype)
+{
+    USART_REG_VAL(usart_periph, inttype) &= ~BIT(USART_BIT_POS(inttype));
+}
+
+/*!
+    \brief      enable USART command
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  cmdtype: command type
+                only one parameter can be selected which is shown as below:
+      \arg        USART_CMD_ABDCMD: auto baudrate detection command
+      \arg        USART_CMD_SBKCMD: send break command
+      \arg        USART_CMD_MMCMD: mute mode command
+      \arg        USART_CMD_RXFCMD: receive data flush command
+      \arg        USART_CMD_TXFCMD: transmit data flush request
+    \param[out] none
+    \retval     none
+*/
+void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype)
+{
+    USART_CMD(usart_periph) |= (cmdtype);   
+}
+
+/*!
+    \brief      get USART interrupt and flag status
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum
+                only one parameter can be selected which is shown as below:
+      \arg        USART_INT_FLAG_EB: end of block interrupt and flag
+      \arg        USART_INT_FLAG_RT: receiver timeout interrupt and flag
+      \arg        USART_INT_FLAG_AM: address match interrupt and flag 
+      \arg        USART_INT_FLAG_PERR: parity error interrupt and flag 
+      \arg        USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag 
+      \arg        USART_INT_FLAG_TC: transmission complete interrupt and flag
+      \arg        USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag
+      \arg        USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag
+      \arg        USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag
+      \arg        USART_INT_FLAG_LBD: LIN break detected interrupt and flag 
+      \arg        USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt and flag
+      \arg        USART_INT_FLAG_CTS: CTS interrupt and flag
+      \arg        USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag
+      \arg        USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error
+      \arg        USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag
+      \arg        USART_INT_FLAG_RFF: receive FIFO full interrupt and flag
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
+{
+    uint32_t intenable = 0U, flagstatus = 0U;
+    /* get the interrupt enable bit status */
+    intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
+    /* get the corresponding flag bit status */
+    flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));
+
+    if(flagstatus && intenable){
+        return SET;
+    }else{
+        return RESET; 
+    }
+}
+
+/*!
+    \brief      clear USART interrupt flag
+    \param[in]  usart_periph: USARTx(x=0,1)
+    \param[in]  flag: USART interrupt flag
+                only one parameter can be selected which is shown as below:
+      \arg        USART_INT_FLAG_PERR: parity error flag
+      \arg        USART_INT_FLAG_ERR_FERR: frame error flag
+      \arg        USART_INT_FLAG_ERR_NERR: noise detected flag
+      \arg        USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag
+      \arg        USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error
+      \arg        USART_INT_FLAG_IDLE: idle line detected flag
+      \arg        USART_INT_FLAG_TC: transmission complete flag
+      \arg        USART_INT_FLAG_LBD: LIN break detected flag
+      \arg        USART_INT_FLAG_CTS: CTS change flag
+      \arg        USART_INT_FLAG_RT: receiver timeout flag
+      \arg        USART_INT_FLAG_EB: end of block flag
+      \arg        USART_INT_FLAG_AM: address match flag
+      \arg        USART_INT_FLAG_WU: wakeup from deep-sleep mode flag
+      \arg        USART_INT_FLAG_RFF: receive FIFO full interrupt and flag
+    \param[out] none
+    \retval     none
+*/
+void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum flag)
+{
+    if(USART_INT_FLAG_RFF == flag){
+        USART_RFCS(usart_periph) &= (uint32_t)(~USART_RFCS_RFFINT);
+    }else{
+        USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(flag));
+    }
+}

+ 148 - 0
bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c

@@ -0,0 +1,148 @@
+/*!
+    \file    gd32e230_wwdgt.c
+    \brief   WWDGT driver
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32e230_wwdgt.h"
+#include "gd32e230_rcu.h"
+
+/* WWDGT_CTL register value */
+#define CTL_CNT(regval)             (BITS(0,6) & ((uint32_t)(regval) << 0U))    /*!< write value to WWDGT_CTL_CNT bit field */
+/* WWDGT_CFG register value */
+#define CFG_WIN(regval)             (BITS(0,6) & ((uint32_t)(regval) << 0U))    /*!< write value to WWDGT_CFG_WIN bit field */
+
+/*!
+    \brief      reset the window watchdog timer configuration
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_deinit(void)
+{
+    rcu_periph_reset_enable(RCU_WWDGTRST);
+    rcu_periph_reset_disable(RCU_WWDGTRST);
+}
+
+/*!
+    \brief      start the window watchdog timer counter
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_enable(void)
+{
+    WWDGT_CTL |= WWDGT_CTL_WDGTEN;
+}
+
+/*!
+    \brief      configure the window watchdog timer counter value
+    \param[in]  counter_value: 0x00000000 - 0x0000007F
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_counter_update(uint16_t counter_value)
+{
+    uint32_t reg = 0x00000000U;
+    
+    reg = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT);
+    reg |= (uint32_t)(CTL_CNT(counter_value));
+    
+    WWDGT_CTL = (uint32_t)reg;
+}
+
+/*!
+    \brief      configure counter value, window value, and prescaler divider value  
+    \param[in]  counter: 0x00000000 - 0x0000007F
+    \param[in]  window: 0x00000000 - 0x0000007F
+    \param[in]  prescaler: wwdgt prescaler value
+                only one parameter can be selected which is shown as below:
+      \arg        WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1
+      \arg        WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2
+      \arg        WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4
+      \arg        WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler)
+{
+    uint32_t reg_cfg = 0x00000000U, reg_ctl = 0x00000000U;
+
+    /* clear WIN and PSC bits, clear CNT bit */
+    reg_cfg = WWDGT_CFG &(~((uint32_t)WWDGT_CFG_WIN|(uint32_t)WWDGT_CFG_PSC));
+    reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT);
+  
+    /* configure WIN and PSC bits, configure CNT bit */
+    reg_cfg |= (uint32_t)(CFG_WIN(window));
+    reg_cfg |= (uint32_t)(prescaler);
+    reg_ctl |= (uint32_t)(CTL_CNT(counter));
+    
+    WWDGT_CFG = (uint32_t)reg_cfg;
+    WWDGT_CTL = (uint32_t)reg_ctl;
+}
+
+/*!
+    \brief      enable early wakeup interrupt of WWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_interrupt_enable(void)
+{
+    WWDGT_CFG |= WWDGT_CFG_EWIE;
+}
+
+/*!
+    \brief      check early wakeup interrupt state of WWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     FlagStatus: SET or RESET
+*/
+FlagStatus wwdgt_flag_get(void)
+{
+  if(RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)){
+        return SET;
+  }
+    return RESET;
+}
+
+/*!
+    \brief      clear early wakeup interrupt state of WWDGT
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void wwdgt_flag_clear(void)
+{
+    WWDGT_STAT &= (uint32_t)(~(uint32_t)WWDGT_STAT_EWIF);
+}

+ 33 - 0
bsp/gd32e230k-start/Libraries/SConscript

@@ -0,0 +1,33 @@
+import rtconfig
+from building import *
+
+# get current directory
+cwd = GetCurrentDir()
+
+# The set of source files associated with this SConscript file.
+
+src = Glob('GD32F30x_standard_peripheral/Source/*.c')
+src += [cwd + '/CMSIS/GD/GD32F30x/Source/system_gd32f30x.c']
+
+#add for startup script
+if rtconfig.CROSS_TOOL == 'gcc':
+    src += [cwd + '/CMSIS/GD/GD32F30x/Source/GCC/startup_gd32f30x_hd.s']
+elif rtconfig.CROSS_TOOL == 'keil':
+    src += [cwd + '/CMSIS/GD/GD32F30x/Source/ARM/startup_gd32f30x_hd.s']
+elif rtconfig.CROSS_TOOL == 'iar':
+    src += [cwd + '/CMSIS/GD/GD32F30x/Source/IAR/startup_gd32f30x_hd.s']
+
+path = [
+    cwd + '/CMSIS/GD/GD32F30x/Include',
+    cwd + '/CMSIS',
+    cwd + '/GD32F30x_standard_peripheral/Include',]
+    
+if GetDepend(['RT_USING_BSP_USB']):
+    path += [cwd + '/GD32F30x_usb_driver/Include']
+    src  += [cwd + '/GD32F30x_usb_driver/Source']
+
+CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'GD32F30X_HD']
+
+group = DefineGroup('GD32_Lib', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
+
+Return('group')

+ 14 - 0
bsp/gd32e230k-start/SConscript

@@ -0,0 +1,14 @@
+# for module compiling
+import os
+Import('RTT_ROOT')
+
+cwd = str(Dir('#'))
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 39 - 0
bsp/gd32e230k-start/SConstruct

@@ -0,0 +1,39 @@
+import os
+import sys
+import rtconfig
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+try:
+    from building import *
+except:
+    print('Cannot found RT-Thread root directory, please check RTT_ROOT')
+    print(RTT_ROOT)
+    exit(-1)
+
+TARGET = 'rtthread-gd32f30x.' + rtconfig.TARGET_EXT
+
+env = Environment(tools = ['mingw'],
+    AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+    CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+    AR = rtconfig.AR, ARFLAGS = '-rc',
+    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+if rtconfig.PLATFORM == 'iar':
+    env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
+    env.Replace(ARFLAGS = [''])
+    env.Replace(LINKCOM = env["LINKCOM"] + ' --map project.map')
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 11 - 0
bsp/gd32e230k-start/applications/SConscript

@@ -0,0 +1,11 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd     = os.path.join(str(Dir('#')), 'applications')
+src	= Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 27 - 0
bsp/gd32e230k-start/applications/main.c

@@ -0,0 +1,27 @@
+/*
+ * File      : main.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2015-07-29     Arda.Fu      first implementation
+ */
+#include <rtthread.h>
+#include <board.h>
+
+int main(void)
+{
+    /* user app entry */
+
+    return 0;
+}
+
+
+
+
+

+ 33 - 0
bsp/gd32e230k-start/drivers/SConscript

@@ -0,0 +1,33 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = os.path.join(str(Dir('#')), 'drivers')
+
+# add the general drivers.
+src = Split("""
+board.c
+drv_usart.c
+""")
+
+CPPPATH = [cwd]
+
+# add spi drivers.
+if GetDepend('RT_USING_SPI'):
+    src += ['drv_spi.c']
+    
+# add i2c drivers.
+if GetDepend('RT_USING_I2C'):
+    src += ['drv_i2c.c']
+
+# add pin drivers.
+if GetDepend('RT_USING_PIN'):
+    src += ['drv_gpio.c']
+
+# add spi flash drivers.
+if GetDepend('RT_USING_SFUD'):
+    src += ['drv_spi_flash.c']
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 87 - 0
bsp/gd32e230k-start/drivers/board.c

@@ -0,0 +1,87 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      first implementation
+ */
+#include <stdint.h>
+#include <rthw.h>
+#include <rtthread.h>
+#include <board.h>
+
+/**
+  * @brief  This function is executed in case of error occurrence.
+  * @param  None
+  * @retval None
+  */
+void Error_Handler(void)
+{
+    /* USER CODE BEGIN Error_Handler */
+    /* User can add his own implementation to report the HAL error return state */
+    while (1)
+    {
+    }
+    /* USER CODE END Error_Handler */
+}
+
+/** System Clock Configuration
+*/
+void SystemClock_Config(void)
+{
+    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
+    NVIC_SetPriority(SysTick_IRQn, 0);
+}
+
+/**
+ * This is the timer interrupt service routine.
+ *
+ */
+void SysTick_Handler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    rt_tick_increase();
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+/**
+ * This function will initial GD32 board.
+ */
+void rt_hw_board_init()
+{
+    /* NVIC Configuration */
+#define NVIC_VTOR_MASK              0x3FFFFF80
+#ifdef  VECT_TAB_RAM
+    /* Set the Vector Table base location at 0x10000000 */
+    SCB->VTOR  = (0x10000000 & NVIC_VTOR_MASK);
+#else  /* VECT_TAB_FLASH  */
+    /* Set the Vector Table base location at 0x08000000 */
+    SCB->VTOR  = (0x08000000 & NVIC_VTOR_MASK);
+#endif
+
+    SystemClock_Config();
+
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+#endif
+
+#ifdef RT_USING_CONSOLE
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif
+
+#ifdef RT_USING_HEAP   
+    rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END);
+#endif
+}
+
+/*@}*/

+ 47 - 0
bsp/gd32e230k-start/drivers/board.h

@@ -0,0 +1,47 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-09-22     Bernard      add board.h to this bsp
+ */
+
+// <<< Use Configuration Wizard in Context Menu >>>
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <gd32e230.h>
+
+// <o> Internal SRAM memory size[Kbytes] <8-64>
+//	<i>Default: 64
+#ifdef __ICCARM__
+// Use *.icf ram symbal, to avoid hardcode.
+extern char __ICFEDIT_region_RAM_end__;
+#define GD32_SRAM_END          &__ICFEDIT_region_RAM_end__
+#else
+#define GD32_SRAM_SIZE         64
+#define GD32_SRAM_END          (0x20000000 + GD32_SRAM_SIZE * 1024)
+#endif
+
+#ifdef __CC_ARM
+extern int Image$$RW_IRAM1$$ZI$$Limit;
+#define HEAP_BEGIN    (&Image$$RW_IRAM1$$ZI$$Limit)
+#elif __ICCARM__
+#pragma section="HEAP"
+#define HEAP_BEGIN    (__segment_end("HEAP"))
+#else
+extern int __bss_end;
+#define HEAP_BEGIN    (&__bss_end)
+#endif
+
+#define HEAP_END          GD32_SRAM_END
+
+#endif
+
+//*** <<< end of configuration section >>>    ***

+ 539 - 0
bsp/gd32e230k-start/drivers/drv_gpio.c

@@ -0,0 +1,539 @@
+/*
+ * File      : drv_gpio.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2015, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2017-10-20     ZYH            the first version
+ * 2018-04-23     misonyo        port to gd32f30x
+ */
+
+#include "drv_gpio.h"
+#include <rtdevice.h>
+#include <rthw.h>
+#include "gd32e230.h"
+#include "gd32e230_exti.h"
+
+#ifdef RT_USING_PIN
+
+#define __GD32_PIN(index, port, pin) {index, RCU_GPIO##port, GPIO##port, \
+        GPIO_PIN_##pin, EXTI_SOURCE_GPIO##port, EXTI_SOURCE_PIN##pin}
+#define __GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0}
+
+/* GD32 GPIO driver */
+struct pin_index
+{
+    rt_int16_t index;
+    rcu_periph_enum clk;
+    rt_uint32_t gpio_periph;
+    rt_uint32_t pin;
+	  rt_uint32_t port_src;
+	  rt_uint32_t pin_src;
+};
+
+static const struct pin_index pins[] =
+{
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(7, C, 13),
+    __GD32_PIN(8, C, 14),
+    __GD32_PIN(9, C, 15),
+    __GD32_PIN(10, F, 0),
+    __GD32_PIN(11, F, 1),
+    __GD32_PIN(12, F, 2),
+    __GD32_PIN(13, F, 3),
+    __GD32_PIN(14, F, 4),
+    __GD32_PIN(15, F, 5),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(18, F, 6),
+    __GD32_PIN(19, F, 7),
+    __GD32_PIN(20, F, 8),
+    __GD32_PIN(21, F, 9),
+    __GD32_PIN(22, F, 10),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(26, C, 0),
+    __GD32_PIN(27, C, 1),
+    __GD32_PIN(28, C, 2),
+    __GD32_PIN(29, C, 3),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(34, A, 0),
+    __GD32_PIN(35, A, 1),
+    __GD32_PIN(36, A, 2),
+    __GD32_PIN(37, A, 3),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(40, A, 4),
+    __GD32_PIN(41, A, 5),
+    __GD32_PIN(42, A, 6),
+    __GD32_PIN(43, A, 7),
+    __GD32_PIN(44, C, 4),
+    __GD32_PIN(45, C, 5),
+    __GD32_PIN(46, B, 0),
+    __GD32_PIN(47, B, 1),
+    __GD32_PIN(48, B, 2),
+    __GD32_PIN(49, F, 11),
+    __GD32_PIN(50, F, 12),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(53, F, 13),
+    __GD32_PIN(54, F, 14),
+    __GD32_PIN(55, F, 15),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(69, B, 10),
+    __GD32_PIN(70, B, 11),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(73, B, 12),
+    __GD32_PIN(74, B, 13),
+    __GD32_PIN(75, B, 14),
+    __GD32_PIN(76, B, 15),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(96, C, 6),
+    __GD32_PIN(97, C, 7),
+    __GD32_PIN(98, C, 8),
+    __GD32_PIN(99, C, 9),
+    __GD32_PIN(100, A, 8),
+    __GD32_PIN(101, A, 9),
+    __GD32_PIN(102, A, 10),
+    __GD32_PIN(103, A, 11),
+    __GD32_PIN(104, A, 12),
+    __GD32_PIN(105, A, 13),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(109, A, 14),
+    __GD32_PIN(110, A, 15),
+    __GD32_PIN(111, C, 10),
+    __GD32_PIN(112, C, 11),
+    __GD32_PIN(113, C, 12),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(133, B, 3),
+    __GD32_PIN(134, B, 4),
+    __GD32_PIN(135, B, 5),
+    __GD32_PIN(136, B, 6),
+    __GD32_PIN(137, B, 7),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN(139, B, 8),
+    __GD32_PIN(140, B, 9),
+    __GD32_PIN_DEFAULT,
+    __GD32_PIN_DEFAULT,
+};
+
+struct pin_irq_map
+{
+    rt_uint16_t pinbit;
+    IRQn_Type irqno;
+};
+static const struct pin_irq_map pin_irq_map[] =
+{
+    {GPIO_PIN_0, EXTI0_1_IRQn},
+    {GPIO_PIN_1, EXTI0_1_IRQn},
+    {GPIO_PIN_2, EXTI2_3_IRQn},
+    {GPIO_PIN_3, EXTI2_3_IRQn},
+    {GPIO_PIN_4, EXTI4_15_IRQn},
+    {GPIO_PIN_5, EXTI4_15_IRQn},
+    {GPIO_PIN_6, EXTI4_15_IRQn},
+    {GPIO_PIN_7, EXTI4_15_IRQn},
+    {GPIO_PIN_8, EXTI4_15_IRQn},
+    {GPIO_PIN_9, EXTI4_15_IRQn},
+    {GPIO_PIN_10, EXTI4_15_IRQn},
+    {GPIO_PIN_11, EXTI4_15_IRQn},
+    {GPIO_PIN_12, EXTI4_15_IRQn},
+    {GPIO_PIN_13, EXTI4_15_IRQn},
+    {GPIO_PIN_14, EXTI4_15_IRQn},
+    {GPIO_PIN_15, EXTI4_15_IRQn},
+};
+struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
+{
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+};
+
+#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
+const struct pin_index *get_pin(rt_uint8_t pin)
+{
+    const struct pin_index *index;
+
+    if (pin < ITEM_NUM(pins))
+    {
+        index = &pins[pin];
+        if (index->index == -1)
+        index = RT_NULL;
+    }
+    else
+    {
+        index = RT_NULL;
+    }
+
+    return index;
+};
+
+void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
+{
+    const struct pin_index *index;
+    rt_uint32_t pin_mode;
+	  rt_uint32_t otype;
+	  rt_uint32_t pull_up_down;
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return;
+    }
+
+    /* GPIO Periph clock enable */
+    rcu_periph_clock_enable(index->clk);
+    pin_mode = GPIO_MODE_OUTPUT;
+		otype = GPIO_OTYPE_PP;
+		pull_up_down = GPIO_PUPD_NONE;
+    
+   switch(mode)
+   {
+   case PIN_MODE_OUTPUT:
+        /* output setting */
+        break;
+   case PIN_MODE_OUTPUT_OD:
+        /* output setting: od. */
+		    otype = GPIO_OTYPE_OD;
+        break;
+   case PIN_MODE_INPUT:
+        /* input setting: not pull. */
+        pin_mode = GPIO_MODE_INPUT;
+        break;
+   case PIN_MODE_INPUT_PULLUP:
+        /* input setting: pull up. */
+        pin_mode = GPIO_MODE_INPUT;
+	      pull_up_down = GPIO_PUPD_PULLUP;
+        break;
+   case PIN_MODE_INPUT_PULLDOWN:
+        /* input setting: pull down. */
+	      pin_mode = GPIO_MODE_INPUT;
+	      pull_up_down = GPIO_PUPD_PULLDOWN;
+        break;
+   default:
+        break;
+   }
+
+	  gpio_mode_set(index->gpio_periph, pin_mode, pull_up_down, index->pin);
+    gpio_output_options_set(index->gpio_periph, otype, GPIO_OSPEED_50MHZ, index->pin);
+	 
+}
+
+void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
+{
+    const struct pin_index *index;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return;
+    }
+
+    gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value);
+}
+
+int gd32_pin_read(rt_device_t dev, rt_base_t pin)
+{
+    int value;
+    const struct pin_index *index;
+
+    value = PIN_LOW;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return value;
+    }
+
+    value = gpio_input_bit_get(index->gpio_periph, index->pin);
+
+    return value;
+}
+
+
+rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
+{
+    rt_uint8_t i;
+    for (i = 0; i < 32; i++)
+    {
+        if ((0x01 << i) == bit)
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit)
+{
+    rt_int32_t mapindex = bit2bitno(pinbit);
+    if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
+    {
+        return RT_NULL;
+    }
+    return &pin_irq_map[mapindex];
+};
+rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
+                              rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+    const struct pin_index *index;
+    rt_base_t level;
+    rt_int32_t hdr_index = -1;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_EINVAL;
+    }
+    hdr_index = bit2bitno(index->pin);
+    if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
+    {
+        return RT_EINVAL;
+    }
+
+    level = rt_hw_interrupt_disable();
+    if (pin_irq_hdr_tab[hdr_index].pin == pin &&
+        pin_irq_hdr_tab[hdr_index].hdr == hdr &&
+        pin_irq_hdr_tab[hdr_index].mode == mode &&
+        pin_irq_hdr_tab[hdr_index].args == args)
+    {
+        rt_hw_interrupt_enable(level);
+        return RT_EOK;
+    }
+    if (pin_irq_hdr_tab[hdr_index].pin != -1)
+    {
+        rt_hw_interrupt_enable(level);
+        return RT_EFULL;
+    }
+    pin_irq_hdr_tab[hdr_index].pin = pin;
+    pin_irq_hdr_tab[hdr_index].hdr = hdr;
+    pin_irq_hdr_tab[hdr_index].mode = mode;
+    pin_irq_hdr_tab[hdr_index].args = args;
+    rt_hw_interrupt_enable(level);
+
+    return RT_EOK;
+}
+rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
+{
+    const struct pin_index *index;
+    rt_base_t level;
+    rt_int32_t hdr_index = -1;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_EINVAL;
+    }
+    hdr_index = bit2bitno(index->pin);
+    if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
+    {
+        return RT_EINVAL;
+    }
+
+    level = rt_hw_interrupt_disable();
+    if (pin_irq_hdr_tab[hdr_index].pin == -1)
+    {
+        rt_hw_interrupt_enable(level);
+        return RT_EOK;
+    }
+    pin_irq_hdr_tab[hdr_index].pin = -1;
+    pin_irq_hdr_tab[hdr_index].hdr = RT_NULL;
+    pin_irq_hdr_tab[hdr_index].mode = 0;
+    pin_irq_hdr_tab[hdr_index].args = RT_NULL;
+    rt_hw_interrupt_enable(level);
+
+    return RT_EOK;
+}
+rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
+{
+    const struct pin_index *index;
+    const struct pin_irq_map *irqmap;
+    rt_base_t level;
+    rt_int32_t hdr_index = -1;
+    exti_trig_type_enum trigger_mode;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_EINVAL;
+    }
+    if (enabled == PIN_IRQ_ENABLE)
+    {
+        hdr_index = bit2bitno(index->pin);
+        if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
+        {
+            return RT_EINVAL;
+        }
+        level = rt_hw_interrupt_disable();
+        if (pin_irq_hdr_tab[hdr_index].pin == -1)
+        {
+            rt_hw_interrupt_enable(level);
+            return RT_EINVAL;
+        }
+        irqmap = &pin_irq_map[hdr_index];
+   
+        switch (pin_irq_hdr_tab[hdr_index].mode)
+        {
+            case PIN_IRQ_MODE_RISING:
+                trigger_mode = EXTI_TRIG_RISING;
+                break;
+            case PIN_IRQ_MODE_FALLING:
+                trigger_mode = EXTI_TRIG_FALLING;
+                break;
+            case PIN_IRQ_MODE_RISING_FALLING:
+                trigger_mode = EXTI_TRIG_BOTH;
+                break;
+            default:
+                rt_hw_interrupt_enable(level);
+                return RT_EINVAL;
+        }
+
+        //rcu_periph_clock_enable(RCU_AF);
+
+        /* enable and set interrupt priority */
+        nvic_irq_enable(irqmap->irqno, 5U);
+        
+        /* connect EXTI line to  GPIO pin */
+				syscfg_exti_line_config(index->port_src, index->pin_src);
+
+        /* configure EXTI line */
+        exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode);
+        exti_interrupt_flag_clear((exti_line_enum)(index->pin));
+        
+        rt_hw_interrupt_enable(level);
+    }
+    else if (enabled == PIN_IRQ_DISABLE)
+    {
+        irqmap = get_pin_irq_map(index->pin);
+        if (irqmap == RT_NULL)
+        {
+            return RT_EINVAL;
+        }
+        nvic_irq_disable(irqmap->irqno);
+    }
+    else
+    {
+        return RT_EINVAL;
+    }
+
+    return RT_EOK;
+}
+const static struct rt_pin_ops _gd32_pin_ops =
+{
+    gd32_pin_mode,
+    gd32_pin_write,
+    gd32_pin_read,
+    gd32_pin_attach_irq,
+    gd32_pin_detach_irq,
+    gd32_pin_irq_enable,
+};
+
+int rt_hw_pin_init(void)
+{
+    int result;
+
+    result = rt_device_pin_register("pin", &_gd32_pin_ops, RT_NULL);
+    
+    return result;
+}
+INIT_BOARD_EXPORT(rt_hw_pin_init);
+
+rt_inline void pin_irq_hdr(int irqno)
+{
+    if (pin_irq_hdr_tab[irqno].hdr)
+    {
+        pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
+    }
+}
+
+void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line)
+{
+    if(RESET != exti_interrupt_flag_get((exti_line_enum)(1 << exti_line)))
+    {
+        pin_irq_hdr(exti_line);
+        exti_interrupt_flag_clear((exti_line_enum)(1 << exti_line));
+    } 
+}
+void EXTI0_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(0);
+    rt_interrupt_leave();
+}
+void EXTI1_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(1);
+    rt_interrupt_leave();
+}
+void EXTI2_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(2);
+    rt_interrupt_leave();
+}
+void EXTI3_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(3);
+    rt_interrupt_leave();
+}
+void EXTI4_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(4);
+    rt_interrupt_leave();
+}
+void EXTI5_9_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(5);
+    GD32_GPIO_EXTI_IRQHandler(6);
+    GD32_GPIO_EXTI_IRQHandler(7);
+    GD32_GPIO_EXTI_IRQHandler(8);
+    GD32_GPIO_EXTI_IRQHandler(9);
+    rt_interrupt_leave();
+}
+void EXTI10_15_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GD32_GPIO_EXTI_IRQHandler(10);
+    GD32_GPIO_EXTI_IRQHandler(11);
+    GD32_GPIO_EXTI_IRQHandler(12);
+    GD32_GPIO_EXTI_IRQHandler(13);
+    GD32_GPIO_EXTI_IRQHandler(14);
+    GD32_GPIO_EXTI_IRQHandler(15);
+    rt_interrupt_leave();
+}
+
+#endif

+ 18 - 0
bsp/gd32e230k-start/drivers/drv_gpio.h

@@ -0,0 +1,18 @@
+/*
+ * File      : drv_gpio.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2015, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2015-01-05     Bernard      the first version
+ */
+#ifndef GPIO_H__
+#define GPIO_H__
+
+
+#endif

+ 381 - 0
bsp/gd32e230k-start/drivers/drv_i2c.c

@@ -0,0 +1,381 @@
+/*
+ * File      : drv_i2c.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-06-05     tanek        first implementation.
+ * 2018-04-19     misonyo      Porting for gd32f30x
+ */
+
+#include "drv_i2c.h"
+#include <rtthread.h>
+#include "gd32e230.h"
+
+#ifdef RT_USING_I2C
+
+#include <rtdevice.h>
+
+#ifdef RT_USING_I2C_BITOPS
+
+/*user can change this*/
+#define I2C_BUS_NAME  "i2c2"
+
+/*user should change this to adapt specific board*/
+#define I2C_SCL_PIN          GPIO_PIN_4
+#define I2C_SCL_PORT         GPIOE
+#define I2C_SCL_CLK          RCU_GPIOE
+#define I2C_SDA_PIN          GPIO_PIN_5
+#define I2C_SDA_PORT         GPIOE
+#define I2C_SDA_CLK          RCU_GPIOE
+
+struct gd32_i2c_bit_data
+{
+    struct
+    {
+        rcu_periph_enum clk;
+        rt_uint32_t port;
+        rt_uint32_t pin;
+    }scl, sda;
+};
+
+static void gpio_set_sda(void *data, rt_int32_t state)
+{
+    struct gd32_i2c_bit_data* bd = data;
+
+    if (state)
+    {
+        gpio_bit_set(bd->sda.port, bd->sda.pin);
+    }
+    else
+    {
+        gpio_bit_reset(bd->sda.port, bd->sda.pin);
+    }
+}
+
+static void gpio_set_scl(void *data, rt_int32_t state)
+{
+    struct gd32_i2c_bit_data* bd = data;
+    if (state)
+    {
+        gpio_bit_set(bd->scl.port, bd->scl.pin);
+    }
+    else
+    {
+        gpio_bit_reset(bd->scl.port, bd->scl.pin);
+    }
+}
+
+static rt_int32_t gpio_get_sda(void *data)
+{
+    struct gd32_i2c_bit_data* bd = data;
+
+    return gpio_input_bit_get(bd->sda.port, bd->sda.pin);
+}
+
+static rt_int32_t gpio_get_scl(void *data)
+{
+    struct gd32_i2c_bit_data* bd = data;
+
+    return gpio_input_bit_get(bd->scl.port, bd->scl.pin);
+}
+
+static void gpio_udelay(rt_uint32_t us)
+{
+    int i = ( rcu_clock_freq_get(CK_SYS) / 4000000 * us);
+    while(i)
+    {
+        i--;
+    }
+}
+
+static void drv_i2c_gpio_init(const struct gd32_i2c_bit_data* bd)
+{
+    rcu_periph_clock_enable(bd->sda.clk);
+    rcu_periph_clock_enable(bd->scl.clk);
+    gpio_init(bd->sda.port, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, bd->sda.pin);
+    gpio_init(bd->scl.port, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, bd->scl.pin);
+
+    gpio_bit_set(bd->sda.port, bd->sda.pin);
+    gpio_bit_set(bd->scl.port, bd->scl.pin);
+}
+
+#else /* use hardware i2c */
+
+struct gd32_i2c_bus
+{
+    struct rt_i2c_bus_device parent;
+    rt_uint32_t i2c_periph;
+};
+
+static int gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint16_t slave_address, rt_uint8_t* p_buffer, rt_uint16_t data_byte)
+{
+    /* wait until I2C bus is idle */
+    while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY));
+
+    /* send a start condition to I2C bus */
+    i2c_start_on_bus(i2c_periph);
+
+    /* wait until SBSEND bit is set */
+    while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND));
+
+    /* send slave address to I2C bus */
+    i2c_master_addressing(i2c_periph, slave_address<<1, I2C_RECEIVER);
+
+    /* wait until ADDSEND bit is set */
+    while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND));
+
+    /* clear the ADDSEND bit */
+    i2c_flag_clear(i2c_periph,I2C_FLAG_ADDSEND);
+
+    if(1 == data_byte){
+        /* disable acknowledge */
+        i2c_ack_config(i2c_periph,I2C_ACK_DISABLE);
+        /* send a stop condition to I2C bus */
+        i2c_stop_on_bus(i2c_periph);
+    }
+
+    /* while there is data to be read */
+    while(data_byte)
+    {
+        /* wait until the RBNE bit is set and clear it */
+        if(i2c_flag_get(i2c_periph, I2C_FLAG_RBNE))
+        {
+            /* read a byte from the EEPROM */
+            *p_buffer = i2c_data_receive(i2c_periph);
+
+            /* point to the next location where the byte read will be saved */
+            p_buffer++; 
+
+            /* decrement the read bytes counter */
+            data_byte--;
+            if(1 == data_byte)
+            {
+                /* disable acknowledge */
+                i2c_ack_config(i2c_periph,I2C_ACK_DISABLE);
+                /* send a stop condition to I2C bus */
+                i2c_stop_on_bus(i2c_periph);
+            }
+        }
+    }
+
+    /* wait until the stop condition is finished */
+    while(I2C_CTL0(i2c_periph)&0x0200);
+
+    /* enable acknowledge */
+    i2c_ack_config(i2c_periph,I2C_ACK_ENABLE);
+
+    i2c_ackpos_config(i2c_periph,I2C_ACKPOS_CURRENT);
+
+    return 0;
+}
+
+static int gd32_i2c_write(rt_uint32_t i2c_periph, uint16_t slave_address, uint8_t* p_buffer, uint16_t data_byte)
+{
+    /* wait until I2C bus is idle */
+    while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY));
+
+    /* send a start condition to I2C bus */
+    i2c_start_on_bus(i2c_periph);
+
+    /* wait until SBSEND bit is set */
+    while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND));
+
+    /* send slave address to I2C bus */
+    i2c_master_addressing(i2c_periph, slave_address<<1, I2C_TRANSMITTER);
+
+    /* wait until ADDSEND bit is set */
+    while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND));
+
+    /* clear the ADDSEND bit */
+    i2c_flag_clear(i2c_periph,I2C_FLAG_ADDSEND);
+
+    /* wait until the transmit data buffer is empty */
+    while(SET != i2c_flag_get( i2c_periph , I2C_FLAG_TBE));
+
+    /* while there is data to be read */
+    while(data_byte)
+    {
+        i2c_data_transmit(i2c_periph, *p_buffer);
+
+        /* point to the next byte to be written */
+        p_buffer++;
+
+        /* decrement the write bytes counter */
+        data_byte --;
+
+        /* wait until BTC bit is set */
+        while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC));
+    }
+
+        /* send a stop condition to I2C bus */
+    i2c_stop_on_bus(i2c_periph);
+
+    /* wait until the stop condition is finished */
+    while(I2C_CTL0(i2c_periph)&0x0200);
+
+    return 0;
+}
+
+static rt_size_t gd32_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
+{
+    struct rt_i2c_msg *msg;
+    rt_uint32_t i;
+    rt_err_t ret = RT_ERROR;
+
+    struct gd32_i2c_bus *gd32_i2c = (struct gd32_i2c_bus *)bus;
+
+    for (i = 0; i < num; i++)
+    {
+        msg = &msgs[i];
+
+        if (msg->flags & RT_I2C_ADDR_10BIT)
+        {
+            i2c_mode_addr_config(gd32_i2c->i2c_periph,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_10BITS,0);
+        }
+        else
+        {
+            i2c_mode_addr_config(gd32_i2c->i2c_periph,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,0);
+        }
+        if (msg->flags & RT_I2C_RD)
+        {
+            if (gd32_i2c_read(gd32_i2c->i2c_periph, msg->addr, msg->buf, msg->len) != 0)
+            {
+                i2c_dbg("i2c bus write failed,i2c bus stop!\n");
+                goto out;
+            }
+        }
+        else
+        {
+            if (gd32_i2c_write(gd32_i2c->i2c_periph, msg->addr, msg->buf, msg->len) != 0)
+            {
+                i2c_dbg("i2c bus write failed,i2c bus stop!\n");
+                goto out;
+            }
+        }
+    }
+    
+    ret = i;
+
+out:
+    i2c_dbg("send stop condition\n");
+
+    return ret;
+}
+
+static const struct rt_i2c_bus_device_ops i2c_ops =
+{ 
+    gd32_i2c_xfer,
+    RT_NULL,
+    RT_NULL
+};
+
+#endif /* RT_USING_I2C_BITOPS */
+
+int rt_hw_i2c_init(void)
+{
+#ifdef RT_USING_I2C_BITOPS
+    {
+        static struct rt_i2c_bus_device i2c_device;
+        static const struct gd32_i2c_bit_data _i2c_bdata =
+        {
+            /* SCL */
+            {    I2C_SCL_CLK, I2C_SCL_PORT, I2C_SCL_PIN},
+            /* SDA */
+            {    I2C_SDA_CLK, I2C_SDA_PORT, I2C_SDA_PIN},
+        };
+
+        static const struct rt_i2c_bit_ops _i2c_bit_ops =
+        {
+            (void*)&_i2c_bdata,
+            gpio_set_sda,
+            gpio_set_scl,
+            gpio_get_sda,
+            gpio_get_scl,
+            gpio_udelay,
+            1,
+            100
+        };
+
+        drv_i2c_gpio_init(&_i2c_bdata);
+
+        i2c_device.priv = (void *)&_i2c_bit_ops;
+        rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME);
+    } 
+
+#else   /* register hardware I2C */
+
+#ifdef RT_USING_I2C0
+#define I2C0_SPEED  100000
+
+    static struct gd32_i2c_bus gd32_i2c0;
+    /* enable GPIOB clock */
+    rcu_periph_clock_enable(RCU_GPIOB);
+
+    /* connect PB6 to I2C0_SCL, PB7 to I2C0_SDA */
+    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7);
+    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
+
+    /* enable I2C clock */
+    rcu_periph_clock_enable(RCU_I2C0);
+    /* configure I2C clock */
+    i2c_clock_config(I2C0,I2C0_SPEED,I2C_DTCY_2);
+
+    i2c_enable(I2C0);
+    /* enable acknowledge */
+    i2c_ack_config(I2C0,I2C_ACK_ENABLE);
+
+    rt_memset((void *)&gd32_i2c0, 0, sizeof(struct gd32_i2c_bus));
+    gd32_i2c0.parent.ops = &i2c_ops;
+    gd32_i2c0.i2c_periph = I2C0;
+    rt_i2c_bus_device_register(&gd32_i2c0.parent, "i2c0");
+#endif
+
+#ifdef RT_USING_I2C1
+#define I2C1_SPEED  100000
+
+    static struct gd32_i2c_bus gd32_i2c1;
+    /* enable GPIOB clock */
+    rcu_periph_clock_enable(RCU_GPIOB);
+
+    /* connect PB10 to I2C1_SCL, PB11 to I2C1_SDA */
+    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);
+
+    /* enable I2C clock */
+    rcu_periph_clock_enable(RCU_I2C1);
+    /* configure I2C clock */
+    i2c_clock_config(I2C1,I2C1_SPEED,I2C_DTCY_2);
+
+    i2c_enable(I2C1);
+    /* enable acknowledge */
+    i2c_ack_config(I2C1,I2C_ACK_ENABLE);
+
+    rt_memset((void *)&gd32_i2c1, 0, sizeof(struct gd32_i2c_bus));
+    gd32_i2c1.parent.ops = &i2c_ops;
+    gd32_i2c1.i2c_periph = I2C1;
+    rt_i2c_bus_device_register(&gd32_i2c1.parent, "i2c1");
+#endif
+
+#endif /* RT_USING_I2C_BITOPS */
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_i2c_init);
+
+#endif
+/* end of i2c driver */

+ 29 - 0
bsp/gd32e230k-start/drivers/drv_i2c.h

@@ -0,0 +1,29 @@
+/*
+ * File      : drv_i2c.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-06-05     tanek        first implementation.
+ */
+
+#ifndef __DRV_I2C__
+#define __DRV_I2C__
+
+
+#endif

+ 290 - 0
bsp/gd32e230k-start/drivers/drv_spi.c

@@ -0,0 +1,290 @@
+/*
+ * File      : drv_spi.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-06-05     tanek        first implementation.
+ * 2018-04-19     misonyo      Porting for gd32f30x
+ */
+
+#include "drv_spi.h"
+#include "gd32e230.h"
+#include <rtthread.h>
+
+#if defined(RT_USING_SPI) && defined(RT_USING_PIN)
+#include <rtdevice.h>
+
+#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1) && \
+    !defined(RT_USING_SPI2)
+#error "Please define at least one SPIx"
+#endif
+
+/* #define DEBUG */
+#ifdef DEBUG
+#define DEBUG_PRINTF(...)   rt_kprintf(__VA_ARGS__)
+#else
+#define DEBUG_PRINTF(...)
+#endif
+
+/* private rt-thread spi ops function */
+static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
+static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message);
+
+static struct rt_spi_ops gd32_spi_ops =
+{
+    configure,
+    xfer
+};
+
+static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration)
+{
+    spi_parameter_struct spi_init_struct;
+
+    rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data;
+
+    RT_ASSERT(device != RT_NULL);
+    RT_ASSERT(configuration != RT_NULL);
+
+    if(configuration->data_width <= 8)
+    {
+        spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
+    }
+    else if(configuration->data_width <= 16)
+    {
+        spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT;
+    }
+    else
+    {
+        return RT_EIO;
+    }
+
+    {
+        rcu_clock_freq_enum spi_src;
+        rt_uint32_t spi_apb_clock;
+        rt_uint32_t max_hz;
+
+        max_hz = configuration->max_hz;
+
+        DEBUG_PRINTF("sys   freq: %d\n", rcu_clock_freq_get(CK_SYS));
+        DEBUG_PRINTF("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2));
+        DEBUG_PRINTF("max   freq: %d\n", max_hz);
+
+        if (spi_periph == SPI1)
+        {
+            spi_src = CK_APB1;
+        }
+        else
+        {
+            spi_src = CK_APB2;
+        }
+        spi_apb_clock = rcu_clock_freq_get(spi_src);
+
+        if(max_hz >= spi_apb_clock/2)
+        {
+            spi_init_struct.prescale = SPI_PSC_2;
+        }
+        else if (max_hz >= spi_apb_clock/4)
+        {
+            spi_init_struct.prescale = SPI_PSC_4;
+        }
+        else if (max_hz >= spi_apb_clock/8)
+        {
+            spi_init_struct.prescale = SPI_PSC_8;
+        }
+        else if (max_hz >= spi_apb_clock/16)
+        {
+            spi_init_struct.prescale = SPI_PSC_16;
+        }
+        else if (max_hz >= spi_apb_clock/32)
+        {
+            spi_init_struct.prescale = SPI_PSC_32;
+        }
+        else if (max_hz >= spi_apb_clock/64)
+        {
+            spi_init_struct.prescale = SPI_PSC_64;
+        }
+        else if (max_hz >= spi_apb_clock/128)
+        {
+            spi_init_struct.prescale = SPI_PSC_128;
+        }
+        else
+        {
+            /*  min prescaler 256 */
+            spi_init_struct.prescale = SPI_PSC_256;
+        }
+    } /* baudrate */
+    
+    switch(configuration->mode & RT_SPI_MODE_3)
+    {
+    case RT_SPI_MODE_0:
+        spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
+        break;
+    case RT_SPI_MODE_1:
+        spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
+        break;
+    case RT_SPI_MODE_2:
+        spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
+        break;
+    case RT_SPI_MODE_3:
+        spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
+        break;
+    }
+    
+    /* MSB or LSB */
+    if(configuration->mode & RT_SPI_MSB)
+    {
+        spi_init_struct.endian = SPI_ENDIAN_MSB;
+    }
+    else
+    {
+        spi_init_struct.endian = SPI_ENDIAN_LSB;
+    }
+    
+    spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
+    spi_init_struct.device_mode = SPI_MASTER;
+    spi_init_struct.nss = SPI_NSS_SOFT;
+
+    spi_init(spi_periph, &spi_init_struct);
+
+    spi_crc_off(spi_periph);
+
+    spi_enable(spi_periph);
+
+    return RT_EOK;
+};
+
+static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message)
+{
+    rt_base_t gd32_cs_pin = (rt_base_t)device->parent.user_data;
+    rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data;
+    struct rt_spi_configuration * config = &device->config;
+
+    RT_ASSERT(device != NULL);
+    RT_ASSERT(message != NULL);
+
+    /* take CS */
+    if(message->cs_take)
+    {
+        rt_pin_write(gd32_cs_pin, PIN_LOW);
+        DEBUG_PRINTF("spi take cs\n");
+    }
+
+    {
+        if(config->data_width <= 8)
+        {
+            const rt_uint8_t * send_ptr = message->send_buf;
+            rt_uint8_t * recv_ptr = message->recv_buf;
+            rt_uint32_t size = message->length;
+            
+            DEBUG_PRINTF("spi poll transfer start: %d\n", size);
+
+            while(size--)
+            {
+                rt_uint8_t data = 0xFF;
+
+                if(send_ptr != RT_NULL)
+                {
+                    data = *send_ptr++;
+                }
+                
+                // Todo: replace register read/write by gd32f3 lib
+                //Wait until the transmit buffer is empty
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
+                // Send the byte
+                spi_i2s_data_transmit(spi_periph, data);
+
+                //Wait until a data is received
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
+                // Get the received data
+                data = spi_i2s_data_receive(spi_periph);
+
+                if(recv_ptr != RT_NULL)
+                {
+                    *recv_ptr++ = data;
+                }
+            }
+            DEBUG_PRINTF("spi poll transfer finsh\n");
+        }
+        else if(config->data_width <= 16)
+        {
+            const rt_uint16_t * send_ptr = message->send_buf;
+            rt_uint16_t * recv_ptr = message->recv_buf;
+            rt_uint32_t size = message->length;
+
+            while(size--)
+            {
+                rt_uint16_t data = 0xFF;
+
+                if(send_ptr != RT_NULL)
+                {
+                    data = *send_ptr++;
+                }
+
+                //Wait until the transmit buffer is empty
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
+                // Send the byte
+                spi_i2s_data_transmit(spi_periph, data);
+
+                //Wait until a data is received
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
+                // Get the received data
+                data = spi_i2s_data_receive(spi_periph);
+
+                if(recv_ptr != RT_NULL)
+                {
+                    *recv_ptr++ = data;
+                }
+            }
+        }
+    }
+
+    /* release CS */
+    if(message->cs_release)
+    {
+        rt_pin_write(gd32_cs_pin, PIN_HIGH);
+        DEBUG_PRINTF("spi release cs\n");
+    }
+
+    return message->length;
+};
+
+int gd32_hw_spi_init(void)
+{
+    int result = 0;
+#ifdef RT_USING_SPI0
+    static struct rt_spi_bus spi_bus0;
+    spi_bus0.parent.user_data = (void *)SPI0;
+
+    result = rt_spi_bus_register(&spi_bus0, "spi0", &gd32_spi_ops);
+
+    rcu_periph_clock_enable(RCU_GPIOA);
+    rcu_periph_clock_enable(RCU_SPI0);
+    /* SPI0_SCK(PA5), SPI0_MISO(PA6) and SPI0_MOSI(PA7) GPIO pin configuration */
+	  gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_7);
+    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);
+    gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_7);
+#endif
+#ifdef RT_USING_SPI1
+    static struct rt_spi_bus spi_bus1;
+    spi_bus1.parent.user_data = (void *)SPI1;
+
+    result = rt_spi_bus_register(&spi_bus1, "spi1", &gd32_spi_ops);
+
+    rcu_periph_clock_enable(RCU_SPI1);
+    rcu_periph_clock_enable(RCU_GPIOB);
+
+    /* SPI1_SCK(PB13), SPI1_MISO(PB14) and SPI1_MOSI(PB15) GPIO pin configuration */
+		gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_15);
+    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15);
+		gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_14);
+#endif
+    return result;
+}
+INIT_BOARD_EXPORT(gd32_hw_spi_init);
+#endif

+ 19 - 0
bsp/gd32e230k-start/drivers/drv_spi.h

@@ -0,0 +1,19 @@
+/*
+ * File      : gd32f30x_spi.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-01-01    aozima       first implementation.
+ */
+
+#ifndef gd32F30X_SPI_H_INCLUDED
+#define gd32F30X_SPI_H_INCLUDED
+
+
+#endif // gd32F30X_SPI_H_INCLUDED

+ 381 - 0
bsp/gd32e230k-start/drivers/drv_usart.c

@@ -0,0 +1,381 @@
+/*
+ * File      : drv_usart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      the first version
+ * 2018-04-19     misonyo      Porting for gd32f30x
+ */
+
+#include <rthw.h>
+#include <drv_usart.h>
+#include <rtthread.h>
+#include "gd32e230.h"
+
+#ifdef RT_USING_SERIAL
+
+#define UART_ENABLE_IRQ(n)            NVIC_EnableIRQ((n))
+#define UART_DISABLE_IRQ(n)           NVIC_DisableIRQ((n))
+
+#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) && \
+    !defined(RT_USING_USART2) && !defined(RT_USING_UART3)  && \
+    !defined(RT_USING_UART4)
+#error "Please define at least one UARTx"
+
+#endif
+
+#include <rtdevice.h>
+
+/* GD32 uart driver */
+// Todo: compress uart info
+struct gd32_uart
+{
+    uint32_t uart_periph;
+    IRQn_Type irqn;
+    rcu_periph_enum per_clk;
+    rcu_periph_enum tx_gpio_clk;
+    rcu_periph_enum rx_gpio_clk;
+    uint32_t tx_port;
+    uint16_t tx_pin;
+    uint32_t rx_port;
+    uint16_t rx_pin; 
+
+    struct rt_serial_device * serial;
+    char *device_name;
+};
+
+static void uart_isr(struct rt_serial_device *serial);
+
+#if defined(RT_USING_USART0)
+struct rt_serial_device serial0;
+
+void USART0_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial0);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_USART0 */
+
+#if defined(RT_USING_USART1)
+struct rt_serial_device serial1;
+
+void USART1_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial1);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART1 */
+
+#if defined(RT_USING_USART2)
+struct rt_serial_device serial2;
+
+void USART2_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial2);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART2 */
+
+#if defined(RT_USING_UART3)
+struct rt_serial_device serial3;
+
+void UART3_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial3);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#endif /* RT_USING_UART3 */
+
+#if defined(RT_USING_UART4)
+struct rt_serial_device serial4;
+
+void UART4_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    uart_isr(&serial4);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif /* RT_USING_UART4 */
+
+static const struct gd32_uart uarts[] = {
+    #ifdef RT_USING_USART0
+    {
+        USART0,                                 // uart peripheral index
+        USART0_IRQn,                            // uart iqrn
+        RCU_USART0, RCU_GPIOA, RCU_GPIOA,       // periph clock, tx gpio clock, rt gpio clock
+        GPIOA, GPIO_PIN_9,                      // tx port, tx pin
+        GPIOA, GPIO_PIN_10,                     // rx port, rx pin
+        &serial0,
+        "uart0",
+    },
+    #endif
+    
+    #ifdef RT_USING_USART1
+    {
+        USART1,                                 // uart peripheral index
+        USART1_IRQn,                            // uart iqrn
+        RCU_USART1, RCU_GPIOA, RCU_GPIOA,       // periph clock, tx gpio clock, rt gpio clock
+        GPIOA, GPIO_PIN_2,                      // tx port, tx pin
+        GPIOA, GPIO_PIN_3,                      // rx port, rx pin
+        &serial1,
+        "uart1",
+    },
+    #endif
+    
+    #ifdef RT_USING_USART2
+    {
+        USART2,                                 // uart peripheral index
+        USART2_IRQn,                            // uart iqrn
+        RCU_USART2, RCU_GPIOB, RCU_GPIOB,       // periph clock, tx gpio clock, rt gpio clock
+        GPIOB, GPIO_PIN_10,                     // tx port, tx alternate, tx pin
+        GPIOB, GPIO_PIN_11,                     // rx port, rx alternate, rx pin
+        &serial2,
+        "uart2",
+    },
+    #endif
+    
+    #ifdef RT_USING_UART3
+    {
+        UART3,                                 // uart peripheral index
+        UART3_IRQn,                            // uart iqrn
+        RCU_UART3, RCU_GPIOC, RCU_GPIOC,       // periph clock, tx gpio clock, rt gpio clock
+        GPIOC, GPIO_PIN_10,                    // tx port, tx alternate, tx pin
+        GPIOC, GPIO_PIN_11,                    // rx port, rx alternate, rx pin
+        &serial3,
+        "uart3",
+    },
+    #endif
+    
+    #ifdef RT_USING_UART4
+    {
+        UART4,                                 // uart peripheral index
+        UART4_IRQn,                            // uart iqrn
+        RCU_UART4, RCU_GPIOC, RCU_GPIOD,       // periph clock, tx gpio clock, rt gpio clock
+        GPIOC, GPIO_PIN_12,                    // tx port, tx alternate, tx pin
+        GPIOD, GPIO_PIN_2,                     // rx port, rx alternate, rx pin
+        &serial4,
+        "uart4",
+    },
+    #endif
+};
+
+
+/**
+* @brief UART MSP Initialization
+*        This function configures the hardware resources used in this example:
+*           - Peripheral's clock enable
+*           - Peripheral's GPIO Configuration
+*           - NVIC configuration for UART interrupt request enable
+* @param uart: UART handle pointer
+* @retval None
+*/
+void gd32_uart_gpio_init(struct gd32_uart *uart)
+{
+    /* enable USART clock */
+    rcu_periph_clock_enable(uart->tx_gpio_clk);
+    rcu_periph_clock_enable(uart->rx_gpio_clk);
+    rcu_periph_clock_enable(uart->per_clk);
+
+    /* connect port to USARTx_Tx */
+    gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, uart->tx_pin);
+    gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->tx_pin);
+	
+    /* connect port to USARTx_Rx */
+    gpio_mode_set(uart->rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, uart->rx_pin);
+	
+    NVIC_SetPriority(uart->irqn, 0);
+    NVIC_EnableIRQ(uart->irqn);
+}
+
+static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+    struct gd32_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    RT_ASSERT(cfg != RT_NULL);
+
+    uart = (struct gd32_uart *)serial->parent.user_data;
+    
+    gd32_uart_gpio_init(uart);
+    
+    usart_baudrate_set(uart->uart_periph, cfg->baud_rate);
+
+    switch (cfg->data_bits)
+    {
+    case DATA_BITS_9:
+        usart_word_length_set(uart->uart_periph, USART_WL_9BIT);
+        break;
+
+    default:
+        usart_word_length_set(uart->uart_periph, USART_WL_8BIT);
+        break;
+    }
+
+    switch (cfg->stop_bits)
+    {
+    case STOP_BITS_2:
+        usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT);
+        break;
+    default:
+        usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT);
+        break;
+    }
+
+    switch (cfg->parity)
+    {
+    case PARITY_ODD:
+        usart_parity_config(uart->uart_periph, USART_PM_ODD);
+        break;
+    case PARITY_EVEN:
+        usart_parity_config(uart->uart_periph, USART_PM_EVEN);
+        break;
+    default:
+        usart_parity_config(uart->uart_periph, USART_PM_NONE);
+        break;
+    }
+
+    usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE);
+    usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE);
+    usart_enable(uart->uart_periph);
+
+    return RT_EOK;
+}
+
+static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+    struct gd32_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct gd32_uart *)serial->parent.user_data;
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+        /* disable rx irq */
+        NVIC_DisableIRQ(uart->irqn);
+        /* disable interrupt */
+        usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE);
+
+        break;
+    case RT_DEVICE_CTRL_SET_INT:
+        /* enable rx irq */
+        NVIC_EnableIRQ(uart->irqn);
+        /* enable interrupt */
+        usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE);
+        break;
+    }
+
+    return RT_EOK;
+}
+
+static int gd32_putc(struct rt_serial_device *serial, char ch)
+{
+    struct gd32_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct gd32_uart *)serial->parent.user_data;
+
+    usart_data_transmit(uart->uart_periph, ch);
+    while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET));
+    
+    return 1;
+}
+
+static int gd32_getc(struct rt_serial_device *serial)
+{
+    int ch;
+    struct gd32_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct gd32_uart *)serial->parent.user_data;
+
+    ch = -1;
+    if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)
+        ch = usart_data_receive(uart->uart_periph);
+    return ch;
+}
+
+/**
+ * Uart common interrupt process. This need add to uart ISR.
+ *
+ * @param serial serial device
+ */
+static void uart_isr(struct rt_serial_device *serial)
+{
+    struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
+
+    RT_ASSERT(uart != RT_NULL);
+
+    /* UART in mode Receiver */
+    if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) &&
+            (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET))
+    {
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+        /* Clear RXNE interrupt flag */
+        usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE);
+    }
+}
+
+static const struct rt_uart_ops gd32_uart_ops =
+{
+    gd32_configure,
+    gd32_control,
+    gd32_putc,
+    gd32_getc
+};
+
+int gd32_hw_usart_init(void)
+{
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+    int i;
+
+    for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++)
+    {
+        uarts[i].serial->ops    = &gd32_uart_ops;
+        uarts[i].serial->config = config;
+
+        /* register UART device */
+        rt_hw_serial_register(uarts[i].serial,
+                              uarts[i].device_name,
+                              RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                              (void *)&uarts[i]);
+    }
+
+    return 0;
+}
+INIT_BOARD_EXPORT(gd32_hw_usart_init);
+#endif

+ 19 - 0
bsp/gd32e230k-start/drivers/drv_usart.h

@@ -0,0 +1,19 @@
+/*
+ * File      : drv_usart.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      the first version
+ */
+
+#ifndef __USART_H__
+#define __USART_H__
+
+
+#endif

+ 60 - 0
bsp/gd32e230k-start/drivers/gd32e230_libopt.h

@@ -0,0 +1,60 @@
+/*!
+    \file    gd32e230_libopt.h
+    \brief   library optional for gd32e230
+    
+    \version 2018-06-19, V1.0.0, firmware for GD32E230
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32E230_LIBOPT_H
+#define GD32E230_LIBOPT_H
+
+#include "gd32e230_adc.h"
+#include "gd32e230_crc.h"
+#include "gd32e230_dbg.h"
+#include "gd32e230_dma.h"
+#include "gd32e230_exti.h"
+#include "gd32e230_fmc.h"
+#include "gd32e230_gpio.h"
+#include "gd32e230_syscfg.h"
+#include "gd32e230_i2c.h"
+#include "gd32e230_fwdgt.h"
+#include "gd32e230_pmu.h"
+#include "gd32e230_rcu.h"
+#include "gd32e230_rtc.h"
+#include "gd32e230_spi.h"
+#include "gd32e230_timer.h"
+#include "gd32e230_usart.h"
+#include "gd32e230_wwdgt.h"
+#include "gd32e230_misc.h"
+#include "gd32e230_cmp.h"
+
+#endif /* GD32E230_LIBOPT_H */

+ 40 - 0
bsp/gd32e230k-start/gd32_rom.icf

@@ -0,0 +1,40 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__   = 0x0807ffff;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__   = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x2000;
+define symbol __ICFEDIT_size_heap__   = 0x2000;
+/**** End of ICF editor section. ###ICF###*/
+
+export symbol __ICFEDIT_region_RAM_end__;
+
+define symbol __region_RAM1_start__ = 0x10000000;
+define symbol __region_RAM1_end__   = 0x1000FFFF;
+
+define memory mem with size = 4G;
+define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
+define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
+define region RAM1_region  = mem:[from __region_RAM1_start__   to __region_RAM1_end__];
+
+define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
+define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };
+
+initialize by copy { readwrite };
+do not initialize  { section .noinit };
+
+keep { section FSymTab };
+keep { section VSymTab };
+keep { section .rti_fn* };
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region   { readonly };
+place in RAM_region   { readwrite,
+                        block CSTACK, block HEAP };                        
+place in RAM1_region  { section .sram };

+ 142 - 0
bsp/gd32e230k-start/gd32_rom.ld

@@ -0,0 +1,142 @@
+/*
+ * linker script for GD32F30x with GNU ld
+ * bernard.xiong 2009-10-14
+ */
+
+/* Program Entry, set to mark it as "used" and avoid gc */
+MEMORY
+{
+    CODE (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */
+    DATA (rw) : ORIGIN = 0x20000000, LENGTH =  64k /* 64KB sram */
+}
+ENTRY(Reset_Handler)
+_system_stack_size = 0x200;
+
+SECTIONS
+{
+    .text :
+    {
+        . = ALIGN(4);
+        _stext = .;
+        KEEP(*(.isr_vector))            /* Startup code */
+        . = ALIGN(4);
+        *(.text)                        /* remaining code */
+        *(.text.*)                      /* remaining code */
+        *(.rodata)                      /* read-only data (constants) */
+        *(.rodata*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gnu.linkonce.t*)
+
+        /* section information for finsh shell */
+        . = ALIGN(4);
+        __fsymtab_start = .;
+        KEEP(*(FSymTab))
+        __fsymtab_end = .;
+        . = ALIGN(4);
+        __vsymtab_start = .;
+        KEEP(*(VSymTab))
+        __vsymtab_end = .;
+        . = ALIGN(4);
+
+        /* section information for initial. */
+        . = ALIGN(4);
+        __rt_init_start = .;
+        KEEP(*(SORT(.rti_fn*)))
+        __rt_init_end = .;
+        . = ALIGN(4);
+
+        . = ALIGN(4);
+        _etext = .;
+    } > CODE = 0
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+
+        /* This is used by the startup in order to initialize the .data secion */
+        _sidata = .;
+    } > CODE
+    __exidx_end = .;
+
+    /* .data section which is used for initialized data */
+
+    .data : AT (_sidata)
+    {
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _sdata = . ;
+
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d*)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _edata = . ;
+    } >DATA
+
+    .stack : 
+    {
+        . = . + _system_stack_size;
+        . = ALIGN(4);
+        _estack = .;
+    } >DATA
+
+    __bss_start = .;
+    .bss :
+    {
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _sbss = .;
+
+        *(.bss)
+        *(.bss.*)
+        *(COMMON)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _ebss = . ;
+        
+        *(.bss.init)
+    } > DATA
+    __bss_end = .;
+
+    _end = .;
+
+    /* 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) }
+    /* DWARF debug sections.
+     * Symbols in the DWARF debugging sections are relative to the beginning
+     * of the section so we begin them at 0.  */
+    /* DWARF 1 */
+    .debug          0 : { *(.debug) }
+    .line           0 : { *(.line) }
+    /* GNU DWARF 1 extensions */
+    .debug_srcinfo  0 : { *(.debug_srcinfo) }
+    .debug_sfnames  0 : { *(.debug_sfnames) }
+    /* DWARF 1.1 and DWARF 2 */
+    .debug_aranges  0 : { *(.debug_aranges) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    /* DWARF 2 */
+    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+    .debug_abbrev   0 : { *(.debug_abbrev) }
+    .debug_line     0 : { *(.debug_line) }
+    .debug_frame    0 : { *(.debug_frame) }
+    .debug_str      0 : { *(.debug_str) }
+    .debug_loc      0 : { *(.debug_loc) }
+    .debug_macinfo  0 : { *(.debug_macinfo) }
+    /* SGI/MIPS DWARF 2 extensions */
+    .debug_weaknames 0 : { *(.debug_weaknames) }
+    .debug_funcnames 0 : { *(.debug_funcnames) }
+    .debug_typenames 0 : { *(.debug_typenames) }
+    .debug_varnames  0 : { *(.debug_varnames) }
+}

+ 15 - 0
bsp/gd32e230k-start/gd32_rom.sct

@@ -0,0 +1,15 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+LR_IROM1 0x08000000 0x000080000  {    ; load region size_region
+  ER_IROM1 0x08000000 0x000080000  {  ; load address = execution address
+   *.o (RESET, +First)
+   *(InRoot$$Sections)
+   .ANY (+RO)
+  }
+  RW_IRAM1 0x20000000 0x00010000  {  ; RW data
+   .ANY (+RW +ZI)
+  }
+}
+

+ 1301 - 0
bsp/gd32e230k-start/project.uvoptx

@@ -0,0 +1,1301 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
+
+  <SchemaVersion>1.0</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Extensions>
+    <cExt>*.c</cExt>
+    <aExt>*.s*; *.src; *.a*</aExt>
+    <oExt>*.obj; *.o</oExt>
+    <lExt>*.lib</lExt>
+    <tExt>*.txt; *.h; *.inc</tExt>
+    <pExt>*.plm</pExt>
+    <CppX>*.cpp</CppX>
+    <nMigrate>0</nMigrate>
+  </Extensions>
+
+  <DaveTm>
+    <dwLowDateTime>0</dwLowDateTime>
+    <dwHighDateTime>0</dwHighDateTime>
+  </DaveTm>
+
+  <Target>
+    <TargetName>rt-thread_gd32f30x</TargetName>
+    <ToolsetNumber>0x4</ToolsetNumber>
+    <ToolsetName>ARM-ADS</ToolsetName>
+    <TargetOption>
+      <CLKADS>12000000</CLKADS>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>79</PageWidth>
+        <PageLength>66</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\build\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>1</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>1</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>255</CpuCode>
+      <DebugOpt>
+        <uSim>0</uSim>
+        <uTrg>1</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <bEvRecOn>1</bEvRecOn>
+        <bSchkAxf>0</bSchkAxf>
+        <bTchkAxf>0</bTchkAxf>
+        <nTsel>19</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>BIN\UL2V8M.DLL</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2V8M</Key>
+          <Name>UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM))</Name>
+        </SetRegEntry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>JL2CM3</Key>
+          <Name>-U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>0</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <bAutoGenD>0</bAutoGenD>
+      <LntExFlags>0</LntExFlags>
+      <pMisraName></pMisraName>
+      <pszMrule></pszMrule>
+      <pSingCmds></pSingCmds>
+      <pMultCmds></pMultCmds>
+      <pMisraNamep></pMisraNamep>
+      <pszMrulep></pszMrulep>
+      <pSingCmdsp></pSingCmdsp>
+      <pMultCmdsp></pMultCmdsp>
+    </TargetOption>
+  </Target>
+
+  <Group>
+    <GroupName>Applications</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>1</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>applications\main.c</PathWithFileName>
+      <FilenameWithoutPath>main.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Drivers</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>2</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>drivers\board.c</PathWithFileName>
+      <FilenameWithoutPath>board.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>3</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>drivers\drv_usart.c</PathWithFileName>
+      <FilenameWithoutPath>drv_usart.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>4</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>drivers\drv_spi.c</PathWithFileName>
+      <FilenameWithoutPath>drv_spi.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>5</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>drivers\drv_i2c.c</PathWithFileName>
+      <FilenameWithoutPath>drv_i2c.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>6</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>drivers\drv_gpio.c</PathWithFileName>
+      <FilenameWithoutPath>drv_gpio.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>GD32_Lib</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>7</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_adc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>8</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_cmp.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>9</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_crc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>10</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_dbg.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>11</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_dma.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>12</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_exti.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>13</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_fmc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>14</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_fwdgt.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>15</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_gpio.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>16</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_i2c.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>17</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_misc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>18</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_pmu.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>19</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_rcu.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>20</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_rtc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>21</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_spi.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>22</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_syscfg.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>23</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_timer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>24</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_usart.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>25</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c</PathWithFileName>
+      <FilenameWithoutPath>gd32e230_wwdgt.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>26</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c</PathWithFileName>
+      <FilenameWithoutPath>system_gd32e230.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>27</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>.\Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s</PathWithFileName>
+      <FilenameWithoutPath>startup_gd32e230.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Kernel</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>28</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\clock.c</PathWithFileName>
+      <FilenameWithoutPath>clock.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>29</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\components.c</PathWithFileName>
+      <FilenameWithoutPath>components.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>30</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\device.c</PathWithFileName>
+      <FilenameWithoutPath>device.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>31</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\idle.c</PathWithFileName>
+      <FilenameWithoutPath>idle.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>32</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\ipc.c</PathWithFileName>
+      <FilenameWithoutPath>ipc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>33</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\irq.c</PathWithFileName>
+      <FilenameWithoutPath>irq.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>34</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\kservice.c</PathWithFileName>
+      <FilenameWithoutPath>kservice.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>35</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\mem.c</PathWithFileName>
+      <FilenameWithoutPath>mem.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>36</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\mempool.c</PathWithFileName>
+      <FilenameWithoutPath>mempool.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>37</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\object.c</PathWithFileName>
+      <FilenameWithoutPath>object.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>38</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\scheduler.c</PathWithFileName>
+      <FilenameWithoutPath>scheduler.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>39</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\signal.c</PathWithFileName>
+      <FilenameWithoutPath>signal.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>40</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\thread.c</PathWithFileName>
+      <FilenameWithoutPath>thread.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>41</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\src\timer.c</PathWithFileName>
+      <FilenameWithoutPath>timer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>CORTEX-M23</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>42</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\libcpu\arm\common\backtrace.c</PathWithFileName>
+      <FilenameWithoutPath>backtrace.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>43</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\libcpu\arm\common\div0.c</PathWithFileName>
+      <FilenameWithoutPath>div0.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>44</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\libcpu\arm\common\showmem.c</PathWithFileName>
+      <FilenameWithoutPath>showmem.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>45</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\libcpu\arm\cortex-m23\cpuport.c</PathWithFileName>
+      <FilenameWithoutPath>cpuport.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>46</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\libcpu\arm\cortex-m23\context_rvds.S</PathWithFileName>
+      <FilenameWithoutPath>context_rvds.S</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Filesystem</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>47</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\src\dfs.c</PathWithFileName>
+      <FilenameWithoutPath>dfs.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>48</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\src\dfs_file.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_file.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>49</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\src\dfs_fs.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_fs.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>50</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\src\dfs_posix.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_posix.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>51</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\filesystems\devfs\devfs.c</PathWithFileName>
+      <FilenameWithoutPath>devfs.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>52</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\filesystems\elmfat\dfs_elm.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_elm.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>53</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\dfs\filesystems\elmfat\ff.c</PathWithFileName>
+      <FilenameWithoutPath>ff.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>DeviceDrivers</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>54</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\i2c\i2c_core.c</PathWithFileName>
+      <FilenameWithoutPath>i2c_core.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>55</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\i2c\i2c_dev.c</PathWithFileName>
+      <FilenameWithoutPath>i2c_dev.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>56</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\misc\pin.c</PathWithFileName>
+      <FilenameWithoutPath>pin.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>57</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\serial\serial.c</PathWithFileName>
+      <FilenameWithoutPath>serial.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>58</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\spi\spi_core.c</PathWithFileName>
+      <FilenameWithoutPath>spi_core.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>59</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\spi\spi_dev.c</PathWithFileName>
+      <FilenameWithoutPath>spi_dev.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>60</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\src\completion.c</PathWithFileName>
+      <FilenameWithoutPath>completion.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>61</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\src\dataqueue.c</PathWithFileName>
+      <FilenameWithoutPath>dataqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>62</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\src\pipe.c</PathWithFileName>
+      <FilenameWithoutPath>pipe.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>63</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\src\ringbuffer.c</PathWithFileName>
+      <FilenameWithoutPath>ringbuffer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>64</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\src\waitqueue.c</PathWithFileName>
+      <FilenameWithoutPath>waitqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>65</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\drivers\src\workqueue.c</PathWithFileName>
+      <FilenameWithoutPath>workqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>finsh</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>66</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\shell.c</PathWithFileName>
+      <FilenameWithoutPath>shell.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>67</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\symbol.c</PathWithFileName>
+      <FilenameWithoutPath>symbol.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>68</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\cmd.c</PathWithFileName>
+      <FilenameWithoutPath>cmd.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>69</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\msh.c</PathWithFileName>
+      <FilenameWithoutPath>msh.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>70</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\msh_cmd.c</PathWithFileName>
+      <FilenameWithoutPath>msh_cmd.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>71</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\msh_file.c</PathWithFileName>
+      <FilenameWithoutPath>msh_file.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>72</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_compiler.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_compiler.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>73</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_error.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_error.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>74</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_heap.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_heap.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>75</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_init.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_init.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>76</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_node.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_node.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>77</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_ops.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_ops.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>78</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_parser.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_parser.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>79</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_var.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_var.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>80</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_vm.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_vm.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>81</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\finsh\finsh_token.c</PathWithFileName>
+      <FilenameWithoutPath>finsh_token.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>libc</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>82</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\libc\compilers\armlibc\libc.c</PathWithFileName>
+      <FilenameWithoutPath>libc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>83</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\libc\compilers\armlibc\libc_syms.c</PathWithFileName>
+      <FilenameWithoutPath>libc_syms.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>84</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\libc\compilers\armlibc\mem_std.c</PathWithFileName>
+      <FilenameWithoutPath>mem_std.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>85</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\libc\compilers\armlibc\stdio.c</PathWithFileName>
+      <FilenameWithoutPath>stdio.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>86</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\libc\compilers\armlibc\stubs.c</PathWithFileName>
+      <FilenameWithoutPath>stubs.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>87</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\components\libc\compilers\armlibc\time.c</PathWithFileName>
+      <FilenameWithoutPath>time.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>::CMSIS</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>1</RteFlg>
+  </Group>
+
+</ProjectOpt>

+ 952 - 0
bsp/gd32e230k-start/project.uvprojx

@@ -0,0 +1,952 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>rt-thread_gd32f30x</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pArmCC>6120000::V6.12::.\ARMCLANG</pArmCC>
+      <pCCUsed>6120000::V6.12::.\ARMCLANG</pCCUsed>
+      <uAC6>1</uAC6>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>GD32E230K8</Device>
+          <Vendor>GigaDevice</Vendor>
+          <PackID>GigaDevice.GD32E230_DFP.1.0.0</PackID>
+          <PackURL>http://gd32mcu.21ic.com/data/documents/yingyongruanjian</PackURL>
+          <Cpu>IRAM(0x20000000,0x0002000) IROM(0x08000000,0x0010000) CPUTYPE("Cortex-M23") CLOCK(12000000) ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:GD32E230K8$Device\Include\gd32e230.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:GD32E230K8$SVD\GD32E230.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\build\</OutputDirectory>
+          <OutputName>rtthread-gd32f30x</OutputName>
+          <CreateExecutable>1</CreateExecutable>
+          <CreateLib>0</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\build\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName></SimDllName>
+          <SimDllArguments></SimDllArguments>
+          <SimDlgDll></SimDlgDll>
+          <SimDlgDllArguments></SimDlgDllArguments>
+          <TargetDllName>SARMV8M.DLL</TargetDllName>
+          <TargetDllArguments> -MPU</TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM23</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2V8M.DLL</Flash2>
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>1</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>1</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M23"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <RvdsMve>0</RvdsMve>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>0</useUlib>
+            <EndSel>0</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x2000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x10000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x10000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x2000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>7</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>0</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>3</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>1</uC99>
+            <uGnu>0</uGnu>
+            <useXO>0</useXO>
+            <v6Lang>3</v6Lang>
+            <v6LangP>3</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <v6Rtti>0</v6Rtti>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define>GD32E230, RT_USING_ARM_LIBC</Define>
+              <Undefine></Undefine>
+              <IncludePath>applications;.;drivers;Libraries\CMSIS;..\..\include;..\..\libcpu\arm\common;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\spi;..\..\components\drivers\include;..\..\components\drivers\spi\sfud\inc;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\armlibc;.\Libraries\GD32E230_standard_peripheral\Include;.\Libraries\CMSIS\GD\GD32E230\Include;..\..\libcpu\arm\cortex-m23</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>0</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <uClangAs>0</uClangAs>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>1</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange>0x08000000</TextAddressRange>
+            <DataAddressRange>0x20000000</DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc>--keep *.o(.rti_fn.*)   --keep *.o(FSymTab) --keep *.o(VSymTab)</Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>Applications</GroupName>
+          <Files>
+            <File>
+              <FileName>main.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>applications\main.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Drivers</GroupName>
+          <Files>
+            <File>
+              <FileName>board.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>drivers\board.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_usart.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>drivers\drv_usart.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_spi.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>drivers\drv_spi.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_i2c.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>drivers\drv_i2c.c</FilePath>
+            </File>
+            <File>
+              <FileName>drv_gpio.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>drivers\drv_gpio.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>GD32_Lib</GroupName>
+          <Files>
+            <File>
+              <FileName>gd32e230_adc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_cmp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_crc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_dbg.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_dma.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_exti.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_fmc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_fwdgt.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_gpio.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_i2c.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_misc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_pmu.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_rcu.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_rtc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_spi.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_syscfg.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_usart.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c</FilePath>
+            </File>
+            <File>
+              <FileName>gd32e230_wwdgt.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c</FilePath>
+            </File>
+            <File>
+              <FileName>system_gd32e230.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c</FilePath>
+            </File>
+            <File>
+              <FileName>startup_gd32e230.s</FileName>
+              <FileType>2</FileType>
+              <FilePath>.\Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Kernel</GroupName>
+          <Files>
+            <File>
+              <FileName>clock.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\clock.c</FilePath>
+            </File>
+            <File>
+              <FileName>components.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\components.c</FilePath>
+            </File>
+            <File>
+              <FileName>device.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\device.c</FilePath>
+            </File>
+            <File>
+              <FileName>idle.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\idle.c</FilePath>
+            </File>
+            <File>
+              <FileName>ipc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\ipc.c</FilePath>
+            </File>
+            <File>
+              <FileName>irq.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\irq.c</FilePath>
+            </File>
+            <File>
+              <FileName>kservice.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\kservice.c</FilePath>
+            </File>
+            <File>
+              <FileName>mem.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\mem.c</FilePath>
+            </File>
+            <File>
+              <FileName>mempool.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\mempool.c</FilePath>
+            </File>
+            <File>
+              <FileName>object.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\object.c</FilePath>
+            </File>
+            <File>
+              <FileName>scheduler.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\scheduler.c</FilePath>
+            </File>
+            <File>
+              <FileName>signal.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\signal.c</FilePath>
+            </File>
+            <File>
+              <FileName>thread.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\thread.c</FilePath>
+            </File>
+            <File>
+              <FileName>timer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\src\timer.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>CORTEX-M23</GroupName>
+          <Files>
+            <File>
+              <FileName>backtrace.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\libcpu\arm\common\backtrace.c</FilePath>
+            </File>
+            <File>
+              <FileName>div0.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\libcpu\arm\common\div0.c</FilePath>
+            </File>
+            <File>
+              <FileName>showmem.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\libcpu\arm\common\showmem.c</FilePath>
+            </File>
+            <File>
+              <FileName>cpuport.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\libcpu\arm\cortex-m23\cpuport.c</FilePath>
+            </File>
+            <File>
+              <FileName>context_rvds.S</FileName>
+              <FileType>2</FileType>
+              <FilePath>..\..\libcpu\arm\cortex-m23\context_rvds.S</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>Filesystem</GroupName>
+          <Files>
+            <File>
+              <FileName>dfs.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\src\dfs.c</FilePath>
+            </File>
+            <File>
+              <FileName>dfs_file.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\src\dfs_file.c</FilePath>
+            </File>
+            <File>
+              <FileName>dfs_fs.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\src\dfs_fs.c</FilePath>
+            </File>
+            <File>
+              <FileName>dfs_posix.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\src\dfs_posix.c</FilePath>
+            </File>
+            <File>
+              <FileName>devfs.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\filesystems\devfs\devfs.c</FilePath>
+            </File>
+            <File>
+              <FileName>dfs_elm.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\filesystems\elmfat\dfs_elm.c</FilePath>
+            </File>
+            <File>
+              <FileName>ff.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\dfs\filesystems\elmfat\ff.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>DeviceDrivers</GroupName>
+          <GroupOption>
+            <CommonProperty>
+              <UseCPPCompiler>0</UseCPPCompiler>
+              <RVCTCodeConst>0</RVCTCodeConst>
+              <RVCTZI>0</RVCTZI>
+              <RVCTOtherData>0</RVCTOtherData>
+              <ModuleSelection>0</ModuleSelection>
+              <IncludeInBuild>1</IncludeInBuild>
+              <AlwaysBuild>0</AlwaysBuild>
+              <GenerateAssemblyFile>0</GenerateAssemblyFile>
+              <AssembleAssemblyFile>0</AssembleAssemblyFile>
+              <PublicsOnly>0</PublicsOnly>
+              <StopOnExitCode>3</StopOnExitCode>
+              <CustomArgument></CustomArgument>
+              <IncludeLibraryModules></IncludeLibraryModules>
+              <ComprImg>0</ComprImg>
+            </CommonProperty>
+            <GroupArmAds>
+              <Cads>
+                <interw>2</interw>
+                <Optim>0</Optim>
+                <oTime>2</oTime>
+                <SplitLS>2</SplitLS>
+                <OneElfS>2</OneElfS>
+                <Strict>2</Strict>
+                <EnumInt>2</EnumInt>
+                <PlainCh>2</PlainCh>
+                <Ropi>2</Ropi>
+                <Rwpi>2</Rwpi>
+                <wLevel>0</wLevel>
+                <uThumb>2</uThumb>
+                <uSurpInc>2</uSurpInc>
+                <uC99>2</uC99>
+                <uGnu>2</uGnu>
+                <useXO>2</useXO>
+                <v6Lang>0</v6Lang>
+                <v6LangP>0</v6LangP>
+                <vShortEn>2</vShortEn>
+                <vShortWch>2</vShortWch>
+                <v6Lto>2</v6Lto>
+                <v6WtE>2</v6WtE>
+                <v6Rtti>2</v6Rtti>
+                <VariousControls>
+                  <MiscControls></MiscControls>
+                  <Define></Define>
+                  <Undefine></Undefine>
+                  <IncludePath></IncludePath>
+                </VariousControls>
+              </Cads>
+              <Aads>
+                <interw>2</interw>
+                <Ropi>2</Ropi>
+                <Rwpi>2</Rwpi>
+                <thumb>2</thumb>
+                <SplitLS>2</SplitLS>
+                <SwStkChk>2</SwStkChk>
+                <NoWarn>2</NoWarn>
+                <uSurpInc>2</uSurpInc>
+                <useXO>2</useXO>
+                <uClangAs>2</uClangAs>
+                <VariousControls>
+                  <MiscControls></MiscControls>
+                  <Define></Define>
+                  <Undefine></Undefine>
+                  <IncludePath></IncludePath>
+                </VariousControls>
+              </Aads>
+            </GroupArmAds>
+          </GroupOption>
+          <Files>
+            <File>
+              <FileName>i2c_core.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\i2c\i2c_core.c</FilePath>
+            </File>
+            <File>
+              <FileName>i2c_dev.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\i2c\i2c_dev.c</FilePath>
+            </File>
+            <File>
+              <FileName>pin.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\misc\pin.c</FilePath>
+            </File>
+            <File>
+              <FileName>serial.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\serial\serial.c</FilePath>
+            </File>
+            <File>
+              <FileName>spi_core.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\spi\spi_core.c</FilePath>
+            </File>
+            <File>
+              <FileName>spi_dev.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\spi\spi_dev.c</FilePath>
+            </File>
+            <File>
+              <FileName>completion.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\src\completion.c</FilePath>
+            </File>
+            <File>
+              <FileName>dataqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\src\dataqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>pipe.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\src\pipe.c</FilePath>
+            </File>
+            <File>
+              <FileName>ringbuffer.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\src\ringbuffer.c</FilePath>
+            </File>
+            <File>
+              <FileName>waitqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\src\waitqueue.c</FilePath>
+            </File>
+            <File>
+              <FileName>workqueue.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\src\workqueue.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>finsh</GroupName>
+          <Files>
+            <File>
+              <FileName>shell.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\shell.c</FilePath>
+            </File>
+            <File>
+              <FileName>symbol.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\symbol.c</FilePath>
+            </File>
+            <File>
+              <FileName>cmd.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\cmd.c</FilePath>
+            </File>
+            <File>
+              <FileName>msh.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\msh.c</FilePath>
+            </File>
+            <File>
+              <FileName>msh_cmd.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\msh_cmd.c</FilePath>
+            </File>
+            <File>
+              <FileName>msh_file.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\msh_file.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_compiler.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_compiler.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_error.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_error.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_heap.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_heap.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_init.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_init.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_node.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_node.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_ops.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_ops.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_parser.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_parser.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_var.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_var.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_vm.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_vm.c</FilePath>
+            </File>
+            <File>
+              <FileName>finsh_token.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\finsh_token.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>libc</GroupName>
+          <Files>
+            <File>
+              <FileName>libc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\libc\compilers\armlibc\libc.c</FilePath>
+            </File>
+            <File>
+              <FileName>libc_syms.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\libc\compilers\armlibc\libc_syms.c</FilePath>
+            </File>
+            <File>
+              <FileName>mem_std.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\libc\compilers\armlibc\mem_std.c</FilePath>
+            </File>
+            <File>
+              <FileName>stdio.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\libc\compilers\armlibc\stdio.c</FilePath>
+            </File>
+            <File>
+              <FileName>stubs.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\libc\compilers\armlibc\stubs.c</FilePath>
+            </File>
+            <File>
+              <FileName>time.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\libc\compilers\armlibc\time.c</FilePath>
+            </File>
+          </Files>
+        </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components>
+      <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.2.0" condition="ARMv6_7_8-M Device">
+        <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.5.1"/>
+        <targetInfos>
+          <targetInfo name="rt-thread_gd32f30x"/>
+        </targetInfos>
+      </component>
+    </components>
+    <files/>
+  </RTE>
+
+</Project>

+ 158 - 0
bsp/gd32e230k-start/rtconfig.h

@@ -0,0 +1,158 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Configuration */
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+#define RT_ALIGN_SIZE 4
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_DEBUG
+#define RT_DEBUG_COLOR
+#define RT_USING_OVERFLOW_CHECK
+#define RT_DEBUG_INIT 0
+#define RT_DEBUG_THREAD 0
+#define RT_USING_HOOK
+#define IDLE_THREAD_STACK_SIZE 256
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+
+/* Memory Management */
+
+#define RT_USING_MEMPOOL
+#define RT_USING_SMALL_MEM
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 128
+#define RT_CONSOLE_DEVICE_NAME "uart0"
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+
+/* C++ features */
+
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
+#define FINSH_CMD_SIZE 80
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_DEFAULT
+
+/* Device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_WORKDIR
+#define DFS_FILESYSTEMS_MAX 2
+#define DFS_FILESYSTEM_TYPES_MAX 2
+#define DFS_FD_MAX 4
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_0
+#define RT_DFS_ELM_USE_LFN 0
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
+#define RT_DFS_ELM_REENTRANT
+#define RT_USING_DFS_DEVFS
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_USING_SERIAL
+#define RT_SERIAL_USING_DMA
+#define RT_USING_I2C
+#define RT_USING_PIN
+#define RT_USING_SPI
+
+/* Using USB */
+
+
+/* POSIX layer and C standard library */
+
+#define RT_USING_LIBC
+
+/* Network stack */
+
+/* light weight TCP/IP stack */
+
+
+/* Modbus master and slave stack */
+
+
+/* VBUS(Virtual Software BUS) */
+
+
+/* Utilities */
+
+
+/* RT-Thread online packages */
+
+/* system packages */
+
+/* RT-Thread GUI Engine */
+
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+
+/* Wiced WiFi */
+
+
+/* security packages */
+
+
+/* language packages */
+
+
+/* multimedia packages */
+
+
+/* tools packages */
+
+
+/* miscellaneous packages */
+
+
+/* example package: hello */
+
+#define RT_USING_USART0
+#define RT_USING_USART1
+#define RT_USING_SPI0
+#define RT_USING_SPI1
+#define RT_USING_I2C0
+
+#endif

+ 126 - 0
bsp/gd32e230k-start/rtconfig.py

@@ -0,0 +1,126 @@
+import os
+
+# toolchains options
+ARCH='arm'
+CPU='cortex-m4'
+CROSS_TOOL='keil'
+
+if os.getenv('RTT_CC'):
+    CROSS_TOOL = os.getenv('RTT_CC')
+
+# cross_tool provides the cross compiler
+# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
+if  CROSS_TOOL == 'gcc':
+    PLATFORM    = 'gcc'
+    EXEC_PATH   = r'D:/toolchain/gnu_tools_arm_embedded/5.4_2016q3/bin'
+elif CROSS_TOOL == 'keil':
+    PLATFORM 	= 'armcc'
+    EXEC_PATH 	= r'C:/Keil_v5'
+elif CROSS_TOOL == 'iar':
+    PLATFORM 	= 'iar'
+    EXEC_PATH 	= r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0'
+
+if os.getenv('RTT_EXEC_PATH'):
+	EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
+BUILD = 'debug'
+
+if PLATFORM == 'gcc':
+    # tool-chains
+    PREFIX = 'arm-none-eabi-'
+    CC = PREFIX + 'gcc'
+    AS = PREFIX + 'gcc'
+    AR = PREFIX + 'ar'
+    LINK = PREFIX + 'gcc'
+    TARGET_EXT = 'elf'
+    SIZE = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY = PREFIX + 'objcopy'
+	
+    DEVICE = ' -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections'
+    CFLAGS = DEVICE + ' -Dgcc' # -D' + PART_TYPE
+    AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
+    LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-gd32.map,-cref,-u,Reset_Handler -T gd32_rom.ld'
+
+    CPATH = ''
+    LPATH = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0 -gdwarf-2 -g'
+        AFLAGS += ' -gdwarf-2'
+    else:
+        CFLAGS += ' -O2'
+
+    POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+
+elif PLATFORM == 'armcc':
+    # toolchains
+    CC = 'armcc'
+    AS = 'armasm'
+    AR = 'armar'
+    LINK = 'armlink'
+    TARGET_EXT = 'axf'
+
+    DEVICE = ' --cpu Cortex-M4'
+    CFLAGS = DEVICE + ' --apcs=interwork'
+    AFLAGS = DEVICE
+    LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-gd32.map --scatter gd32_rom.sct'
+
+    LFLAGS += ' --keep *.o(.rti_fn.*)   --keep *.o(FSymTab) --keep *.o(VSymTab)' 
+
+    EXEC_PATH += '/ARM/ARMCC/bin'
+    print(EXEC_PATH)
+
+    CFLAGS += ' --c99'
+
+    if BUILD == 'debug':
+        CFLAGS += ' -g -O0'
+        AFLAGS += ' -g'
+    else:
+        CFLAGS += ' -O2'
+
+    POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
+
+elif PLATFORM == 'iar':
+    # toolchains
+    CC = 'iccarm'
+    AS = 'iasmarm'
+    AR = 'iarchive'
+    LINK = 'ilinkarm'
+    TARGET_EXT = 'out'
+
+    DEVICE = ' -D USE_STDPERIPH_DRIVER' + ' -D GD32F30X_HD'
+
+    CFLAGS = DEVICE
+    CFLAGS += ' --diag_suppress Pa050'
+    CFLAGS += ' --no_cse'
+    CFLAGS += ' --no_unroll'
+    CFLAGS += ' --no_inline'
+    CFLAGS += ' --no_code_motion'
+    CFLAGS += ' --no_tbaa'
+    CFLAGS += ' --no_clustering'
+    CFLAGS += ' --no_scheduling'
+    CFLAGS += ' --debug'
+    CFLAGS += ' --endian=little'
+    CFLAGS += ' --cpu=Cortex-M4'
+    CFLAGS += ' -e'
+    CFLAGS += ' --fpu=None'
+    CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"'
+    CFLAGS += ' -Ol'
+    CFLAGS += ' --use_c++_inline'
+
+    AFLAGS = ''
+    AFLAGS += ' -s+'
+    AFLAGS += ' -w+'
+    AFLAGS += ' -r'
+    AFLAGS += ' --cpu Cortex-M4'
+    AFLAGS += ' --fpu None'
+
+    LFLAGS = ' --config gd32_rom.icf'
+    LFLAGS += ' --redirect _Printf=_PrintfTiny'
+    LFLAGS += ' --redirect _Scanf=_ScanfSmall'
+    LFLAGS += ' --entry __iar_program_start'
+
+    EXEC_PATH += '/arm/bin/'
+    POST_ACTION = ''
+

+ 185 - 0
bsp/gd32e230k-start/template.uvoptx

@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
+
+  <SchemaVersion>1.0</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Extensions>
+    <cExt>*.c</cExt>
+    <aExt>*.s*; *.src; *.a*</aExt>
+    <oExt>*.obj; *.o</oExt>
+    <lExt>*.lib</lExt>
+    <tExt>*.txt; *.h; *.inc</tExt>
+    <pExt>*.plm</pExt>
+    <CppX>*.cpp</CppX>
+    <nMigrate>0</nMigrate>
+  </Extensions>
+
+  <DaveTm>
+    <dwLowDateTime>0</dwLowDateTime>
+    <dwHighDateTime>0</dwHighDateTime>
+  </DaveTm>
+
+  <Target>
+    <TargetName>rt-thread_gd32f30x</TargetName>
+    <ToolsetNumber>0x4</ToolsetNumber>
+    <ToolsetName>ARM-ADS</ToolsetName>
+    <TargetOption>
+      <CLKADS>16000000</CLKADS>
+      <OPTTT>
+        <gFlags>1</gFlags>
+        <BeepAtEnd>1</BeepAtEnd>
+        <RunSim>0</RunSim>
+        <RunTarget>1</RunTarget>
+        <RunAbUc>0</RunAbUc>
+      </OPTTT>
+      <OPTHX>
+        <HexSelection>1</HexSelection>
+        <FlashByte>65535</FlashByte>
+        <HexRangeLowAddress>0</HexRangeLowAddress>
+        <HexRangeHighAddress>0</HexRangeHighAddress>
+        <HexOffset>0</HexOffset>
+      </OPTHX>
+      <OPTLEX>
+        <PageWidth>79</PageWidth>
+        <PageLength>66</PageLength>
+        <TabStop>8</TabStop>
+        <ListingPath>.\build\</ListingPath>
+      </OPTLEX>
+      <ListingPage>
+        <CreateCListing>1</CreateCListing>
+        <CreateAListing>1</CreateAListing>
+        <CreateLListing>1</CreateLListing>
+        <CreateIListing>0</CreateIListing>
+        <AsmCond>1</AsmCond>
+        <AsmSymb>1</AsmSymb>
+        <AsmXref>0</AsmXref>
+        <CCond>1</CCond>
+        <CCode>0</CCode>
+        <CListInc>0</CListInc>
+        <CSymb>0</CSymb>
+        <LinkerCodeListing>0</LinkerCodeListing>
+      </ListingPage>
+      <OPTXL>
+        <LMap>1</LMap>
+        <LComments>1</LComments>
+        <LGenerateSymbols>1</LGenerateSymbols>
+        <LLibSym>1</LLibSym>
+        <LLines>1</LLines>
+        <LLocSym>1</LLocSym>
+        <LPubSym>1</LPubSym>
+        <LXref>0</LXref>
+        <LExpSel>0</LExpSel>
+      </OPTXL>
+      <OPTFL>
+        <tvExp>0</tvExp>
+        <tvExpOptDlg>0</tvExpOptDlg>
+        <IsCurrentTarget>1</IsCurrentTarget>
+      </OPTFL>
+      <CpuCode>255</CpuCode>
+      <DebugOpt>
+        <uSim>0</uSim>
+        <uTrg>1</uTrg>
+        <sLdApp>1</sLdApp>
+        <sGomain>1</sGomain>
+        <sRbreak>1</sRbreak>
+        <sRwatch>1</sRwatch>
+        <sRmem>1</sRmem>
+        <sRfunc>1</sRfunc>
+        <sRbox>1</sRbox>
+        <tLdApp>1</tLdApp>
+        <tGomain>1</tGomain>
+        <tRbreak>1</tRbreak>
+        <tRwatch>1</tRwatch>
+        <tRmem>1</tRmem>
+        <tRfunc>0</tRfunc>
+        <tRbox>1</tRbox>
+        <tRtrace>1</tRtrace>
+        <sRSysVw>1</sRSysVw>
+        <tRSysVw>1</tRSysVw>
+        <sRunDeb>0</sRunDeb>
+        <sLrtime>0</sLrtime>
+        <bEvRecOn>1</bEvRecOn>
+        <bSchkAxf>0</bSchkAxf>
+        <bTchkAxf>0</bTchkAxf>
+        <nTsel>4</nTsel>
+        <sDll></sDll>
+        <sDllPa></sDllPa>
+        <sDlgDll></sDlgDll>
+        <sDlgPa></sDlgPa>
+        <sIfile></sIfile>
+        <tDll></tDll>
+        <tDllPa></tDllPa>
+        <tDlgDll></tDlgDll>
+        <tDlgPa></tDlgPa>
+        <tIfile></tIfile>
+        <pMon>Segger\JL2CM3.dll</pMon>
+      </DebugOpt>
+      <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>JL2CM3</Key>
+          <Name>-U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000</Name>
+        </SetRegEntry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>UL2CM3</Key>
+          <Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL010000 -FP0($$Device:GD32F303ZE$Flash\GD32F30x_HD.FLM))</Name>
+        </SetRegEntry>
+      </TargetDriverDllRegistry>
+      <Breakpoint/>
+      <Tracepoint>
+        <THDelay>0</THDelay>
+      </Tracepoint>
+      <DebugFlag>
+        <trace>0</trace>
+        <periodic>0</periodic>
+        <aLwin>0</aLwin>
+        <aCover>0</aCover>
+        <aSer1>0</aSer1>
+        <aSer2>0</aSer2>
+        <aPa>0</aPa>
+        <viewmode>0</viewmode>
+        <vrSel>0</vrSel>
+        <aSym>0</aSym>
+        <aTbox>0</aTbox>
+        <AscS1>0</AscS1>
+        <AscS2>0</AscS2>
+        <AscS3>0</AscS3>
+        <aSer3>0</aSer3>
+        <eProf>0</eProf>
+        <aLa>0</aLa>
+        <aPa1>0</aPa1>
+        <AscS4>0</AscS4>
+        <aSer4>0</aSer4>
+        <StkLoc>0</StkLoc>
+        <TrcWin>0</TrcWin>
+        <newCpu>0</newCpu>
+        <uProt>0</uProt>
+      </DebugFlag>
+      <LintExecutable></LintExecutable>
+      <LintConfigFile></LintConfigFile>
+      <bLintAuto>0</bLintAuto>
+      <bAutoGenD>0</bAutoGenD>
+      <LntExFlags>0</LntExFlags>
+      <pMisraName></pMisraName>
+      <pszMrule></pszMrule>
+      <pSingCmds></pSingCmds>
+      <pMultCmds></pMultCmds>
+      <pMisraNamep></pMisraNamep>
+      <pszMrulep></pszMrulep>
+      <pSingCmdsp></pSingCmdsp>
+      <pMultCmdsp></pMultCmdsp>
+    </TargetOption>
+  </Target>
+
+  <Group>
+    <GroupName>::CMSIS</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>1</RteFlg>
+  </Group>
+
+</ProjectOpt>

+ 400 - 0
bsp/gd32e230k-start/template.uvprojx

@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>rt-thread_gd32f30x</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed>
+      <uAC6>0</uAC6>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>GD32F303ZE</Device>
+          <Vendor>GigaDevice</Vendor>
+          <PackID>GigaDevice.GD32F30x_DFP.1.0.1</PackID>
+          <PackURL>http://gd32mcu.21ic.com/data/documents/yingyongruanjian</PackURL>
+          <Cpu>IRAM(0x20000000-0x2000FFFF)IROM(0x08000000-0x0807FFFF) CLOCK(16000000) CPUTYPE("Cortex-M4")</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile>"Startup\GD\GD32F30x\startup_gd32f30x_hd.s" ("GD32F30x Startup Code")</StartupFile>
+          <FlashDriverDll>UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000)</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>gd32f30x.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>SFD\GD\GD32F30x\GD32F30x_HD.SFR</SFDFile>
+          <bCustSvd>0</bCustSvd>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath>GD\GD32F30x\</RegisterFilePath>
+          <DBRegisterFilePath>GD\GD32F30x\</DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\build\</OutputDirectory>
+          <OutputName>rtthread-gd32f30x</OutputName>
+          <CreateExecutable>1</CreateExecutable>
+          <CreateLib>0</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\build\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopU1X>0</nStopU1X>
+            <nStopU2X>0</nStopU2X>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>1</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments> -REMAP</SimDllArguments>
+          <SimDlgDll>DCM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pCM3</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments></TargetDllArguments>
+          <TargetDlgDll>TCM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pCM3</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <bUseTDR>1</bUseTDR>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3>"" ()</Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>1</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>1</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M4"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>0</useUlib>
+            <EndSel>0</EndSel>
+            <uLtcg>0</uLtcg>
+            <nSecure>0</nSecure>
+            <RoSelD>3</RoSelD>
+            <RwSelD>4</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x10000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x80000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x80000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x10000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>1</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>0</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>0</wLevel>
+            <uThumb>0</uThumb>
+            <uSurpInc>0</uSurpInc>
+            <uC99>1</uC99>
+            <useXO>0</useXO>
+            <v6Lang>1</v6Lang>
+            <v6LangP>1</v6LangP>
+            <vShortEn>1</vShortEn>
+            <vShortWch>1</vShortWch>
+            <v6Lto>0</v6Lto>
+            <v6WtE>0</v6WtE>
+            <v6Rtti>0</v6Rtti>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath>applications;.;drivers;Libraries\CMSIS\GD\GD32F30x\Include;Libraries\CMSIS;Libraries\GD32F30x_standard_peripheral\Include;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh</IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>0</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
+            <uClangAs>0</uClangAs>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>1</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange>0x08000000</TextAddressRange>
+            <DataAddressRange>0x20000000</DataAddressRange>
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc>--keep *.o(RTMSymTab)  --keep *.o(.rti_fn.*)   --keep *.o(FSymTab) --keep *.o(VSymTab)</Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
+      </Groups>
+    </Target>
+  </Targets>
+
+  <RTE>
+    <apis/>
+    <components>
+      <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.0.1" condition="ARMv6_7_8-M Device">
+        <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.0.1"/>
+        <targetInfos>
+          <targetInfo name="rt-thread_gd32f30x"/>
+        </targetInfos>
+      </component>
+    </components>
+    <files/>
+  </RTE>
+
+</Project>

+ 23 - 0
libcpu/arm/cortex-m23/SConscript

@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+    src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+    src += Glob('*_init.S')
+    src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+    src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 210 - 0
libcpu/arm/cortex-m23/context_gcc.S

@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date         Author    Notes
+ * 2009-10-11   Bernard   First version
+ * 2010-12-29   onelife   Modify for EFM32
+ * 2011-06-17   onelife   Merge all of the assembly source code into context_gcc.S
+ * 2011-07-12   onelife   Add interrupt context check function
+ * 2013-06-18   aozima    add restore MSP feature.
+ * 2013-07-09   aozima    enhancement hard fault exception handler.
+ */
+ 
+    .cpu    cortex-m3
+    .fpu    softvfp
+    .syntax unified
+    .thumb
+    .text
+
+    .equ    SCB_VTOR, 0xE000ED08            /* Vector Table Offset Register */
+    .equ    ICSR, 0xE000ED04                /* interrupt control state register */
+    .equ    PENDSVSET_BIT, 0x10000000       /* value to trigger PendSV exception */
+    
+    .equ    SHPR3, 0xE000ED20               /* system priority register (3) */
+    .equ    PENDSV_PRI_LOWEST, 0x00FF0000   /* PendSV priority value (lowest) */
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+    .global rt_hw_interrupt_disable
+    .type rt_hw_interrupt_disable, %function
+rt_hw_interrupt_disable:
+    MRS     R0, PRIMASK
+    CPSID   I
+    BX      LR
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+    .global rt_hw_interrupt_enable
+    .type rt_hw_interrupt_enable, %function
+rt_hw_interrupt_enable:
+    MSR     PRIMASK, R0
+    BX      LR
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * R0 --> from
+ * R1 --> to
+ */
+    .global rt_hw_context_switch_interrupt
+    .type rt_hw_context_switch_interrupt, %function
+    .global rt_hw_context_switch
+    .type rt_hw_context_switch, %function
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+    /* set rt_thread_switch_interrupt_flag to 1 */
+    LDR     R2, =rt_thread_switch_interrupt_flag
+    LDR     R3, [R2]
+    CMP     R3, #1
+    BEQ     _reswitch
+    MOV     R3, #1
+    STR     R3, [R2]
+
+    LDR     R2, =rt_interrupt_from_thread   /* set rt_interrupt_from_thread */
+    STR     R0, [R2]
+
+_reswitch:
+    LDR     R2, =rt_interrupt_to_thread     /* set rt_interrupt_to_thread */
+    STR     R1, [R2]
+
+    LDR     R0, =ICSR           /* trigger the PendSV exception (causes context switch) */
+    LDR     R1, =PENDSVSET_BIT
+    STR     R1, [R0]
+    BX      LR
+
+/* R0 --> switch from thread stack
+ * R1 --> switch to thread stack
+ * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
+ */
+    .global PendSV_Handler
+    .type PendSV_Handler, %function
+PendSV_Handler:
+    /* disable interrupt to protect context switch */
+    MRS     R2, PRIMASK
+    CPSID   I
+
+    /* get rt_thread_switch_interrupt_flag */
+    LDR     R0, =rt_thread_switch_interrupt_flag
+    LDR     R1, [R0]
+    CBZ     R1, pendsv_exit         /* pendsv aLReady handled */
+
+    /* clear rt_thread_switch_interrupt_flag to 0 */
+    MOV     R1, #0
+    STR     R1, [R0]
+
+    LDR     R0, =rt_interrupt_from_thread
+    LDR     R1, [R0]
+    CBZ     R1, switch_to_thread    /* skip register save at the first time */
+
+    MRS     R1, PSP                 /* get from thread stack pointer */
+    STMFD   R1!, {R4 - R11}         /* push R4 - R11 register */
+    LDR     R0, [R0]
+    STR     R1, [R0]                /* update from thread stack pointer */
+
+switch_to_thread:
+    LDR     R1, =rt_interrupt_to_thread
+    LDR     R1, [R1]
+    LDR     R1, [R1]                /* load thread stack pointer */
+
+    LDMFD   R1!, {R4 - R11}         /* pop R4 - R11 register */
+    MSR     PSP, R1                 /* update stack pointer */
+
+pendsv_exit:
+    /* restore interrupt */
+    MSR     PRIMASK, R2
+
+    ORR     LR, LR, #0x04
+    BX      LR
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * R0 --> to
+ */
+    .global rt_hw_context_switch_to
+    .type rt_hw_context_switch_to, %function
+rt_hw_context_switch_to:
+    LDR     R1, =rt_interrupt_to_thread
+    STR     R0, [R1]
+
+    /* set from thread to 0 */
+    LDR     R1, =rt_interrupt_from_thread
+    MOV     R0, #0
+    STR     R0, [R1]
+
+    /* set interrupt flag to 1 */
+    LDR     R1, =rt_thread_switch_interrupt_flag
+    MOV     R0, #1
+    STR     R0, [R1]
+
+    /* set the PendSV exception priority */
+    LDR     R0, =SHPR3
+    LDR     R1, =PENDSV_PRI_LOWEST
+    LDR.W   R2, [R0,#0]             /* read */
+    ORR     R1, R1, R2              /* modify */
+    STR     R1, [R0]                /* write-back */
+
+    LDR     R0, =ICSR               /* trigger the PendSV exception (causes context switch) */
+    LDR     R1, =PENDSVSET_BIT
+    STR     R1, [R0]
+
+    /* restore MSP */
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
+    /* enable interrupts at processor level */
+    CPSIE   F
+    CPSIE   I
+
+    /* never reach here! */
+
+/* compatible with old version */
+    .global rt_hw_interrupt_thread_switch
+    .type rt_hw_interrupt_thread_switch, %function
+rt_hw_interrupt_thread_switch:
+    BX      LR
+    NOP
+
+    .global HardFault_Handler
+    .type HardFault_Handler, %function
+HardFault_Handler:
+    /* get current context */
+    MRS     r0, msp                 /* get fault context from handler. */
+    TST     lr, #0x04               /* if(!EXC_RETURN[2]) */
+    BEQ     _get_sp_done
+    MRS     r0, psp                 /* get fault context from thread. */
+_get_sp_done:
+
+    STMFD   r0!, {r4 - r11}         /* push r4 - r11 register */
+    STMFD   r0!, {lr}               /* push exec_return register */
+
+    TST     lr, #0x04               /* if(!EXC_RETURN[2]) */
+    BEQ     _update_msp
+    MSR     psp, r0                 /* update stack pointer to PSP. */
+    B       _update_done
+_update_msp:
+    MSR     msp, r0                 /* update stack pointer to MSP. */
+_update_done:
+
+    PUSH    {LR}
+    BL      rt_hw_hard_fault_exception
+    POP     {LR}
+
+    ORR     LR, LR, #0x04
+    BX      LR
+
+/*
+ * rt_uint32_t rt_hw_interrupt_check(void);
+ * R0 --> state
+ */
+    .global rt_hw_interrupt_check
+    .type rt_hw_interrupt_check, %function
+rt_hw_interrupt_check:
+    MRS     R0, IPSR
+    BX      LR

+ 202 - 0
libcpu/arm/cortex-m23/context_iar.S

@@ -0,0 +1,202 @@
+;/*
+; * Copyright (c) 2006-2018, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-17     Bernard      first version
+; * 2009-09-27     Bernard      add protect when contex switch occurs
+; * 2013-06-18     aozima       add restore MSP feature.
+; * 2013-07-09     aozima       enhancement hard fault exception handler.
+; */
+
+;/**
+; * @addtogroup cortex-m3
+; */
+;/*@{*/
+
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
+NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
+NVIC_SYSPRI2    EQU     0xE000ED20               ; system priority register (2)
+NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
+NVIC_PENDSVSET  EQU     0x10000000               ; value to trigger PendSV exception
+
+    SECTION    .text:CODE(2)
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+    IMPORT rt_thread_switch_interrupt_flag
+    IMPORT rt_interrupt_from_thread
+    IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+    EXPORT rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+    MRS     r0, PRIMASK
+    CPSID   I
+    BX      LR
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+    EXPORT  rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+    MSR     PRIMASK, r0
+    BX      LR
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+    EXPORT rt_hw_context_switch_interrupt
+    EXPORT rt_hw_context_switch
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+    ; set rt_thread_switch_interrupt_flag to 1
+    LDR     r2, =rt_thread_switch_interrupt_flag
+    LDR     r3, [r2]
+    CMP     r3, #1
+    BEQ     _reswitch
+    MOV     r3, #1
+    STR     r3, [r2]
+
+    LDR     r2, =rt_interrupt_from_thread   ; set rt_interrupt_from_thread
+    STR     r0, [r2]
+
+_reswitch
+    LDR     r2, =rt_interrupt_to_thread     ; set rt_interrupt_to_thread
+    STR     r1, [r2]
+
+    LDR     r0, =NVIC_INT_CTRL              ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+    BX      LR
+
+; r0 --> switch from thread stack
+; r1 --> switch to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+    EXPORT PendSV_Handler
+PendSV_Handler:
+
+    ; disable interrupt to protect context switch
+    MRS     r2, PRIMASK
+    CPSID   I
+
+    ; get rt_thread_switch_interrupt_flag
+    LDR     r0, =rt_thread_switch_interrupt_flag
+    LDR     r1, [r0]
+    CBZ     r1, pendsv_exit         ; pendsv already handled
+
+    ; clear rt_thread_switch_interrupt_flag to 0
+    MOV     r1, #0x00
+    STR     r1, [r0]
+
+    LDR     r0, =rt_interrupt_from_thread
+    LDR     r1, [r0]
+    CBZ     r1, switch_to_thread    ; skip register save at the first time
+
+    MRS     r1, psp                 ; get from thread stack pointer
+    STMFD   r1!, {r4 - r11}         ; push r4 - r11 register
+    LDR     r0, [r0]
+    STR     r1, [r0]                ; update from thread stack pointer
+
+switch_to_thread
+    LDR     r1, =rt_interrupt_to_thread
+    LDR     r1, [r1]
+    LDR     r1, [r1]                ; load thread stack pointer
+
+    LDMFD   r1!, {r4 - r11}         ; pop r4 - r11 register
+    MSR     psp, r1                 ; update stack pointer
+
+pendsv_exit
+    ; restore interrupt
+    MSR     PRIMASK, r2
+
+    ORR     lr, lr, #0x04
+    BX      lr
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+    EXPORT rt_hw_context_switch_to
+rt_hw_context_switch_to:
+    LDR     r1, =rt_interrupt_to_thread
+    STR     r0, [r1]
+
+    ; set from thread to 0
+    LDR     r1, =rt_interrupt_from_thread
+    MOV     r0, #0x0
+    STR     r0, [r1]
+
+    ; set interrupt flag to 1
+    LDR     r1, =rt_thread_switch_interrupt_flag
+    MOV     r0, #1
+    STR     r0, [r1]
+
+    ; set the PendSV exception priority
+    LDR     r0, =NVIC_SYSPRI2
+    LDR     r1, =NVIC_PENDSV_PRI
+    LDR.W   r2, [r0,#0x00]       ; read
+    ORR     r1,r1,r2             ; modify
+    STR     r1, [r0]             ; write-back
+
+    LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
+    ; enable interrupts at processor level
+    CPSIE   F
+    CPSIE   I
+
+    ; never reach here!
+
+; compatible with old version
+    EXPORT rt_hw_interrupt_thread_switch
+rt_hw_interrupt_thread_switch:
+    BX      lr
+
+    IMPORT rt_hw_hard_fault_exception
+    EXPORT HardFault_Handler
+HardFault_Handler:
+
+    ; get current context
+    MRS     r0, msp                 ; get fault context from handler.
+    TST     lr, #0x04               ; if(!EXC_RETURN[2])
+    BEQ     _get_sp_done
+    MRS     r0, psp                 ; get fault context from thread.
+_get_sp_done
+
+    STMFD   r0!, {r4 - r11}         ; push r4 - r11 register
+    ;STMFD   r0!, {lr}               ; push exec_return register
+    SUB     r0, r0, #0x04
+    STR     lr, [r0]
+
+    TST     lr, #0x04               ; if(!EXC_RETURN[2])
+    BEQ     _update_msp
+    MSR     psp, r0                 ; update stack pointer to PSP.
+    B       _update_done
+_update_msp
+    MSR     msp, r0                 ; update stack pointer to MSP.
+_update_done
+
+    PUSH    {lr}
+    BL      rt_hw_hard_fault_exception
+    POP     {lr}
+
+    ORR     lr, lr, #0x04
+    BX      lr
+
+    END

+ 207 - 0
libcpu/arm/cortex-m23/context_rvds.S

@@ -0,0 +1,207 @@
+;/*
+; * Copyright (c) 2006-2018, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-17     Bernard      first version
+; * 2013-06-18     aozima       add restore MSP feature.
+; * 2013-07-09     aozima       enhancement hard fault exception handler.
+; */
+
+;/**
+; * @addtogroup CORTEX-M23
+; */
+;/*@{*/
+
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
+NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
+NVIC_SYSPRI2    EQU     0xE000ED20               ; system priority register (2)
+NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
+NVIC_PENDSVSET  EQU     0x10000000               ; value to trigger PendSV exception
+
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+    IMPORT rt_thread_switch_interrupt_flag
+    IMPORT rt_interrupt_from_thread
+    IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable    PROC
+    EXPORT  rt_hw_interrupt_disable
+    MRS     r0, PRIMASK
+    CPSID   I
+    BX      LR
+    ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable    PROC
+    EXPORT  rt_hw_interrupt_enable
+    MSR     PRIMASK, r0
+    BX      LR
+    ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch_interrupt
+    EXPORT rt_hw_context_switch_interrupt
+rt_hw_context_switch    PROC
+    EXPORT rt_hw_context_switch
+
+    ; set rt_thread_switch_interrupt_flag to 1
+    LDR     r2, =rt_thread_switch_interrupt_flag
+    LDR     r3, [r2]
+    CMP     r3, #1
+    BEQ     _reswitch
+    MOV     r3, #1
+    STR     r3, [r2]
+
+    LDR     r2, =rt_interrupt_from_thread   ; set rt_interrupt_from_thread
+    STR     r0, [r2]
+
+_reswitch
+    LDR     r2, =rt_interrupt_to_thread     ; set rt_interrupt_to_thread
+    STR     r1, [r2]
+
+    LDR     r0, =NVIC_INT_CTRL              ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+    BX      LR
+    ENDP
+
+; r0 --> switch from thread stack
+; r1 --> switch to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+PendSV_Handler   PROC
+    EXPORT PendSV_Handler
+
+    ; disable interrupt to protect context switch
+    MRS     r2, PRIMASK
+    CPSID   I
+
+    ; get rt_thread_switch_interrupt_flag
+    LDR     r0, =rt_thread_switch_interrupt_flag
+    LDR     r1, [r0]
+    CBZ     r1, pendsv_exit         ; pendsv already handled
+
+    ; clear rt_thread_switch_interrupt_flag to 0
+    MOV     r1, #0x00
+    STR     r1, [r0]
+
+    LDR     r0, =rt_interrupt_from_thread
+    LDR     r1, [r0]
+    CBZ     r1, switch_to_thread    ; skip register save at the first time
+
+    MRS     r1, psp                 ; get from thread stack pointer
+    STMFD   r1!, {r4 - r11}         ; push r4 - r11 register
+    LDR     r0, [r0]
+    STR     r1, [r0]                ; update from thread stack pointer
+
+switch_to_thread
+    LDR     r1, =rt_interrupt_to_thread
+    LDR     r1, [r1]
+    LDR     r1, [r1]                ; load thread stack pointer
+
+    LDMFD   r1!, {r4 - r11}         ; pop r4 - r11 register
+    MSR     psp, r1                 ; update stack pointer
+
+pendsv_exit
+    ; restore interrupt
+    MSR     PRIMASK, r2
+
+    ORR     lr, lr, #0x04
+    BX      lr
+    ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; * this fucntion is used to perform the first thread switch
+; */
+rt_hw_context_switch_to    PROC
+    EXPORT rt_hw_context_switch_to
+    ; set to thread
+    LDR     r1, =rt_interrupt_to_thread
+    STR     r0, [r1]
+
+    ; set from thread to 0
+    LDR     r1, =rt_interrupt_from_thread
+    MOV     r0, #0x0
+    STR     r0, [r1]
+
+    ; set interrupt flag to 1
+    LDR     r1, =rt_thread_switch_interrupt_flag
+    MOV     r0, #1
+    STR     r0, [r1]
+
+    ; set the PendSV exception priority
+    LDR     r0, =NVIC_SYSPRI2
+    LDR     r1, =NVIC_PENDSV_PRI
+    LDR.W   r2, [r0,#0x00]       ; read
+    ORR     r1,r1,r2             ; modify
+    STR     r1, [r0]             ; write-back
+
+    ; trigger the PendSV exception (causes context switch)
+    LDR     r0, =NVIC_INT_CTRL
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    MSR     msp, r0
+
+    ; enable interrupts at processor level
+    CPSIE   F
+    CPSIE   I
+
+    ; never reach here!
+    ENDP
+
+; compatible with old version
+rt_hw_interrupt_thread_switch PROC
+    EXPORT rt_hw_interrupt_thread_switch
+    BX      lr
+    ENDP
+
+    IMPORT rt_hw_hard_fault_exception
+    EXPORT HardFault_Handler
+HardFault_Handler    PROC
+
+    ; get current context
+    TST     lr, #0x04               ; if(!EXC_RETURN[2])
+    ITE     EQ
+    MRSEQ   r0, msp                 ; [2]=0 ==> Z=1, get fault context from handler.
+    MRSNE   r0, psp                 ; [2]=1 ==> Z=0, get fault context from thread.
+
+    STMFD   r0!, {r4 - r11}         ; push r4 - r11 register
+    STMFD   r0!, {lr}               ; push exec_return register
+
+    TST     lr, #0x04               ; if(!EXC_RETURN[2])
+    ITE     EQ
+    MSREQ   msp, r0                 ; [2]=0 ==> Z=1, update stack pointer to MSP.
+    MSRNE   psp, r0                 ; [2]=1 ==> Z=0, update stack pointer to PSP.
+
+    PUSH    {lr}
+    BL      rt_hw_hard_fault_exception
+    POP     {lr}
+
+    ORR     lr, lr, #0x04
+    BX      lr
+    ENDP
+
+    ALIGN   4
+
+    END

+ 403 - 0
libcpu/arm/cortex-m23/cpuport.c

@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date         Author      Notes
+ * 2009-01-05   Bernard     first version
+ * 2011-02-14   onelife     Modify for EFM32
+ * 2011-06-17   onelife     Merge all of the C source code into cpuport.c
+ * 2012-12-23   aozima      stack addr align to 8byte.
+ * 2012-12-29   Bernard     Add exception hook.
+ * 2013-07-09   aozima      enhancement hard fault exception handler.
+ */
+
+#include <rtthread.h>
+
+struct exception_stack_frame
+{
+    rt_uint32_t r0;
+    rt_uint32_t r1;
+    rt_uint32_t r2;
+    rt_uint32_t r3;
+    rt_uint32_t r12;
+    rt_uint32_t lr;
+    rt_uint32_t pc;
+    rt_uint32_t psr;
+};
+
+struct stack_frame
+{
+    /* r4 ~ r11 register */
+    rt_uint32_t r4;
+    rt_uint32_t r5;
+    rt_uint32_t r6;
+    rt_uint32_t r7;
+    rt_uint32_t r8;
+    rt_uint32_t r9;
+    rt_uint32_t r10;
+    rt_uint32_t r11;
+
+    struct exception_stack_frame exception_stack_frame;
+};
+
+/* flag in interrupt handling */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+/* exception hook */
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void       *tentry,
+                             void       *parameter,
+                             rt_uint8_t *stack_addr,
+                             void       *texit)
+{
+    struct stack_frame *stack_frame;
+    rt_uint8_t         *stk;
+    unsigned long       i;
+
+    stk  = stack_addr + sizeof(rt_uint32_t);
+    stk  = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
+    stk -= sizeof(struct stack_frame);
+
+    stack_frame = (struct stack_frame *)stk;
+
+    /* init all register */
+    for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
+    {
+        ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
+    }
+
+    stack_frame->exception_stack_frame.r0  = (unsigned long)parameter; /* r0 : argument */
+    stack_frame->exception_stack_frame.r1  = 0;                        /* r1 */
+    stack_frame->exception_stack_frame.r2  = 0;                        /* r2 */
+    stack_frame->exception_stack_frame.r3  = 0;                        /* r3 */
+    stack_frame->exception_stack_frame.r12 = 0;                        /* r12 */
+    stack_frame->exception_stack_frame.lr  = (unsigned long)texit;     /* lr */
+    stack_frame->exception_stack_frame.pc  = (unsigned long)tentry;    /* entry point, pc */
+    stack_frame->exception_stack_frame.psr = 0x01000000L;              /* PSR */
+
+    /* return task's current stack address */
+    return stk;
+}
+
+/**
+ * This function set the hook, which is invoked on fault exception handling.
+ *
+ * @param exception_handle the exception handling hook function.
+ */
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
+{
+    rt_exception_hook = exception_handle;
+}
+
+#define SCB_CFSR        (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
+#define SCB_HFSR        (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
+#define SCB_MMAR        (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
+#define SCB_BFAR        (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR       (*(volatile unsigned long *)0xE000ED0C)  /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004                               /* Reset value, write to SCB_AIRCR can reset cpu */
+
+#define SCB_CFSR_MFSR   (*(volatile const unsigned char*)0xE000ED28)  /* Memory-management Fault Status Register */
+#define SCB_CFSR_BFSR   (*(volatile const unsigned char*)0xE000ED29)  /* Bus Fault Status Register */
+#define SCB_CFSR_UFSR   (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
+
+#ifdef RT_USING_FINSH
+static void usage_fault_track(void)
+{
+    rt_kprintf("usage fault:\n");
+    rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
+
+    if(SCB_CFSR_UFSR & (1<<0))
+    {
+        /* [0]:UNDEFINSTR */
+        rt_kprintf("UNDEFINSTR ");
+    }
+
+    if(SCB_CFSR_UFSR & (1<<1))
+    {
+        /* [1]:INVSTATE */
+        rt_kprintf("INVSTATE ");
+    }
+
+    if(SCB_CFSR_UFSR & (1<<2))
+    {
+        /* [2]:INVPC */
+        rt_kprintf("INVPC ");
+    }
+
+    if(SCB_CFSR_UFSR & (1<<3))
+    {
+        /* [3]:NOCP */
+        rt_kprintf("NOCP ");
+    }
+
+    if(SCB_CFSR_UFSR & (1<<8))
+    {
+        /* [8]:UNALIGNED */
+        rt_kprintf("UNALIGNED ");
+    }
+
+    if(SCB_CFSR_UFSR & (1<<9))
+    {
+        /* [9]:DIVBYZERO */
+        rt_kprintf("DIVBYZERO ");
+    }
+
+    rt_kprintf("\n");
+}
+
+static void bus_fault_track(void)
+{
+    rt_kprintf("bus fault:\n");
+    rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
+
+    if(SCB_CFSR_BFSR & (1<<0))
+    {
+        /* [0]:IBUSERR */
+        rt_kprintf("IBUSERR ");
+    }
+
+    if(SCB_CFSR_BFSR & (1<<1))
+    {
+        /* [1]:PRECISERR */
+        rt_kprintf("PRECISERR ");
+    }
+
+    if(SCB_CFSR_BFSR & (1<<2))
+    {
+        /* [2]:IMPRECISERR */
+        rt_kprintf("IMPRECISERR ");
+    }
+
+    if(SCB_CFSR_BFSR & (1<<3))
+    {
+        /* [3]:UNSTKERR */
+        rt_kprintf("UNSTKERR ");
+    }
+
+    if(SCB_CFSR_BFSR & (1<<4))
+    {
+        /* [4]:STKERR */
+        rt_kprintf("STKERR ");
+    }
+
+    if(SCB_CFSR_BFSR & (1<<7))
+    {
+        rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR);
+    }
+    else
+    {
+        rt_kprintf("\n");
+    }
+}
+
+static void mem_manage_fault_track(void)
+{
+    rt_kprintf("mem manage fault:\n");
+    rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
+
+    if(SCB_CFSR_MFSR & (1<<0))
+    {
+        /* [0]:IACCVIOL */
+        rt_kprintf("IACCVIOL ");
+    }
+
+    if(SCB_CFSR_MFSR & (1<<1))
+    {
+        /* [1]:DACCVIOL */
+        rt_kprintf("DACCVIOL ");
+    }
+
+    if(SCB_CFSR_MFSR & (1<<3))
+    {
+        /* [3]:MUNSTKERR */
+        rt_kprintf("MUNSTKERR ");
+    }
+
+    if(SCB_CFSR_MFSR & (1<<4))
+    {
+        /* [4]:MSTKERR */
+        rt_kprintf("MSTKERR ");
+    }
+
+    if(SCB_CFSR_MFSR & (1<<7))
+    {
+        /* [7]:MMARVALID */
+        rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR);
+    }
+    else
+    {
+        rt_kprintf("\n");
+    }
+}
+
+static void hard_fault_track(void)
+{
+    if(SCB_HFSR & (1UL<<1))
+    {
+        /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */
+        rt_kprintf("failed vector fetch\n");
+    }
+
+    if(SCB_HFSR & (1UL<<30))
+    {
+        /* [30]:FORCED, Indicates hard fault is taken because of bus fault,
+                        memory management fault, or usage fault. */
+        if(SCB_CFSR_BFSR)
+        {
+            bus_fault_track();
+        }
+
+        if(SCB_CFSR_MFSR)
+        {
+            mem_manage_fault_track();
+        }
+
+        if(SCB_CFSR_UFSR)
+        {
+            usage_fault_track();
+        }
+    }
+
+    if(SCB_HFSR & (1UL<<31))
+    {
+        /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */
+        rt_kprintf("debug event\n");
+    }
+}
+#endif /* RT_USING_FINSH */
+
+struct exception_info
+{
+    rt_uint32_t exc_return;
+    struct stack_frame stack_frame;
+};
+
+/*
+ * fault exception handler
+ */
+void rt_hw_hard_fault_exception(struct exception_info * exception_info)
+{
+    extern long list_thread(void);
+    struct stack_frame* context = &exception_info->stack_frame;
+
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
+
+        result = rt_exception_hook(exception_info);
+        if (result == RT_EOK)
+            return;
+    }
+
+    rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr);
+
+    rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0);
+    rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1);
+    rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2);
+    rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3);
+    rt_kprintf("r04: 0x%08x\n", context->r4);
+    rt_kprintf("r05: 0x%08x\n", context->r5);
+    rt_kprintf("r06: 0x%08x\n", context->r6);
+    rt_kprintf("r07: 0x%08x\n", context->r7);
+    rt_kprintf("r08: 0x%08x\n", context->r8);
+    rt_kprintf("r09: 0x%08x\n", context->r9);
+    rt_kprintf("r10: 0x%08x\n", context->r10);
+    rt_kprintf("r11: 0x%08x\n", context->r11);
+    rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12);
+    rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr);
+    rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc);
+
+    if(exception_info->exc_return & (1 << 2) )
+    {
+        rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name);
+
+#ifdef RT_USING_FINSH
+        list_thread();
+#endif /* RT_USING_FINSH */
+    }
+    else
+    {
+        rt_kprintf("hard fault on handler\r\n\r\n");
+    }
+
+#ifdef RT_USING_FINSH
+    hard_fault_track();
+#endif /* RT_USING_FINSH */
+
+    while (1);
+}
+
+/**
+ * shutdown CPU
+ */
+void rt_hw_cpu_shutdown(void)
+{
+    rt_kprintf("shutdown...\n");
+
+    RT_ASSERT(0);
+}
+
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+    SCB_AIRCR = SCB_RESET_VALUE;
+}
+
+#ifdef RT_USING_CPU_FFS
+/**
+ * This function finds the first bit set (beginning with the least significant bit)
+ * in value and return the index of that bit.
+ *
+ * Bits are numbered starting at 1 (the least significant bit).  A return value of
+ * zero from any of these functions means that the argument was zero.
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
+ * shall return 0.
+ */
+#if defined(__CC_ARM)
+__asm int __rt_ffs(int value)
+{
+    CMP     r0, #0x00
+    BEQ     exit
+
+    RBIT    r0, r0
+    CLZ     r0, r0
+    ADDS    r0, r0, #0x01
+
+exit
+    BX      lr
+}
+#elif defined(__IAR_SYSTEMS_ICC__)
+int __rt_ffs(int value)
+{
+    if (value == 0) return value;
+
+    asm("RBIT %0, %1" : "=r"(value) : "r"(value));
+    asm("CLZ  %0, %1" : "=r"(value) : "r"(value));
+    asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value));
+
+    return value;
+}
+#elif defined(__GNUC__)
+int __rt_ffs(int value)
+{
+    return __builtin_ffs(value);
+}
+#endif
+
+#endif